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;
605 * We know that all the name entries in the protocols array
606 * are short (< 16 bytes anyway) and are NUL terminated.
608 for (i = 0; i < CIFS_NUM_PROT; i++) {
609 size_t len = strlen(protocols[i].name) + 1;
611 memcpy(pSMB->DialectsArray+count, protocols[i].name, len);
614 inc_rfc1001_len(pSMB, count);
615 pSMB->ByteCount = cpu_to_le16(count);
617 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
618 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
622 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
623 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
624 /* Check wct = 1 error case */
625 if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
626 /* core returns wct = 1, but we do not ask for core - otherwise
627 small wct just comes when dialect index is -1 indicating we
628 could not negotiate a common dialect */
631 } else if (pSMBr->hdr.WordCount == 13) {
632 server->negflavor = CIFS_NEGFLAVOR_LANMAN;
633 rc = decode_lanman_negprot_rsp(server, pSMBr);
635 } else if (pSMBr->hdr.WordCount != 17) {
640 /* else wct == 17, NTLM or better */
642 server->sec_mode = pSMBr->SecurityMode;
643 if ((server->sec_mode & SECMODE_USER) == 0)
644 cifs_dbg(FYI, "share mode security\n");
646 /* one byte, so no need to convert this or EncryptionKeyLen from
648 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
650 set_credits(server, server->maxReq);
651 /* probably no need to store and check maxvcs */
652 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
653 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
654 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
655 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
656 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
657 server->timeAdj *= 60;
659 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
660 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
661 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
662 CIFS_CRYPTO_KEY_SIZE);
663 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
664 server->capabilities & CAP_EXTENDED_SECURITY) {
665 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
666 rc = decode_ext_sec_blob(ses, pSMBr);
667 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
668 rc = -EIO; /* no crypt key only if plain text pwd */
670 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
671 server->capabilities &= ~CAP_EXTENDED_SECURITY;
676 rc = cifs_enable_signing(server, ses->sign);
678 cifs_buf_release(pSMB);
680 cifs_dbg(FYI, "negprot rc %d\n", rc);
685 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
687 struct smb_hdr *smb_buffer;
690 cifs_dbg(FYI, "In tree disconnect\n");
692 /* BB: do we need to check this? These should never be NULL. */
693 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
697 * No need to return error on this operation if tid invalidated and
698 * closed on server already e.g. due to tcp session crashing. Also,
699 * the tcon is no longer on the list, so no need to take lock before
702 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
705 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
706 (void **)&smb_buffer);
710 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
711 cifs_small_buf_release(smb_buffer);
713 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
715 /* No need to return error on this operation if tid invalidated and
716 closed on server already e.g. due to tcp session crashing */
724 * This is a no-op for now. We're not really interested in the reply, but
725 * rather in the fact that the server sent one and that server->lstrp
728 * FIXME: maybe we should consider checking that the reply matches request?
731 cifs_echo_callback(struct mid_q_entry *mid)
733 struct TCP_Server_Info *server = mid->callback_data;
735 DeleteMidQEntry(mid);
736 add_credits(server, 1, CIFS_ECHO_OP);
740 CIFSSMBEcho(struct TCP_Server_Info *server)
745 struct smb_rqst rqst = { .rq_iov = iov,
748 cifs_dbg(FYI, "In echo request\n");
750 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
754 if (server->capabilities & CAP_UNICODE)
755 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
757 /* set up echo request */
758 smb->hdr.Tid = 0xffff;
759 smb->hdr.WordCount = 1;
760 put_unaligned_le16(1, &smb->EchoCount);
761 put_bcc(1, &smb->hdr);
763 inc_rfc1001_len(smb, 3);
766 iov[0].iov_base = smb;
767 iov[1].iov_len = get_rfc1002_length(smb);
768 iov[1].iov_base = (char *)smb + 4;
770 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
771 server, CIFS_ASYNC_OP | CIFS_ECHO_OP);
773 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
775 cifs_small_buf_release(smb);
781 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
783 LOGOFF_ANDX_REQ *pSMB;
786 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
789 * BB: do we need to check validity of ses and server? They should
790 * always be valid since we have an active reference. If not, that
791 * should probably be a BUG()
793 if (!ses || !ses->server)
796 mutex_lock(&ses->session_mutex);
797 if (ses->need_reconnect)
798 goto session_already_dead; /* no need to send SMBlogoff if uid
799 already closed due to reconnect */
800 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
802 mutex_unlock(&ses->session_mutex);
806 pSMB->hdr.Mid = get_next_mid(ses->server);
808 if (ses->server->sign)
809 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
811 pSMB->hdr.Uid = ses->Suid;
813 pSMB->AndXCommand = 0xFF;
814 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
815 cifs_small_buf_release(pSMB);
816 session_already_dead:
817 mutex_unlock(&ses->session_mutex);
819 /* if session dead then we do not need to do ulogoff,
820 since server closed smb session, no sense reporting
828 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
829 const char *fileName, __u16 type,
830 const struct nls_table *nls_codepage, int remap)
832 TRANSACTION2_SPI_REQ *pSMB = NULL;
833 TRANSACTION2_SPI_RSP *pSMBr = NULL;
834 struct unlink_psx_rq *pRqD;
837 int bytes_returned = 0;
838 __u16 params, param_offset, offset, byte_count;
840 cifs_dbg(FYI, "In POSIX delete\n");
842 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
847 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
849 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
850 PATH_MAX, nls_codepage, remap);
851 name_len++; /* trailing null */
853 } else { /* BB add path length overrun check */
854 name_len = strnlen(fileName, PATH_MAX);
855 name_len++; /* trailing null */
856 strncpy(pSMB->FileName, fileName, name_len);
859 params = 6 + name_len;
860 pSMB->MaxParameterCount = cpu_to_le16(2);
861 pSMB->MaxDataCount = 0; /* BB double check this with jra */
862 pSMB->MaxSetupCount = 0;
867 param_offset = offsetof(struct smb_com_transaction2_spi_req,
868 InformationLevel) - 4;
869 offset = param_offset + params;
871 /* Setup pointer to Request Data (inode type) */
872 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
873 pRqD->type = cpu_to_le16(type);
874 pSMB->ParameterOffset = cpu_to_le16(param_offset);
875 pSMB->DataOffset = cpu_to_le16(offset);
876 pSMB->SetupCount = 1;
878 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
879 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
881 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
882 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
883 pSMB->ParameterCount = cpu_to_le16(params);
884 pSMB->TotalParameterCount = pSMB->ParameterCount;
885 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
887 inc_rfc1001_len(pSMB, byte_count);
888 pSMB->ByteCount = cpu_to_le16(byte_count);
889 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
890 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
892 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
893 cifs_buf_release(pSMB);
895 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
904 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
905 struct cifs_sb_info *cifs_sb)
907 DELETE_FILE_REQ *pSMB = NULL;
908 DELETE_FILE_RSP *pSMBr = NULL;
912 int remap = cifs_remap(cifs_sb);
915 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
920 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
921 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
922 PATH_MAX, cifs_sb->local_nls,
924 name_len++; /* trailing null */
926 } else { /* BB improve check for buffer overruns BB */
927 name_len = strnlen(name, PATH_MAX);
928 name_len++; /* trailing null */
929 strncpy(pSMB->fileName, name, name_len);
931 pSMB->SearchAttributes =
932 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
933 pSMB->BufferFormat = 0x04;
934 inc_rfc1001_len(pSMB, name_len + 1);
935 pSMB->ByteCount = cpu_to_le16(name_len + 1);
936 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
937 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
938 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
940 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
942 cifs_buf_release(pSMB);
950 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
951 struct cifs_sb_info *cifs_sb)
953 DELETE_DIRECTORY_REQ *pSMB = NULL;
954 DELETE_DIRECTORY_RSP *pSMBr = NULL;
958 int remap = cifs_remap(cifs_sb);
960 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
962 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
967 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
968 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
969 PATH_MAX, cifs_sb->local_nls,
971 name_len++; /* trailing null */
973 } else { /* BB improve check for buffer overruns BB */
974 name_len = strnlen(name, PATH_MAX);
975 name_len++; /* trailing null */
976 strncpy(pSMB->DirName, name, name_len);
979 pSMB->BufferFormat = 0x04;
980 inc_rfc1001_len(pSMB, name_len + 1);
981 pSMB->ByteCount = cpu_to_le16(name_len + 1);
982 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
983 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
984 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
986 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
988 cifs_buf_release(pSMB);
995 CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
996 struct cifs_sb_info *cifs_sb)
999 CREATE_DIRECTORY_REQ *pSMB = NULL;
1000 CREATE_DIRECTORY_RSP *pSMBr = NULL;
1003 int remap = cifs_remap(cifs_sb);
1005 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
1007 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
1012 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1013 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
1014 PATH_MAX, cifs_sb->local_nls,
1016 name_len++; /* trailing null */
1018 } else { /* BB improve check for buffer overruns BB */
1019 name_len = strnlen(name, PATH_MAX);
1020 name_len++; /* trailing null */
1021 strncpy(pSMB->DirName, name, name_len);
1024 pSMB->BufferFormat = 0x04;
1025 inc_rfc1001_len(pSMB, name_len + 1);
1026 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1027 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1028 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1029 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1031 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
1033 cifs_buf_release(pSMB);
1040 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1041 __u32 posix_flags, __u64 mode, __u16 *netfid,
1042 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1043 const char *name, const struct nls_table *nls_codepage,
1046 TRANSACTION2_SPI_REQ *pSMB = NULL;
1047 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1050 int bytes_returned = 0;
1051 __u16 params, param_offset, offset, byte_count, count;
1052 OPEN_PSX_REQ *pdata;
1053 OPEN_PSX_RSP *psx_rsp;
1055 cifs_dbg(FYI, "In POSIX Create\n");
1057 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1062 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1064 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1065 PATH_MAX, nls_codepage, remap);
1066 name_len++; /* trailing null */
1068 } else { /* BB improve the check for buffer overruns BB */
1069 name_len = strnlen(name, PATH_MAX);
1070 name_len++; /* trailing null */
1071 strncpy(pSMB->FileName, name, name_len);
1074 params = 6 + name_len;
1075 count = sizeof(OPEN_PSX_REQ);
1076 pSMB->MaxParameterCount = cpu_to_le16(2);
1077 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1078 pSMB->MaxSetupCount = 0;
1082 pSMB->Reserved2 = 0;
1083 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1084 InformationLevel) - 4;
1085 offset = param_offset + params;
1086 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1087 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1088 pdata->Permissions = cpu_to_le64(mode);
1089 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1090 pdata->OpenFlags = cpu_to_le32(*pOplock);
1091 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1092 pSMB->DataOffset = cpu_to_le16(offset);
1093 pSMB->SetupCount = 1;
1094 pSMB->Reserved3 = 0;
1095 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1096 byte_count = 3 /* pad */ + params + count;
1098 pSMB->DataCount = cpu_to_le16(count);
1099 pSMB->ParameterCount = cpu_to_le16(params);
1100 pSMB->TotalDataCount = pSMB->DataCount;
1101 pSMB->TotalParameterCount = pSMB->ParameterCount;
1102 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1103 pSMB->Reserved4 = 0;
1104 inc_rfc1001_len(pSMB, byte_count);
1105 pSMB->ByteCount = cpu_to_le16(byte_count);
1106 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1107 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1109 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1110 goto psx_create_err;
1113 cifs_dbg(FYI, "copying inode info\n");
1114 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1116 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1117 rc = -EIO; /* bad smb */
1118 goto psx_create_err;
1121 /* copy return information to pRetData */
1122 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1123 + le16_to_cpu(pSMBr->t2.DataOffset));
1125 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1127 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1128 /* Let caller know file was created so we can set the mode. */
1129 /* Do we care about the CreateAction in any other cases? */
1130 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1131 *pOplock |= CIFS_CREATE_ACTION;
1132 /* check to make sure response data is there */
1133 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1134 pRetData->Type = cpu_to_le32(-1); /* unknown */
1135 cifs_dbg(NOISY, "unknown type\n");
1137 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1138 + sizeof(FILE_UNIX_BASIC_INFO)) {
1139 cifs_dbg(VFS, "Open response data too small\n");
1140 pRetData->Type = cpu_to_le32(-1);
1141 goto psx_create_err;
1143 memcpy((char *) pRetData,
1144 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1145 sizeof(FILE_UNIX_BASIC_INFO));
1149 cifs_buf_release(pSMB);
1151 if (posix_flags & SMB_O_DIRECTORY)
1152 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1154 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1162 static __u16 convert_disposition(int disposition)
1166 switch (disposition) {
1167 case FILE_SUPERSEDE:
1168 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1171 ofun = SMBOPEN_OAPPEND;
1174 ofun = SMBOPEN_OCREATE;
1177 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1179 case FILE_OVERWRITE:
1180 ofun = SMBOPEN_OTRUNC;
1182 case FILE_OVERWRITE_IF:
1183 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1186 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1187 ofun = SMBOPEN_OAPPEND; /* regular open */
1193 access_flags_to_smbopen_mode(const int access_flags)
1195 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1197 if (masked_flags == GENERIC_READ)
1198 return SMBOPEN_READ;
1199 else if (masked_flags == GENERIC_WRITE)
1200 return SMBOPEN_WRITE;
1202 /* just go for read/write */
1203 return SMBOPEN_READWRITE;
1207 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1208 const char *fileName, const int openDisposition,
1209 const int access_flags, const int create_options, __u16 *netfid,
1210 int *pOplock, FILE_ALL_INFO *pfile_info,
1211 const struct nls_table *nls_codepage, int remap)
1214 OPENX_REQ *pSMB = NULL;
1215 OPENX_RSP *pSMBr = NULL;
1221 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1226 pSMB->AndXCommand = 0xFF; /* none */
1228 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1229 count = 1; /* account for one byte pad to word boundary */
1231 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1232 fileName, PATH_MAX, nls_codepage, remap);
1233 name_len++; /* trailing null */
1235 } else { /* BB improve check for buffer overruns BB */
1236 count = 0; /* no pad */
1237 name_len = strnlen(fileName, PATH_MAX);
1238 name_len++; /* trailing null */
1239 strncpy(pSMB->fileName, fileName, name_len);
1241 if (*pOplock & REQ_OPLOCK)
1242 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1243 else if (*pOplock & REQ_BATCHOPLOCK)
1244 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1246 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1247 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1248 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1249 /* set file as system file if special file such
1250 as fifo and server expecting SFU style and
1251 no Unix extensions */
1253 if (create_options & CREATE_OPTION_SPECIAL)
1254 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1255 else /* BB FIXME BB */
1256 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1258 if (create_options & CREATE_OPTION_READONLY)
1259 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1262 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1263 CREATE_OPTIONS_MASK); */
1264 /* BB FIXME END BB */
1266 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1267 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1269 inc_rfc1001_len(pSMB, count);
1271 pSMB->ByteCount = cpu_to_le16(count);
1272 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1273 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1274 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1276 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1278 /* BB verify if wct == 15 */
1280 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1282 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1283 /* Let caller know file was created so we can set the mode. */
1284 /* Do we care about the CreateAction in any other cases? */
1286 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1287 *pOplock |= CIFS_CREATE_ACTION; */
1291 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1292 pfile_info->LastAccessTime = 0; /* BB fixme */
1293 pfile_info->LastWriteTime = 0; /* BB fixme */
1294 pfile_info->ChangeTime = 0; /* BB fixme */
1295 pfile_info->Attributes =
1296 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1297 /* the file_info buf is endian converted by caller */
1298 pfile_info->AllocationSize =
1299 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1300 pfile_info->EndOfFile = pfile_info->AllocationSize;
1301 pfile_info->NumberOfLinks = cpu_to_le32(1);
1302 pfile_info->DeletePending = 0;
1306 cifs_buf_release(pSMB);
1313 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1317 OPEN_REQ *req = NULL;
1318 OPEN_RSP *rsp = NULL;
1322 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1323 struct cifs_tcon *tcon = oparms->tcon;
1324 int remap = cifs_remap(cifs_sb);
1325 const struct nls_table *nls = cifs_sb->local_nls;
1326 int create_options = oparms->create_options;
1327 int desired_access = oparms->desired_access;
1328 int disposition = oparms->disposition;
1329 const char *path = oparms->path;
1332 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1337 /* no commands go after this */
1338 req->AndXCommand = 0xFF;
1340 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1341 /* account for one byte pad to word boundary */
1343 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1344 path, PATH_MAX, nls, remap);
1348 req->NameLength = cpu_to_le16(name_len);
1350 /* BB improve check for buffer overruns BB */
1353 name_len = strnlen(path, PATH_MAX);
1356 req->NameLength = cpu_to_le16(name_len);
1357 strncpy(req->fileName, path, name_len);
1360 if (*oplock & REQ_OPLOCK)
1361 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1362 else if (*oplock & REQ_BATCHOPLOCK)
1363 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1365 req->DesiredAccess = cpu_to_le32(desired_access);
1366 req->AllocationSize = 0;
1369 * Set file as system file if special file such as fifo and server
1370 * expecting SFU style and no Unix extensions.
1372 if (create_options & CREATE_OPTION_SPECIAL)
1373 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1375 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1378 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1379 * sensitive checks for other servers such as Samba.
1381 if (tcon->ses->capabilities & CAP_UNIX)
1382 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1384 if (create_options & CREATE_OPTION_READONLY)
1385 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1387 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1388 req->CreateDisposition = cpu_to_le32(disposition);
1389 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1391 /* BB Expirement with various impersonation levels and verify */
1392 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1393 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1396 inc_rfc1001_len(req, count);
1398 req->ByteCount = cpu_to_le16(count);
1399 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1400 (struct smb_hdr *)rsp, &bytes_returned, 0);
1401 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1403 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1404 cifs_buf_release(req);
1410 /* 1 byte no need to le_to_cpu */
1411 *oplock = rsp->OplockLevel;
1412 /* cifs fid stays in le */
1413 oparms->fid->netfid = rsp->Fid;
1415 /* Let caller know file was created so we can set the mode. */
1416 /* Do we care about the CreateAction in any other cases? */
1417 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1418 *oplock |= CIFS_CREATE_ACTION;
1421 /* copy from CreationTime to Attributes */
1422 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1423 /* the file_info buf is endian converted by caller */
1424 buf->AllocationSize = rsp->AllocationSize;
1425 buf->EndOfFile = rsp->EndOfFile;
1426 buf->NumberOfLinks = cpu_to_le32(1);
1427 buf->DeletePending = 0;
1430 cifs_buf_release(req);
1435 * Discard any remaining data in the current SMB. To do this, we borrow the
1439 cifs_discard_remaining_data(struct TCP_Server_Info *server)
1441 unsigned int rfclen = server->pdu_size;
1442 int remaining = rfclen + server->vals->header_preamble_size -
1445 while (remaining > 0) {
1448 length = cifs_read_from_socket(server, server->bigbuf,
1449 min_t(unsigned int, remaining,
1450 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1453 server->total_read += length;
1454 remaining -= length;
1461 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1464 struct cifs_readdata *rdata = mid->callback_data;
1466 length = cifs_discard_remaining_data(server);
1467 dequeue_mid(mid, rdata->result);
1468 mid->resp_buf = server->smallbuf;
1469 server->smallbuf = NULL;
1474 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1477 unsigned int data_offset, data_len;
1478 struct cifs_readdata *rdata = mid->callback_data;
1479 char *buf = server->smallbuf;
1480 unsigned int buflen = server->pdu_size +
1481 server->vals->header_preamble_size;
1482 bool use_rdma_mr = false;
1484 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1485 __func__, mid->mid, rdata->offset, rdata->bytes);
1488 * read the rest of READ_RSP header (sans Data array), or whatever we
1489 * can if there's not enough data. At this point, we've read down to
1492 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1493 HEADER_SIZE(server) + 1;
1495 length = cifs_read_from_socket(server,
1496 buf + HEADER_SIZE(server) - 1, len);
1499 server->total_read += length;
1501 if (server->ops->is_session_expired &&
1502 server->ops->is_session_expired(buf)) {
1503 cifs_reconnect(server);
1504 wake_up(&server->response_q);
1508 if (server->ops->is_status_pending &&
1509 server->ops->is_status_pending(buf, server, 0)) {
1510 cifs_discard_remaining_data(server);
1514 /* Was the SMB read successful? */
1515 rdata->result = server->ops->map_error(buf, false);
1516 if (rdata->result != 0) {
1517 cifs_dbg(FYI, "%s: server returned error %d\n",
1518 __func__, rdata->result);
1519 return cifs_readv_discard(server, mid);
1522 /* Is there enough to get to the rest of the READ_RSP header? */
1523 if (server->total_read < server->vals->read_rsp_size) {
1524 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1525 __func__, server->total_read,
1526 server->vals->read_rsp_size);
1527 rdata->result = -EIO;
1528 return cifs_readv_discard(server, mid);
1531 data_offset = server->ops->read_data_offset(buf) +
1532 server->vals->header_preamble_size;
1533 if (data_offset < server->total_read) {
1535 * win2k8 sometimes sends an offset of 0 when the read
1536 * is beyond the EOF. Treat it as if the data starts just after
1539 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1540 __func__, data_offset);
1541 data_offset = server->total_read;
1542 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1543 /* data_offset is beyond the end of smallbuf */
1544 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1545 __func__, data_offset);
1546 rdata->result = -EIO;
1547 return cifs_readv_discard(server, mid);
1550 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1551 __func__, server->total_read, data_offset);
1553 len = data_offset - server->total_read;
1555 /* read any junk before data into the rest of smallbuf */
1556 length = cifs_read_from_socket(server,
1557 buf + server->total_read, len);
1560 server->total_read += length;
1563 /* set up first iov for signature check */
1564 rdata->iov[0].iov_base = buf;
1565 rdata->iov[0].iov_len = 4;
1566 rdata->iov[1].iov_base = buf + 4;
1567 rdata->iov[1].iov_len = server->total_read - 4;
1568 cifs_dbg(FYI, "0: iov_base=%p iov_len=%u\n",
1569 rdata->iov[0].iov_base, server->total_read);
1571 /* how much data is in the response? */
1572 #ifdef CONFIG_CIFS_SMB_DIRECT
1573 use_rdma_mr = rdata->mr;
1575 data_len = server->ops->read_data_length(buf, use_rdma_mr);
1576 if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1577 /* data_len is corrupt -- discard frame */
1578 rdata->result = -EIO;
1579 return cifs_readv_discard(server, mid);
1582 length = rdata->read_into_pages(server, rdata, data_len);
1586 server->total_read += length;
1588 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1589 server->total_read, buflen, data_len);
1591 /* discard anything left over */
1592 if (server->total_read < buflen)
1593 return cifs_readv_discard(server, mid);
1595 dequeue_mid(mid, false);
1596 mid->resp_buf = server->smallbuf;
1597 server->smallbuf = NULL;
1602 cifs_readv_callback(struct mid_q_entry *mid)
1604 struct cifs_readdata *rdata = mid->callback_data;
1605 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1606 struct TCP_Server_Info *server = tcon->ses->server;
1607 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1609 .rq_pages = rdata->pages,
1610 .rq_npages = rdata->nr_pages,
1611 .rq_pagesz = rdata->pagesz,
1612 .rq_tailsz = rdata->tailsz };
1614 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1615 __func__, mid->mid, mid->mid_state, rdata->result,
1618 switch (mid->mid_state) {
1619 case MID_RESPONSE_RECEIVED:
1620 /* result already set, check signature */
1624 rc = cifs_verify_signature(&rqst, server,
1625 mid->sequence_number);
1627 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1630 /* FIXME: should this be counted toward the initiating task? */
1631 task_io_account_read(rdata->got_bytes);
1632 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1634 case MID_REQUEST_SUBMITTED:
1635 case MID_RETRY_NEEDED:
1636 rdata->result = -EAGAIN;
1637 if (server->sign && rdata->got_bytes)
1638 /* reset bytes number since we can not check a sign */
1639 rdata->got_bytes = 0;
1640 /* FIXME: should this be counted toward the initiating task? */
1641 task_io_account_read(rdata->got_bytes);
1642 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1645 rdata->result = -EIO;
1648 queue_work(cifsiod_wq, &rdata->work);
1649 DeleteMidQEntry(mid);
1650 add_credits(server, 1, 0);
1653 /* cifs_async_readv - send an async write, and set up mid to handle result */
1655 cifs_async_readv(struct cifs_readdata *rdata)
1658 READ_REQ *smb = NULL;
1660 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1661 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1664 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1665 __func__, rdata->offset, rdata->bytes);
1667 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1670 wct = 10; /* old style read */
1671 if ((rdata->offset >> 32) > 0) {
1672 /* can not handle this big offset for old */
1677 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1681 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1682 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1684 smb->AndXCommand = 0xFF; /* none */
1685 smb->Fid = rdata->cfile->fid.netfid;
1686 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1688 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1690 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1691 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1695 /* old style read */
1696 struct smb_com_readx_req *smbr =
1697 (struct smb_com_readx_req *)smb;
1698 smbr->ByteCount = 0;
1701 /* 4 for RFC1001 length + 1 for BCC */
1702 rdata->iov[0].iov_base = smb;
1703 rdata->iov[0].iov_len = 4;
1704 rdata->iov[1].iov_base = (char *)smb + 4;
1705 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1707 kref_get(&rdata->refcount);
1708 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1709 cifs_readv_callback, NULL, rdata, 0);
1712 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1714 kref_put(&rdata->refcount, cifs_readdata_release);
1716 cifs_small_buf_release(smb);
1721 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1722 unsigned int *nbytes, char **buf, int *pbuf_type)
1725 READ_REQ *pSMB = NULL;
1726 READ_RSP *pSMBr = NULL;
1727 char *pReadData = NULL;
1729 int resp_buf_type = 0;
1731 struct kvec rsp_iov;
1732 __u32 pid = io_parms->pid;
1733 __u16 netfid = io_parms->netfid;
1734 __u64 offset = io_parms->offset;
1735 struct cifs_tcon *tcon = io_parms->tcon;
1736 unsigned int count = io_parms->length;
1738 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1739 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1742 wct = 10; /* old style read */
1743 if ((offset >> 32) > 0) {
1744 /* can not handle this big offset for old */
1750 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1754 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1755 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1757 /* tcon and ses pointer are checked in smb_init */
1758 if (tcon->ses->server == NULL)
1759 return -ECONNABORTED;
1761 pSMB->AndXCommand = 0xFF; /* none */
1763 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1765 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1767 pSMB->Remaining = 0;
1768 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1769 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1771 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1773 /* old style read */
1774 struct smb_com_readx_req *pSMBW =
1775 (struct smb_com_readx_req *)pSMB;
1776 pSMBW->ByteCount = 0;
1779 iov[0].iov_base = (char *)pSMB;
1780 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1781 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1782 CIFS_LOG_ERROR, &rsp_iov);
1783 cifs_small_buf_release(pSMB);
1784 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1785 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1787 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1789 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1790 data_length = data_length << 16;
1791 data_length += le16_to_cpu(pSMBr->DataLength);
1792 *nbytes = data_length;
1794 /*check that DataLength would not go beyond end of SMB */
1795 if ((data_length > CIFSMaxBufSize)
1796 || (data_length > count)) {
1797 cifs_dbg(FYI, "bad length %d for count %d\n",
1798 data_length, count);
1802 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1803 le16_to_cpu(pSMBr->DataOffset);
1804 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1805 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1807 }*/ /* can not use copy_to_user when using page cache*/
1809 memcpy(*buf, pReadData, data_length);
1814 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1815 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1816 /* return buffer to caller to free */
1817 *buf = rsp_iov.iov_base;
1818 if (resp_buf_type == CIFS_SMALL_BUFFER)
1819 *pbuf_type = CIFS_SMALL_BUFFER;
1820 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1821 *pbuf_type = CIFS_LARGE_BUFFER;
1822 } /* else no valid buffer on return - leave as null */
1824 /* Note: On -EAGAIN error only caller can retry on handle based calls
1825 since file handle passed in no longer valid */
1831 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1832 unsigned int *nbytes, const char *buf)
1835 WRITE_REQ *pSMB = NULL;
1836 WRITE_RSP *pSMBr = NULL;
1837 int bytes_returned, wct;
1840 __u32 pid = io_parms->pid;
1841 __u16 netfid = io_parms->netfid;
1842 __u64 offset = io_parms->offset;
1843 struct cifs_tcon *tcon = io_parms->tcon;
1844 unsigned int count = io_parms->length;
1848 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1849 if (tcon->ses == NULL)
1850 return -ECONNABORTED;
1852 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1856 if ((offset >> 32) > 0) {
1857 /* can not handle big offset for old srv */
1862 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1867 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1868 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1870 /* tcon and ses pointer are checked in smb_init */
1871 if (tcon->ses->server == NULL)
1872 return -ECONNABORTED;
1874 pSMB->AndXCommand = 0xFF; /* none */
1876 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1878 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1880 pSMB->Reserved = 0xFFFFFFFF;
1881 pSMB->WriteMode = 0;
1882 pSMB->Remaining = 0;
1884 /* Can increase buffer size if buffer is big enough in some cases ie we
1885 can send more if LARGE_WRITE_X capability returned by the server and if
1886 our buffer is big enough or if we convert to iovecs on socket writes
1887 and eliminate the copy to the CIFS buffer */
1888 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1889 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1891 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1895 if (bytes_sent > count)
1898 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1900 memcpy(pSMB->Data, buf, bytes_sent);
1901 else if (count != 0) {
1903 cifs_buf_release(pSMB);
1905 } /* else setting file size with write of zero bytes */
1907 byte_count = bytes_sent + 1; /* pad */
1908 else /* wct == 12 */
1909 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1911 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1912 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1913 inc_rfc1001_len(pSMB, byte_count);
1916 pSMB->ByteCount = cpu_to_le16(byte_count);
1917 else { /* old style write has byte count 4 bytes earlier
1919 struct smb_com_writex_req *pSMBW =
1920 (struct smb_com_writex_req *)pSMB;
1921 pSMBW->ByteCount = cpu_to_le16(byte_count);
1924 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1925 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1926 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1928 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1930 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1931 *nbytes = (*nbytes) << 16;
1932 *nbytes += le16_to_cpu(pSMBr->Count);
1935 * Mask off high 16 bits when bytes written as returned by the
1936 * server is greater than bytes requested by the client. Some
1937 * OS/2 servers are known to set incorrect CountHigh values.
1939 if (*nbytes > count)
1943 cifs_buf_release(pSMB);
1945 /* Note: On -EAGAIN error only caller can retry on handle based calls
1946 since file handle passed in no longer valid */
1952 cifs_writedata_release(struct kref *refcount)
1954 struct cifs_writedata *wdata = container_of(refcount,
1955 struct cifs_writedata, refcount);
1956 #ifdef CONFIG_CIFS_SMB_DIRECT
1958 smbd_deregister_mr(wdata->mr);
1964 cifsFileInfo_put(wdata->cfile);
1966 kvfree(wdata->pages);
1971 * Write failed with a retryable error. Resend the write request. It's also
1972 * possible that the page was redirtied so re-clean the page.
1975 cifs_writev_requeue(struct cifs_writedata *wdata)
1978 struct inode *inode = d_inode(wdata->cfile->dentry);
1979 struct TCP_Server_Info *server;
1980 unsigned int rest_len;
1982 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1984 rest_len = wdata->bytes;
1986 struct cifs_writedata *wdata2;
1987 unsigned int j, nr_pages, wsize, tailsz, cur_len;
1989 wsize = server->ops->wp_retry_size(inode);
1990 if (wsize < rest_len) {
1991 nr_pages = wsize / PAGE_SIZE;
1996 cur_len = nr_pages * PAGE_SIZE;
1999 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
2001 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
2004 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
2010 for (j = 0; j < nr_pages; j++) {
2011 wdata2->pages[j] = wdata->pages[i + j];
2012 lock_page(wdata2->pages[j]);
2013 clear_page_dirty_for_io(wdata2->pages[j]);
2016 wdata2->sync_mode = wdata->sync_mode;
2017 wdata2->nr_pages = nr_pages;
2018 wdata2->offset = page_offset(wdata2->pages[0]);
2019 wdata2->pagesz = PAGE_SIZE;
2020 wdata2->tailsz = tailsz;
2021 wdata2->bytes = cur_len;
2023 wdata2->cfile = find_writable_file(CIFS_I(inode), false);
2024 if (!wdata2->cfile) {
2025 cifs_dbg(VFS, "No writable handles for inode\n");
2029 wdata2->pid = wdata2->cfile->pid;
2030 rc = server->ops->async_writev(wdata2, cifs_writedata_release);
2032 for (j = 0; j < nr_pages; j++) {
2033 unlock_page(wdata2->pages[j]);
2034 if (rc != 0 && rc != -EAGAIN) {
2035 SetPageError(wdata2->pages[j]);
2036 end_page_writeback(wdata2->pages[j]);
2037 put_page(wdata2->pages[j]);
2042 kref_put(&wdata2->refcount, cifs_writedata_release);
2048 rest_len -= cur_len;
2050 } while (i < wdata->nr_pages);
2052 mapping_set_error(inode->i_mapping, rc);
2053 kref_put(&wdata->refcount, cifs_writedata_release);
2057 cifs_writev_complete(struct work_struct *work)
2059 struct cifs_writedata *wdata = container_of(work,
2060 struct cifs_writedata, work);
2061 struct inode *inode = d_inode(wdata->cfile->dentry);
2064 if (wdata->result == 0) {
2065 spin_lock(&inode->i_lock);
2066 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2067 spin_unlock(&inode->i_lock);
2068 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2070 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2071 return cifs_writev_requeue(wdata);
2073 for (i = 0; i < wdata->nr_pages; i++) {
2074 struct page *page = wdata->pages[i];
2075 if (wdata->result == -EAGAIN)
2076 __set_page_dirty_nobuffers(page);
2077 else if (wdata->result < 0)
2079 end_page_writeback(page);
2082 if (wdata->result != -EAGAIN)
2083 mapping_set_error(inode->i_mapping, wdata->result);
2084 kref_put(&wdata->refcount, cifs_writedata_release);
2087 struct cifs_writedata *
2088 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2090 struct page **pages =
2091 kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
2093 return cifs_writedata_direct_alloc(pages, complete);
2098 struct cifs_writedata *
2099 cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
2101 struct cifs_writedata *wdata;
2103 wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
2104 if (wdata != NULL) {
2105 wdata->pages = pages;
2106 kref_init(&wdata->refcount);
2107 INIT_LIST_HEAD(&wdata->list);
2108 init_completion(&wdata->done);
2109 INIT_WORK(&wdata->work, complete);
2115 * Check the mid_state and signature on received buffer (if any), and queue the
2116 * workqueue completion task.
2119 cifs_writev_callback(struct mid_q_entry *mid)
2121 struct cifs_writedata *wdata = mid->callback_data;
2122 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2123 unsigned int written;
2124 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2126 switch (mid->mid_state) {
2127 case MID_RESPONSE_RECEIVED:
2128 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2129 if (wdata->result != 0)
2132 written = le16_to_cpu(smb->CountHigh);
2134 written += le16_to_cpu(smb->Count);
2136 * Mask off high 16 bits when bytes written as returned
2137 * by the server is greater than bytes requested by the
2138 * client. OS/2 servers are known to set incorrect
2141 if (written > wdata->bytes)
2144 if (written < wdata->bytes)
2145 wdata->result = -ENOSPC;
2147 wdata->bytes = written;
2149 case MID_REQUEST_SUBMITTED:
2150 case MID_RETRY_NEEDED:
2151 wdata->result = -EAGAIN;
2154 wdata->result = -EIO;
2158 queue_work(cifsiod_wq, &wdata->work);
2159 DeleteMidQEntry(mid);
2160 add_credits(tcon->ses->server, 1, 0);
2163 /* cifs_async_writev - send an async write, and set up mid to handle result */
2165 cifs_async_writev(struct cifs_writedata *wdata,
2166 void (*release)(struct kref *kref))
2169 WRITE_REQ *smb = NULL;
2171 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2173 struct smb_rqst rqst = { };
2175 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2179 if (wdata->offset >> 32 > 0) {
2180 /* can not handle big offset for old srv */
2185 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2187 goto async_writev_out;
2189 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2190 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2192 smb->AndXCommand = 0xFF; /* none */
2193 smb->Fid = wdata->cfile->fid.netfid;
2194 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2196 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2197 smb->Reserved = 0xFFFFFFFF;
2202 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2204 /* 4 for RFC1001 length + 1 for BCC */
2206 iov[0].iov_base = smb;
2207 iov[1].iov_len = get_rfc1002_length(smb) + 1;
2208 iov[1].iov_base = (char *)smb + 4;
2212 rqst.rq_pages = wdata->pages;
2213 rqst.rq_npages = wdata->nr_pages;
2214 rqst.rq_pagesz = wdata->pagesz;
2215 rqst.rq_tailsz = wdata->tailsz;
2217 cifs_dbg(FYI, "async write at %llu %u bytes\n",
2218 wdata->offset, wdata->bytes);
2220 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2221 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2224 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2225 put_bcc(wdata->bytes + 1, &smb->hdr);
2228 struct smb_com_writex_req *smbw =
2229 (struct smb_com_writex_req *)smb;
2230 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2231 put_bcc(wdata->bytes + 5, &smbw->hdr);
2232 iov[1].iov_len += 4; /* pad bigger by four bytes */
2235 kref_get(&wdata->refcount);
2236 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2237 cifs_writev_callback, NULL, wdata, 0);
2240 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2242 kref_put(&wdata->refcount, release);
2245 cifs_small_buf_release(smb);
2250 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2251 unsigned int *nbytes, struct kvec *iov, int n_vec)
2254 WRITE_REQ *pSMB = NULL;
2257 int resp_buf_type = 0;
2258 __u32 pid = io_parms->pid;
2259 __u16 netfid = io_parms->netfid;
2260 __u64 offset = io_parms->offset;
2261 struct cifs_tcon *tcon = io_parms->tcon;
2262 unsigned int count = io_parms->length;
2263 struct kvec rsp_iov;
2267 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2269 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2273 if ((offset >> 32) > 0) {
2274 /* can not handle big offset for old srv */
2278 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2282 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2283 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2285 /* tcon and ses pointer are checked in smb_init */
2286 if (tcon->ses->server == NULL)
2287 return -ECONNABORTED;
2289 pSMB->AndXCommand = 0xFF; /* none */
2291 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2293 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2294 pSMB->Reserved = 0xFFFFFFFF;
2295 pSMB->WriteMode = 0;
2296 pSMB->Remaining = 0;
2299 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2301 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2302 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2303 /* header + 1 byte pad */
2304 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2306 inc_rfc1001_len(pSMB, count + 1);
2307 else /* wct == 12 */
2308 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2310 pSMB->ByteCount = cpu_to_le16(count + 1);
2311 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2312 struct smb_com_writex_req *pSMBW =
2313 (struct smb_com_writex_req *)pSMB;
2314 pSMBW->ByteCount = cpu_to_le16(count + 5);
2316 iov[0].iov_base = pSMB;
2318 iov[0].iov_len = smb_hdr_len + 4;
2319 else /* wct == 12 pad bigger by four bytes */
2320 iov[0].iov_len = smb_hdr_len + 8;
2322 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2324 cifs_small_buf_release(pSMB);
2325 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2327 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2328 } else if (resp_buf_type == 0) {
2329 /* presumably this can not happen, but best to be safe */
2332 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2333 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2334 *nbytes = (*nbytes) << 16;
2335 *nbytes += le16_to_cpu(pSMBr->Count);
2338 * Mask off high 16 bits when bytes written as returned by the
2339 * server is greater than bytes requested by the client. OS/2
2340 * servers are known to set incorrect CountHigh values.
2342 if (*nbytes > count)
2346 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2348 /* Note: On -EAGAIN error only caller can retry on handle based calls
2349 since file handle passed in no longer valid */
2354 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2355 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2356 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2359 LOCK_REQ *pSMB = NULL;
2361 struct kvec rsp_iov;
2365 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2366 num_lock, num_unlock);
2368 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2373 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2374 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2375 pSMB->LockType = lock_type;
2376 pSMB->AndXCommand = 0xFF; /* none */
2377 pSMB->Fid = netfid; /* netfid stays le */
2379 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2380 inc_rfc1001_len(pSMB, count);
2381 pSMB->ByteCount = cpu_to_le16(count);
2383 iov[0].iov_base = (char *)pSMB;
2384 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2385 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2386 iov[1].iov_base = (char *)buf;
2387 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2389 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2390 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP,
2392 cifs_small_buf_release(pSMB);
2394 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2400 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2401 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2402 const __u64 offset, const __u32 numUnlock,
2403 const __u32 numLock, const __u8 lockType,
2404 const bool waitFlag, const __u8 oplock_level)
2407 LOCK_REQ *pSMB = NULL;
2408 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2413 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2414 (int)waitFlag, numLock);
2415 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2420 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2421 /* no response expected */
2422 flags = CIFS_ASYNC_OP | CIFS_OBREAK_OP;
2424 } else if (waitFlag) {
2425 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2426 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2431 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2432 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2433 pSMB->LockType = lockType;
2434 pSMB->OplockLevel = oplock_level;
2435 pSMB->AndXCommand = 0xFF; /* none */
2436 pSMB->Fid = smb_file_id; /* netfid stays le */
2438 if ((numLock != 0) || (numUnlock != 0)) {
2439 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2440 /* BB where to store pid high? */
2441 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2442 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2443 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2444 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2445 count = sizeof(LOCKING_ANDX_RANGE);
2450 inc_rfc1001_len(pSMB, count);
2451 pSMB->ByteCount = cpu_to_le16(count);
2454 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2455 (struct smb_hdr *) pSMB, &bytes_returned);
2457 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2458 cifs_small_buf_release(pSMB);
2459 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2461 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2463 /* Note: On -EAGAIN error only caller can retry on handle based calls
2464 since file handle passed in no longer valid */
2469 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2470 const __u16 smb_file_id, const __u32 netpid,
2471 const loff_t start_offset, const __u64 len,
2472 struct file_lock *pLockData, const __u16 lock_type,
2473 const bool waitFlag)
2475 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2476 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2477 struct cifs_posix_lock *parm_data;
2480 int bytes_returned = 0;
2481 int resp_buf_type = 0;
2482 __u16 params, param_offset, offset, byte_count, count;
2484 struct kvec rsp_iov;
2486 cifs_dbg(FYI, "Posix Lock\n");
2488 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2493 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2496 pSMB->MaxSetupCount = 0;
2499 pSMB->Reserved2 = 0;
2500 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2501 offset = param_offset + params;
2503 count = sizeof(struct cifs_posix_lock);
2504 pSMB->MaxParameterCount = cpu_to_le16(2);
2505 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2506 pSMB->SetupCount = 1;
2507 pSMB->Reserved3 = 0;
2509 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2511 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2512 byte_count = 3 /* pad */ + params + count;
2513 pSMB->DataCount = cpu_to_le16(count);
2514 pSMB->ParameterCount = cpu_to_le16(params);
2515 pSMB->TotalDataCount = pSMB->DataCount;
2516 pSMB->TotalParameterCount = pSMB->ParameterCount;
2517 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2518 parm_data = (struct cifs_posix_lock *)
2519 (((char *) &pSMB->hdr.Protocol) + offset);
2521 parm_data->lock_type = cpu_to_le16(lock_type);
2523 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2524 parm_data->lock_flags = cpu_to_le16(1);
2525 pSMB->Timeout = cpu_to_le32(-1);
2529 parm_data->pid = cpu_to_le32(netpid);
2530 parm_data->start = cpu_to_le64(start_offset);
2531 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2533 pSMB->DataOffset = cpu_to_le16(offset);
2534 pSMB->Fid = smb_file_id;
2535 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2536 pSMB->Reserved4 = 0;
2537 inc_rfc1001_len(pSMB, byte_count);
2538 pSMB->ByteCount = cpu_to_le16(byte_count);
2540 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2541 (struct smb_hdr *) pSMBr, &bytes_returned);
2543 iov[0].iov_base = (char *)pSMB;
2544 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2545 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2546 &resp_buf_type, timeout, &rsp_iov);
2547 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2549 cifs_small_buf_release(pSMB);
2552 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2553 } else if (pLockData) {
2554 /* lock structure can be returned on get */
2557 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2559 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2560 rc = -EIO; /* bad smb */
2563 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2564 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2565 if (data_count < sizeof(struct cifs_posix_lock)) {
2569 parm_data = (struct cifs_posix_lock *)
2570 ((char *)&pSMBr->hdr.Protocol + data_offset);
2571 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2572 pLockData->fl_type = F_UNLCK;
2574 if (parm_data->lock_type ==
2575 cpu_to_le16(CIFS_RDLCK))
2576 pLockData->fl_type = F_RDLCK;
2577 else if (parm_data->lock_type ==
2578 cpu_to_le16(CIFS_WRLCK))
2579 pLockData->fl_type = F_WRLCK;
2581 pLockData->fl_start = le64_to_cpu(parm_data->start);
2582 pLockData->fl_end = pLockData->fl_start +
2583 le64_to_cpu(parm_data->length) - 1;
2584 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2589 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2591 /* Note: On -EAGAIN error only caller can retry on handle based calls
2592 since file handle passed in no longer valid */
2599 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2602 CLOSE_REQ *pSMB = NULL;
2603 cifs_dbg(FYI, "In CIFSSMBClose\n");
2605 /* do not retry on dead session on close */
2606 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2612 pSMB->FileID = (__u16) smb_file_id;
2613 pSMB->LastWriteTime = 0xFFFFFFFF;
2614 pSMB->ByteCount = 0;
2615 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2616 cifs_small_buf_release(pSMB);
2617 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2620 /* EINTR is expected when user ctl-c to kill app */
2621 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2625 /* Since session is dead, file will be closed on server already */
2633 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2636 FLUSH_REQ *pSMB = NULL;
2637 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2639 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2643 pSMB->FileID = (__u16) smb_file_id;
2644 pSMB->ByteCount = 0;
2645 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2646 cifs_small_buf_release(pSMB);
2647 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2649 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2655 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2656 const char *from_name, const char *to_name,
2657 struct cifs_sb_info *cifs_sb)
2660 RENAME_REQ *pSMB = NULL;
2661 RENAME_RSP *pSMBr = NULL;
2663 int name_len, name_len2;
2665 int remap = cifs_remap(cifs_sb);
2667 cifs_dbg(FYI, "In CIFSSMBRename\n");
2669 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2674 pSMB->BufferFormat = 0x04;
2675 pSMB->SearchAttributes =
2676 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2679 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2680 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2681 from_name, PATH_MAX,
2682 cifs_sb->local_nls, remap);
2683 name_len++; /* trailing null */
2685 pSMB->OldFileName[name_len] = 0x04; /* pad */
2686 /* protocol requires ASCII signature byte on Unicode string */
2687 pSMB->OldFileName[name_len + 1] = 0x00;
2689 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2690 to_name, PATH_MAX, cifs_sb->local_nls,
2692 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2693 name_len2 *= 2; /* convert to bytes */
2694 } else { /* BB improve the check for buffer overruns BB */
2695 name_len = strnlen(from_name, PATH_MAX);
2696 name_len++; /* trailing null */
2697 strncpy(pSMB->OldFileName, from_name, name_len);
2698 name_len2 = strnlen(to_name, PATH_MAX);
2699 name_len2++; /* trailing null */
2700 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2701 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
2702 name_len2++; /* trailing null */
2703 name_len2++; /* signature byte */
2706 count = 1 /* 1st signature byte */ + name_len + name_len2;
2707 inc_rfc1001_len(pSMB, count);
2708 pSMB->ByteCount = cpu_to_le16(count);
2710 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2711 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2712 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2714 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2716 cifs_buf_release(pSMB);
2724 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2725 int netfid, const char *target_name,
2726 const struct nls_table *nls_codepage, int remap)
2728 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2729 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2730 struct set_file_rename *rename_info;
2732 char dummy_string[30];
2734 int bytes_returned = 0;
2736 __u16 params, param_offset, offset, count, byte_count;
2738 cifs_dbg(FYI, "Rename to File by handle\n");
2739 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2745 pSMB->MaxSetupCount = 0;
2749 pSMB->Reserved2 = 0;
2750 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2751 offset = param_offset + params;
2753 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2754 rename_info = (struct set_file_rename *) data_offset;
2755 pSMB->MaxParameterCount = cpu_to_le16(2);
2756 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2757 pSMB->SetupCount = 1;
2758 pSMB->Reserved3 = 0;
2759 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2760 byte_count = 3 /* pad */ + params;
2761 pSMB->ParameterCount = cpu_to_le16(params);
2762 pSMB->TotalParameterCount = pSMB->ParameterCount;
2763 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2764 pSMB->DataOffset = cpu_to_le16(offset);
2765 /* construct random name ".cifs_tmp<inodenum><mid>" */
2766 rename_info->overwrite = cpu_to_le32(1);
2767 rename_info->root_fid = 0;
2768 /* unicode only call */
2769 if (target_name == NULL) {
2770 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2772 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2773 dummy_string, 24, nls_codepage, remap);
2776 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2777 target_name, PATH_MAX, nls_codepage,
2780 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2781 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2782 byte_count += count;
2783 pSMB->DataCount = cpu_to_le16(count);
2784 pSMB->TotalDataCount = pSMB->DataCount;
2786 pSMB->InformationLevel =
2787 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2788 pSMB->Reserved4 = 0;
2789 inc_rfc1001_len(pSMB, byte_count);
2790 pSMB->ByteCount = cpu_to_le16(byte_count);
2791 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2792 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2793 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2795 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2798 cifs_buf_release(pSMB);
2800 /* Note: On -EAGAIN error only caller can retry on handle based calls
2801 since file handle passed in no longer valid */
2807 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2808 const char *fromName, const __u16 target_tid, const char *toName,
2809 const int flags, const struct nls_table *nls_codepage, int remap)
2812 COPY_REQ *pSMB = NULL;
2813 COPY_RSP *pSMBr = NULL;
2815 int name_len, name_len2;
2818 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2820 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2825 pSMB->BufferFormat = 0x04;
2826 pSMB->Tid2 = target_tid;
2828 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2830 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2831 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2832 fromName, PATH_MAX, nls_codepage,
2834 name_len++; /* trailing null */
2836 pSMB->OldFileName[name_len] = 0x04; /* pad */
2837 /* protocol requires ASCII signature byte on Unicode string */
2838 pSMB->OldFileName[name_len + 1] = 0x00;
2840 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2841 toName, PATH_MAX, nls_codepage, remap);
2842 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2843 name_len2 *= 2; /* convert to bytes */
2844 } else { /* BB improve the check for buffer overruns BB */
2845 name_len = strnlen(fromName, PATH_MAX);
2846 name_len++; /* trailing null */
2847 strncpy(pSMB->OldFileName, fromName, name_len);
2848 name_len2 = strnlen(toName, PATH_MAX);
2849 name_len2++; /* trailing null */
2850 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2851 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2852 name_len2++; /* trailing null */
2853 name_len2++; /* signature byte */
2856 count = 1 /* 1st signature byte */ + name_len + name_len2;
2857 inc_rfc1001_len(pSMB, count);
2858 pSMB->ByteCount = cpu_to_le16(count);
2860 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2861 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2863 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2864 rc, le16_to_cpu(pSMBr->CopyCount));
2866 cifs_buf_release(pSMB);
2875 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2876 const char *fromName, const char *toName,
2877 const struct nls_table *nls_codepage, int remap)
2879 TRANSACTION2_SPI_REQ *pSMB = NULL;
2880 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2883 int name_len_target;
2885 int bytes_returned = 0;
2886 __u16 params, param_offset, offset, byte_count;
2888 cifs_dbg(FYI, "In Symlink Unix style\n");
2890 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2895 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2897 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2898 /* find define for this maxpathcomponent */
2899 PATH_MAX, nls_codepage, remap);
2900 name_len++; /* trailing null */
2903 } else { /* BB improve the check for buffer overruns BB */
2904 name_len = strnlen(fromName, PATH_MAX);
2905 name_len++; /* trailing null */
2906 strncpy(pSMB->FileName, fromName, name_len);
2908 params = 6 + name_len;
2909 pSMB->MaxSetupCount = 0;
2913 pSMB->Reserved2 = 0;
2914 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2915 InformationLevel) - 4;
2916 offset = param_offset + params;
2918 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2919 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2921 cifsConvertToUTF16((__le16 *) data_offset, toName,
2922 /* find define for this maxpathcomponent */
2923 PATH_MAX, nls_codepage, remap);
2924 name_len_target++; /* trailing null */
2925 name_len_target *= 2;
2926 } else { /* BB improve the check for buffer overruns BB */
2927 name_len_target = strnlen(toName, PATH_MAX);
2928 name_len_target++; /* trailing null */
2929 strncpy(data_offset, toName, name_len_target);
2932 pSMB->MaxParameterCount = cpu_to_le16(2);
2933 /* BB find exact max on data count below from sess */
2934 pSMB->MaxDataCount = cpu_to_le16(1000);
2935 pSMB->SetupCount = 1;
2936 pSMB->Reserved3 = 0;
2937 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2938 byte_count = 3 /* pad */ + params + name_len_target;
2939 pSMB->DataCount = cpu_to_le16(name_len_target);
2940 pSMB->ParameterCount = cpu_to_le16(params);
2941 pSMB->TotalDataCount = pSMB->DataCount;
2942 pSMB->TotalParameterCount = pSMB->ParameterCount;
2943 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2944 pSMB->DataOffset = cpu_to_le16(offset);
2945 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2946 pSMB->Reserved4 = 0;
2947 inc_rfc1001_len(pSMB, byte_count);
2948 pSMB->ByteCount = cpu_to_le16(byte_count);
2949 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2950 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2951 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2953 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2956 cifs_buf_release(pSMB);
2959 goto createSymLinkRetry;
2965 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2966 const char *fromName, const char *toName,
2967 const struct nls_table *nls_codepage, int remap)
2969 TRANSACTION2_SPI_REQ *pSMB = NULL;
2970 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2973 int name_len_target;
2975 int bytes_returned = 0;
2976 __u16 params, param_offset, offset, byte_count;
2978 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2979 createHardLinkRetry:
2980 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2985 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2986 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2987 PATH_MAX, nls_codepage, remap);
2988 name_len++; /* trailing null */
2991 } else { /* BB improve the check for buffer overruns BB */
2992 name_len = strnlen(toName, PATH_MAX);
2993 name_len++; /* trailing null */
2994 strncpy(pSMB->FileName, toName, name_len);
2996 params = 6 + name_len;
2997 pSMB->MaxSetupCount = 0;
3001 pSMB->Reserved2 = 0;
3002 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3003 InformationLevel) - 4;
3004 offset = param_offset + params;
3006 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
3007 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3009 cifsConvertToUTF16((__le16 *) data_offset, fromName,
3010 PATH_MAX, nls_codepage, remap);
3011 name_len_target++; /* trailing null */
3012 name_len_target *= 2;
3013 } else { /* BB improve the check for buffer overruns BB */
3014 name_len_target = strnlen(fromName, PATH_MAX);
3015 name_len_target++; /* trailing null */
3016 strncpy(data_offset, fromName, name_len_target);
3019 pSMB->MaxParameterCount = cpu_to_le16(2);
3020 /* BB find exact max on data count below from sess*/
3021 pSMB->MaxDataCount = cpu_to_le16(1000);
3022 pSMB->SetupCount = 1;
3023 pSMB->Reserved3 = 0;
3024 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3025 byte_count = 3 /* pad */ + params + name_len_target;
3026 pSMB->ParameterCount = cpu_to_le16(params);
3027 pSMB->TotalParameterCount = pSMB->ParameterCount;
3028 pSMB->DataCount = cpu_to_le16(name_len_target);
3029 pSMB->TotalDataCount = pSMB->DataCount;
3030 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3031 pSMB->DataOffset = cpu_to_le16(offset);
3032 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
3033 pSMB->Reserved4 = 0;
3034 inc_rfc1001_len(pSMB, byte_count);
3035 pSMB->ByteCount = cpu_to_le16(byte_count);
3036 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3037 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3038 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3040 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
3043 cifs_buf_release(pSMB);
3045 goto createHardLinkRetry;
3051 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3052 const char *from_name, const char *to_name,
3053 struct cifs_sb_info *cifs_sb)
3056 NT_RENAME_REQ *pSMB = NULL;
3057 RENAME_RSP *pSMBr = NULL;
3059 int name_len, name_len2;
3061 int remap = cifs_remap(cifs_sb);
3063 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3064 winCreateHardLinkRetry:
3066 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3071 pSMB->SearchAttributes =
3072 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3074 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3075 pSMB->ClusterCount = 0;
3077 pSMB->BufferFormat = 0x04;
3079 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3081 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3082 PATH_MAX, cifs_sb->local_nls, remap);
3083 name_len++; /* trailing null */
3086 /* protocol specifies ASCII buffer format (0x04) for unicode */
3087 pSMB->OldFileName[name_len] = 0x04;
3088 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3090 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3091 to_name, PATH_MAX, cifs_sb->local_nls,
3093 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3094 name_len2 *= 2; /* convert to bytes */
3095 } else { /* BB improve the check for buffer overruns BB */
3096 name_len = strnlen(from_name, PATH_MAX);
3097 name_len++; /* trailing null */
3098 strncpy(pSMB->OldFileName, from_name, name_len);
3099 name_len2 = strnlen(to_name, PATH_MAX);
3100 name_len2++; /* trailing null */
3101 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3102 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
3103 name_len2++; /* trailing null */
3104 name_len2++; /* signature byte */
3107 count = 1 /* string type byte */ + name_len + name_len2;
3108 inc_rfc1001_len(pSMB, count);
3109 pSMB->ByteCount = cpu_to_le16(count);
3111 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3112 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3113 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3115 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3117 cifs_buf_release(pSMB);
3119 goto winCreateHardLinkRetry;
3125 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3126 const unsigned char *searchName, char **symlinkinfo,
3127 const struct nls_table *nls_codepage, int remap)
3129 /* SMB_QUERY_FILE_UNIX_LINK */
3130 TRANSACTION2_QPI_REQ *pSMB = NULL;
3131 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3135 __u16 params, byte_count;
3138 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3141 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3146 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3148 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3149 searchName, PATH_MAX, nls_codepage,
3151 name_len++; /* trailing null */
3153 } else { /* BB improve the check for buffer overruns BB */
3154 name_len = strnlen(searchName, PATH_MAX);
3155 name_len++; /* trailing null */
3156 strncpy(pSMB->FileName, searchName, name_len);
3159 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3160 pSMB->TotalDataCount = 0;
3161 pSMB->MaxParameterCount = cpu_to_le16(2);
3162 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3163 pSMB->MaxSetupCount = 0;
3167 pSMB->Reserved2 = 0;
3168 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3169 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3170 pSMB->DataCount = 0;
3171 pSMB->DataOffset = 0;
3172 pSMB->SetupCount = 1;
3173 pSMB->Reserved3 = 0;
3174 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3175 byte_count = params + 1 /* pad */ ;
3176 pSMB->TotalParameterCount = cpu_to_le16(params);
3177 pSMB->ParameterCount = pSMB->TotalParameterCount;
3178 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3179 pSMB->Reserved4 = 0;
3180 inc_rfc1001_len(pSMB, byte_count);
3181 pSMB->ByteCount = cpu_to_le16(byte_count);
3183 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3184 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3186 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3188 /* decode response */
3190 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3191 /* BB also check enough total bytes returned */
3192 if (rc || get_bcc(&pSMBr->hdr) < 2)
3196 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3198 data_start = ((char *) &pSMBr->hdr.Protocol) +
3199 le16_to_cpu(pSMBr->t2.DataOffset);
3201 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3206 /* BB FIXME investigate remapping reserved chars here */
3207 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3208 count, is_unicode, nls_codepage);
3213 cifs_buf_release(pSMB);
3215 goto querySymLinkRetry;
3220 * Recent Windows versions now create symlinks more frequently
3221 * and they use the "reparse point" mechanism below. We can of course
3222 * do symlinks nicely to Samba and other servers which support the
3223 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3224 * "MF" symlinks optionally, but for recent Windows we really need to
3225 * reenable the code below and fix the cifs_symlink callers to handle this.
3226 * In the interim this code has been moved to its own config option so
3227 * it is not compiled in by default until callers fixed up and more tested.
3230 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3231 __u16 fid, char **symlinkinfo,
3232 const struct nls_table *nls_codepage)
3236 struct smb_com_transaction_ioctl_req *pSMB;
3237 struct smb_com_transaction_ioctl_rsp *pSMBr;
3239 unsigned int sub_len;
3241 struct reparse_symlink_data *reparse_buf;
3242 struct reparse_posix_data *posix_buf;
3243 __u32 data_offset, data_count;
3246 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3247 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3252 pSMB->TotalParameterCount = 0 ;
3253 pSMB->TotalDataCount = 0;
3254 pSMB->MaxParameterCount = cpu_to_le32(2);
3255 /* BB find exact data count max from sess structure BB */
3256 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3257 pSMB->MaxSetupCount = 4;
3259 pSMB->ParameterOffset = 0;
3260 pSMB->DataCount = 0;
3261 pSMB->DataOffset = 0;
3262 pSMB->SetupCount = 4;
3263 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3264 pSMB->ParameterCount = pSMB->TotalParameterCount;
3265 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3266 pSMB->IsFsctl = 1; /* FSCTL */
3267 pSMB->IsRootFlag = 0;
3268 pSMB->Fid = fid; /* file handle always le */
3269 pSMB->ByteCount = 0;
3271 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3272 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3274 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3278 data_offset = le32_to_cpu(pSMBr->DataOffset);
3279 data_count = le32_to_cpu(pSMBr->DataCount);
3280 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3281 /* BB also check enough total bytes returned */
3282 rc = -EIO; /* bad smb */
3285 if (!data_count || (data_count > 2048)) {
3287 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3290 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3291 reparse_buf = (struct reparse_symlink_data *)
3292 ((char *)&pSMBr->hdr.Protocol + data_offset);
3293 if ((char *)reparse_buf >= end_of_smb) {
3297 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3298 cifs_dbg(FYI, "NFS style reparse tag\n");
3299 posix_buf = (struct reparse_posix_data *)reparse_buf;
3301 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3302 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3303 le64_to_cpu(posix_buf->InodeType));
3308 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3309 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3310 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3314 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3315 sub_len, is_unicode, nls_codepage);
3317 } else if (reparse_buf->ReparseTag !=
3318 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3323 /* Reparse tag is NTFS symlink */
3324 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3325 reparse_buf->PathBuffer;
3326 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3327 if (sub_start + sub_len > end_of_smb) {
3328 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3332 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3337 /* BB FIXME investigate remapping reserved chars here */
3338 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3343 cifs_buf_release(pSMB);
3346 * Note: On -EAGAIN error only caller can retry on handle based calls
3347 * since file handle passed in no longer valid.
3353 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3358 struct smb_com_transaction_compr_ioctl_req *pSMB;
3359 struct smb_com_transaction_ioctl_rsp *pSMBr;
3361 cifs_dbg(FYI, "Set compression for %u\n", fid);
3362 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3367 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3369 pSMB->TotalParameterCount = 0;
3370 pSMB->TotalDataCount = cpu_to_le32(2);
3371 pSMB->MaxParameterCount = 0;
3372 pSMB->MaxDataCount = 0;
3373 pSMB->MaxSetupCount = 4;
3375 pSMB->ParameterOffset = 0;
3376 pSMB->DataCount = cpu_to_le32(2);
3378 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3379 compression_state) - 4); /* 84 */
3380 pSMB->SetupCount = 4;
3381 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3382 pSMB->ParameterCount = 0;
3383 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3384 pSMB->IsFsctl = 1; /* FSCTL */
3385 pSMB->IsRootFlag = 0;
3386 pSMB->Fid = fid; /* file handle always le */
3387 /* 3 byte pad, followed by 2 byte compress state */
3388 pSMB->ByteCount = cpu_to_le16(5);
3389 inc_rfc1001_len(pSMB, 5);
3391 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3392 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3394 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3396 cifs_buf_release(pSMB);
3399 * Note: On -EAGAIN error only caller can retry on handle based calls
3400 * since file handle passed in no longer valid.
3406 #ifdef CONFIG_CIFS_POSIX
3408 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3409 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3410 struct cifs_posix_ace *cifs_ace)
3412 /* u8 cifs fields do not need le conversion */
3413 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3414 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3415 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3417 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3418 ace->e_perm, ace->e_tag, ace->e_id);
3424 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3425 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3426 const int acl_type, const int size_of_data_area)
3431 struct cifs_posix_ace *pACE;
3432 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3433 struct posix_acl_xattr_header *local_acl = (void *)trgt;
3435 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3438 if (acl_type == ACL_TYPE_ACCESS) {
3439 count = le16_to_cpu(cifs_acl->access_entry_count);
3440 pACE = &cifs_acl->ace_array[0];
3441 size = sizeof(struct cifs_posix_acl);
3442 size += sizeof(struct cifs_posix_ace) * count;
3443 /* check if we would go beyond end of SMB */
3444 if (size_of_data_area < size) {
3445 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3446 size_of_data_area, size);
3449 } else if (acl_type == ACL_TYPE_DEFAULT) {
3450 count = le16_to_cpu(cifs_acl->access_entry_count);
3451 size = sizeof(struct cifs_posix_acl);
3452 size += sizeof(struct cifs_posix_ace) * count;
3453 /* skip past access ACEs to get to default ACEs */
3454 pACE = &cifs_acl->ace_array[count];
3455 count = le16_to_cpu(cifs_acl->default_entry_count);
3456 size += sizeof(struct cifs_posix_ace) * count;
3457 /* check if we would go beyond end of SMB */
3458 if (size_of_data_area < size)
3465 size = posix_acl_xattr_size(count);
3466 if ((buflen == 0) || (local_acl == NULL)) {
3467 /* used to query ACL EA size */
3468 } else if (size > buflen) {
3470 } else /* buffer big enough */ {
3471 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3473 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3474 for (i = 0; i < count ; i++) {
3475 cifs_convert_ace(&ace[i], pACE);
3482 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3483 const struct posix_acl_xattr_entry *local_ace)
3485 __u16 rc = 0; /* 0 = ACL converted ok */
3487 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3488 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3489 /* BB is there a better way to handle the large uid? */
3490 if (local_ace->e_id == cpu_to_le32(-1)) {
3491 /* Probably no need to le convert -1 on any arch but can not hurt */
3492 cifs_ace->cifs_uid = cpu_to_le64(-1);
3494 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3496 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3497 ace->e_perm, ace->e_tag, ace->e_id);
3502 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3503 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3504 const int buflen, const int acl_type)
3507 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3508 struct posix_acl_xattr_header *local_acl = (void *)pACL;
3509 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3513 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3516 count = posix_acl_xattr_count((size_t)buflen);
3517 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3518 count, buflen, le32_to_cpu(local_acl->a_version));
3519 if (le32_to_cpu(local_acl->a_version) != 2) {
3520 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3521 le32_to_cpu(local_acl->a_version));
3524 cifs_acl->version = cpu_to_le16(1);
3525 if (acl_type == ACL_TYPE_ACCESS) {
3526 cifs_acl->access_entry_count = cpu_to_le16(count);
3527 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3528 } else if (acl_type == ACL_TYPE_DEFAULT) {
3529 cifs_acl->default_entry_count = cpu_to_le16(count);
3530 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3532 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3535 for (i = 0; i < count; i++) {
3536 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3538 /* ACE not converted */
3543 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3544 rc += sizeof(struct cifs_posix_acl);
3545 /* BB add check to make sure ACL does not overflow SMB */
3551 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3552 const unsigned char *searchName,
3553 char *acl_inf, const int buflen, const int acl_type,
3554 const struct nls_table *nls_codepage, int remap)
3556 /* SMB_QUERY_POSIX_ACL */
3557 TRANSACTION2_QPI_REQ *pSMB = NULL;
3558 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3562 __u16 params, byte_count;
3564 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3567 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3572 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3574 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3575 searchName, PATH_MAX, nls_codepage,
3577 name_len++; /* trailing null */
3579 pSMB->FileName[name_len] = 0;
3580 pSMB->FileName[name_len+1] = 0;
3581 } else { /* BB improve the check for buffer overruns BB */
3582 name_len = strnlen(searchName, PATH_MAX);
3583 name_len++; /* trailing null */
3584 strncpy(pSMB->FileName, searchName, name_len);
3587 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3588 pSMB->TotalDataCount = 0;
3589 pSMB->MaxParameterCount = cpu_to_le16(2);
3590 /* BB find exact max data count below from sess structure BB */
3591 pSMB->MaxDataCount = cpu_to_le16(4000);
3592 pSMB->MaxSetupCount = 0;
3596 pSMB->Reserved2 = 0;
3597 pSMB->ParameterOffset = cpu_to_le16(
3598 offsetof(struct smb_com_transaction2_qpi_req,
3599 InformationLevel) - 4);
3600 pSMB->DataCount = 0;
3601 pSMB->DataOffset = 0;
3602 pSMB->SetupCount = 1;
3603 pSMB->Reserved3 = 0;
3604 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3605 byte_count = params + 1 /* pad */ ;
3606 pSMB->TotalParameterCount = cpu_to_le16(params);
3607 pSMB->ParameterCount = pSMB->TotalParameterCount;
3608 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3609 pSMB->Reserved4 = 0;
3610 inc_rfc1001_len(pSMB, byte_count);
3611 pSMB->ByteCount = cpu_to_le16(byte_count);
3613 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3614 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3615 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3617 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3619 /* decode response */
3621 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3622 /* BB also check enough total bytes returned */
3623 if (rc || get_bcc(&pSMBr->hdr) < 2)
3624 rc = -EIO; /* bad smb */
3626 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3627 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3628 rc = cifs_copy_posix_acl(acl_inf,
3629 (char *)&pSMBr->hdr.Protocol+data_offset,
3630 buflen, acl_type, count);
3633 cifs_buf_release(pSMB);
3640 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3641 const unsigned char *fileName,
3642 const char *local_acl, const int buflen,
3644 const struct nls_table *nls_codepage, int remap)
3646 struct smb_com_transaction2_spi_req *pSMB = NULL;
3647 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3651 int bytes_returned = 0;
3652 __u16 params, byte_count, data_count, param_offset, offset;
3654 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3656 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3660 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3662 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3663 PATH_MAX, nls_codepage, remap);
3664 name_len++; /* trailing null */
3666 } else { /* BB improve the check for buffer overruns BB */
3667 name_len = strnlen(fileName, PATH_MAX);
3668 name_len++; /* trailing null */
3669 strncpy(pSMB->FileName, fileName, name_len);
3671 params = 6 + name_len;
3672 pSMB->MaxParameterCount = cpu_to_le16(2);
3673 /* BB find max SMB size from sess */
3674 pSMB->MaxDataCount = cpu_to_le16(1000);
3675 pSMB->MaxSetupCount = 0;
3679 pSMB->Reserved2 = 0;
3680 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3681 InformationLevel) - 4;
3682 offset = param_offset + params;
3683 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3684 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3686 /* convert to on the wire format for POSIX ACL */
3687 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3689 if (data_count == 0) {
3691 goto setACLerrorExit;
3693 pSMB->DataOffset = cpu_to_le16(offset);
3694 pSMB->SetupCount = 1;
3695 pSMB->Reserved3 = 0;
3696 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3697 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3698 byte_count = 3 /* pad */ + params + data_count;
3699 pSMB->DataCount = cpu_to_le16(data_count);
3700 pSMB->TotalDataCount = pSMB->DataCount;
3701 pSMB->ParameterCount = cpu_to_le16(params);
3702 pSMB->TotalParameterCount = pSMB->ParameterCount;
3703 pSMB->Reserved4 = 0;
3704 inc_rfc1001_len(pSMB, byte_count);
3705 pSMB->ByteCount = cpu_to_le16(byte_count);
3706 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3707 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3709 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3712 cifs_buf_release(pSMB);
3718 /* BB fix tabs in this function FIXME BB */
3720 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3721 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3724 struct smb_t2_qfi_req *pSMB = NULL;
3725 struct smb_t2_qfi_rsp *pSMBr = NULL;
3727 __u16 params, byte_count;
3729 cifs_dbg(FYI, "In GetExtAttr\n");
3734 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3739 params = 2 /* level */ + 2 /* fid */;
3740 pSMB->t2.TotalDataCount = 0;
3741 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3742 /* BB find exact max data count below from sess structure BB */
3743 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3744 pSMB->t2.MaxSetupCount = 0;
3745 pSMB->t2.Reserved = 0;
3747 pSMB->t2.Timeout = 0;
3748 pSMB->t2.Reserved2 = 0;
3749 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3751 pSMB->t2.DataCount = 0;
3752 pSMB->t2.DataOffset = 0;
3753 pSMB->t2.SetupCount = 1;
3754 pSMB->t2.Reserved3 = 0;
3755 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3756 byte_count = params + 1 /* pad */ ;
3757 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3758 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3759 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3762 inc_rfc1001_len(pSMB, byte_count);
3763 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3765 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3766 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3768 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3770 /* decode response */
3771 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3772 /* BB also check enough total bytes returned */
3773 if (rc || get_bcc(&pSMBr->hdr) < 2)
3774 /* If rc should we check for EOPNOSUPP and
3775 disable the srvino flag? or in caller? */
3776 rc = -EIO; /* bad smb */
3778 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3779 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3780 struct file_chattr_info *pfinfo;
3781 /* BB Do we need a cast or hash here ? */
3783 cifs_dbg(FYI, "Illegal size ret in GetExtAttr\n");
3787 pfinfo = (struct file_chattr_info *)
3788 (data_offset + (char *) &pSMBr->hdr.Protocol);
3789 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3790 *pMask = le64_to_cpu(pfinfo->mask);
3794 cifs_buf_release(pSMB);
3796 goto GetExtAttrRetry;
3800 #endif /* CONFIG_POSIX */
3802 #ifdef CONFIG_CIFS_ACL
3804 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3805 * all NT TRANSACTS that we init here have total parm and data under about 400
3806 * bytes (to fit in small cifs buffer size), which is the case so far, it
3807 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3808 * returned setup area) and MaxParameterCount (returned parms size) must be set
3812 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3813 const int parm_len, struct cifs_tcon *tcon,
3818 struct smb_com_ntransact_req *pSMB;
3820 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3824 *ret_buf = (void *)pSMB;
3826 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3827 pSMB->TotalDataCount = 0;
3828 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3829 pSMB->ParameterCount = pSMB->TotalParameterCount;
3830 pSMB->DataCount = pSMB->TotalDataCount;
3831 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3832 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3833 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3834 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3835 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3836 pSMB->SubCommand = cpu_to_le16(sub_command);
3841 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3842 __u32 *pparmlen, __u32 *pdatalen)
3845 __u32 data_count, data_offset, parm_count, parm_offset;
3846 struct smb_com_ntransact_rsp *pSMBr;
3855 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3857 bcc = get_bcc(&pSMBr->hdr);
3858 end_of_smb = 2 /* sizeof byte count */ + bcc +
3859 (char *)&pSMBr->ByteCount;
3861 data_offset = le32_to_cpu(pSMBr->DataOffset);
3862 data_count = le32_to_cpu(pSMBr->DataCount);
3863 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3864 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3866 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3867 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3869 /* should we also check that parm and data areas do not overlap? */
3870 if (*ppparm > end_of_smb) {
3871 cifs_dbg(FYI, "parms start after end of smb\n");
3873 } else if (parm_count + *ppparm > end_of_smb) {
3874 cifs_dbg(FYI, "parm end after end of smb\n");
3876 } else if (*ppdata > end_of_smb) {
3877 cifs_dbg(FYI, "data starts after end of smb\n");
3879 } else if (data_count + *ppdata > end_of_smb) {
3880 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3881 *ppdata, data_count, (data_count + *ppdata),
3884 } else if (parm_count + data_count > bcc) {
3885 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3888 *pdatalen = data_count;
3889 *pparmlen = parm_count;
3893 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3895 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3896 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3900 QUERY_SEC_DESC_REQ *pSMB;
3902 struct kvec rsp_iov;
3904 cifs_dbg(FYI, "GetCifsACL\n");
3909 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3910 8 /* parm len */, tcon, (void **) &pSMB);
3914 pSMB->MaxParameterCount = cpu_to_le32(4);
3915 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3916 pSMB->MaxSetupCount = 0;
3917 pSMB->Fid = fid; /* file handle always le */
3918 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3920 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3921 inc_rfc1001_len(pSMB, 11);
3922 iov[0].iov_base = (char *)pSMB;
3923 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3925 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3927 cifs_small_buf_release(pSMB);
3928 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3930 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3931 } else { /* decode response */
3935 struct smb_com_ntransact_rsp *pSMBr;
3938 /* validate_nttransact */
3939 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3940 &pdata, &parm_len, pbuflen);
3943 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3945 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3946 pSMBr, parm, *acl_inf);
3948 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3949 rc = -EIO; /* bad smb */
3954 /* BB check that data area is minimum length and as big as acl_len */
3956 acl_len = le32_to_cpu(*parm);
3957 if (acl_len != *pbuflen) {
3958 cifs_dbg(VFS, "acl length %d does not match %d\n",
3960 if (*pbuflen > acl_len)
3964 /* check if buffer is big enough for the acl
3965 header followed by the smallest SID */
3966 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3967 (*pbuflen >= 64 * 1024)) {
3968 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3972 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3973 if (*acl_inf == NULL) {
3980 free_rsp_buf(buf_type, rsp_iov.iov_base);
3985 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3986 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3988 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3990 int bytes_returned = 0;
3991 SET_SEC_DESC_REQ *pSMB = NULL;
3995 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3999 pSMB->MaxSetupCount = 0;
4003 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
4004 data_count = acllen;
4005 data_offset = param_offset + param_count;
4006 byte_count = 3 /* pad */ + param_count;
4008 pSMB->DataCount = cpu_to_le32(data_count);
4009 pSMB->TotalDataCount = pSMB->DataCount;
4010 pSMB->MaxParameterCount = cpu_to_le32(4);
4011 pSMB->MaxDataCount = cpu_to_le32(16384);
4012 pSMB->ParameterCount = cpu_to_le32(param_count);
4013 pSMB->ParameterOffset = cpu_to_le32(param_offset);
4014 pSMB->TotalParameterCount = pSMB->ParameterCount;
4015 pSMB->DataOffset = cpu_to_le32(data_offset);
4016 pSMB->SetupCount = 0;
4017 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
4018 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
4020 pSMB->Fid = fid; /* file handle always le */
4021 pSMB->Reserved2 = 0;
4022 pSMB->AclFlags = cpu_to_le32(aclflag);
4024 if (pntsd && acllen) {
4025 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
4026 data_offset, pntsd, acllen);
4027 inc_rfc1001_len(pSMB, byte_count + data_count);
4029 inc_rfc1001_len(pSMB, byte_count);
4031 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4032 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4034 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4035 bytes_returned, rc);
4037 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
4038 cifs_buf_release(pSMB);
4041 goto setCifsAclRetry;
4046 #endif /* CONFIG_CIFS_ACL */
4048 /* Legacy Query Path Information call for lookup to old servers such
4051 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
4052 const char *search_name, FILE_ALL_INFO *data,
4053 const struct nls_table *nls_codepage, int remap)
4055 QUERY_INFORMATION_REQ *pSMB;
4056 QUERY_INFORMATION_RSP *pSMBr;
4061 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
4063 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
4068 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4070 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4071 search_name, PATH_MAX, nls_codepage,
4073 name_len++; /* trailing null */
4076 name_len = strnlen(search_name, PATH_MAX);
4077 name_len++; /* trailing null */
4078 strncpy(pSMB->FileName, search_name, name_len);
4080 pSMB->BufferFormat = 0x04;
4081 name_len++; /* account for buffer type byte */
4082 inc_rfc1001_len(pSMB, (__u16)name_len);
4083 pSMB->ByteCount = cpu_to_le16(name_len);
4085 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4086 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4088 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4090 struct timespec64 ts;
4091 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4093 /* decode response */
4094 /* BB FIXME - add time zone adjustment BB */
4095 memset(data, 0, sizeof(FILE_ALL_INFO));
4098 /* decode time fields */
4099 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4100 data->LastWriteTime = data->ChangeTime;
4101 data->LastAccessTime = 0;
4102 data->AllocationSize =
4103 cpu_to_le64(le32_to_cpu(pSMBr->size));
4104 data->EndOfFile = data->AllocationSize;
4106 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4108 rc = -EIO; /* bad buffer passed in */
4110 cifs_buf_release(pSMB);
4119 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4120 u16 netfid, FILE_ALL_INFO *pFindData)
4122 struct smb_t2_qfi_req *pSMB = NULL;
4123 struct smb_t2_qfi_rsp *pSMBr = NULL;
4126 __u16 params, byte_count;
4129 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4134 params = 2 /* level */ + 2 /* fid */;
4135 pSMB->t2.TotalDataCount = 0;
4136 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4137 /* BB find exact max data count below from sess structure BB */
4138 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4139 pSMB->t2.MaxSetupCount = 0;
4140 pSMB->t2.Reserved = 0;
4142 pSMB->t2.Timeout = 0;
4143 pSMB->t2.Reserved2 = 0;
4144 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4146 pSMB->t2.DataCount = 0;
4147 pSMB->t2.DataOffset = 0;
4148 pSMB->t2.SetupCount = 1;
4149 pSMB->t2.Reserved3 = 0;
4150 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4151 byte_count = params + 1 /* pad */ ;
4152 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4153 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4154 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4157 inc_rfc1001_len(pSMB, byte_count);
4158 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4160 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4161 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4163 cifs_dbg(FYI, "Send error in QFileInfo = %d", rc);
4164 } else { /* decode response */
4165 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4167 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4169 else if (get_bcc(&pSMBr->hdr) < 40)
4170 rc = -EIO; /* bad smb */
4171 else if (pFindData) {
4172 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4173 memcpy((char *) pFindData,
4174 (char *) &pSMBr->hdr.Protocol +
4175 data_offset, sizeof(FILE_ALL_INFO));
4179 cifs_buf_release(pSMB);
4181 goto QFileInfoRetry;
4187 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4188 const char *search_name, FILE_ALL_INFO *data,
4189 int legacy /* old style infolevel */,
4190 const struct nls_table *nls_codepage, int remap)
4192 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4193 TRANSACTION2_QPI_REQ *pSMB = NULL;
4194 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4198 __u16 params, byte_count;
4200 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4202 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4207 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4209 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4210 PATH_MAX, nls_codepage, remap);
4211 name_len++; /* trailing null */
4213 } else { /* BB improve the check for buffer overruns BB */
4214 name_len = strnlen(search_name, PATH_MAX);
4215 name_len++; /* trailing null */
4216 strncpy(pSMB->FileName, search_name, name_len);
4219 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4220 pSMB->TotalDataCount = 0;
4221 pSMB->MaxParameterCount = cpu_to_le16(2);
4222 /* BB find exact max SMB PDU from sess structure BB */
4223 pSMB->MaxDataCount = cpu_to_le16(4000);
4224 pSMB->MaxSetupCount = 0;
4228 pSMB->Reserved2 = 0;
4229 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4230 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4231 pSMB->DataCount = 0;
4232 pSMB->DataOffset = 0;
4233 pSMB->SetupCount = 1;
4234 pSMB->Reserved3 = 0;
4235 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4236 byte_count = params + 1 /* pad */ ;
4237 pSMB->TotalParameterCount = cpu_to_le16(params);
4238 pSMB->ParameterCount = pSMB->TotalParameterCount;
4240 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4242 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4243 pSMB->Reserved4 = 0;
4244 inc_rfc1001_len(pSMB, byte_count);
4245 pSMB->ByteCount = cpu_to_le16(byte_count);
4247 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4248 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4250 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4251 } else { /* decode response */
4252 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4254 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4256 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4257 rc = -EIO; /* bad smb */
4258 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4259 rc = -EIO; /* 24 or 26 expected but we do not read
4263 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4266 * On legacy responses we do not read the last field,
4267 * EAsize, fortunately since it varies by subdialect and
4268 * also note it differs on Set vs Get, ie two bytes or 4
4269 * bytes depending but we don't care here.
4272 size = sizeof(FILE_INFO_STANDARD);
4274 size = sizeof(FILE_ALL_INFO);
4275 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4280 cifs_buf_release(pSMB);
4282 goto QPathInfoRetry;
4288 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4289 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4291 struct smb_t2_qfi_req *pSMB = NULL;
4292 struct smb_t2_qfi_rsp *pSMBr = NULL;
4295 __u16 params, byte_count;
4298 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4303 params = 2 /* level */ + 2 /* fid */;
4304 pSMB->t2.TotalDataCount = 0;
4305 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4306 /* BB find exact max data count below from sess structure BB */
4307 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4308 pSMB->t2.MaxSetupCount = 0;
4309 pSMB->t2.Reserved = 0;
4311 pSMB->t2.Timeout = 0;
4312 pSMB->t2.Reserved2 = 0;
4313 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4315 pSMB->t2.DataCount = 0;
4316 pSMB->t2.DataOffset = 0;
4317 pSMB->t2.SetupCount = 1;
4318 pSMB->t2.Reserved3 = 0;
4319 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4320 byte_count = params + 1 /* pad */ ;
4321 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4322 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4323 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4326 inc_rfc1001_len(pSMB, byte_count);
4327 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4329 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4330 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4332 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d", rc);
4333 } else { /* decode response */
4334 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4336 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4337 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4338 rc = -EIO; /* bad smb */
4340 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4341 memcpy((char *) pFindData,
4342 (char *) &pSMBr->hdr.Protocol +
4344 sizeof(FILE_UNIX_BASIC_INFO));
4348 cifs_buf_release(pSMB);
4350 goto UnixQFileInfoRetry;
4356 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4357 const unsigned char *searchName,
4358 FILE_UNIX_BASIC_INFO *pFindData,
4359 const struct nls_table *nls_codepage, int remap)
4361 /* SMB_QUERY_FILE_UNIX_BASIC */
4362 TRANSACTION2_QPI_REQ *pSMB = NULL;
4363 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4365 int bytes_returned = 0;
4367 __u16 params, byte_count;
4369 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4371 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4376 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4378 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4379 PATH_MAX, nls_codepage, remap);
4380 name_len++; /* trailing null */
4382 } else { /* BB improve the check for buffer overruns BB */
4383 name_len = strnlen(searchName, PATH_MAX);
4384 name_len++; /* trailing null */
4385 strncpy(pSMB->FileName, searchName, name_len);
4388 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4389 pSMB->TotalDataCount = 0;
4390 pSMB->MaxParameterCount = cpu_to_le16(2);
4391 /* BB find exact max SMB PDU from sess structure BB */
4392 pSMB->MaxDataCount = cpu_to_le16(4000);
4393 pSMB->MaxSetupCount = 0;
4397 pSMB->Reserved2 = 0;
4398 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4399 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4400 pSMB->DataCount = 0;
4401 pSMB->DataOffset = 0;
4402 pSMB->SetupCount = 1;
4403 pSMB->Reserved3 = 0;
4404 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4405 byte_count = params + 1 /* pad */ ;
4406 pSMB->TotalParameterCount = cpu_to_le16(params);
4407 pSMB->ParameterCount = pSMB->TotalParameterCount;
4408 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4409 pSMB->Reserved4 = 0;
4410 inc_rfc1001_len(pSMB, byte_count);
4411 pSMB->ByteCount = cpu_to_le16(byte_count);
4413 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4414 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4416 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d", rc);
4417 } else { /* decode response */
4418 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4420 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4421 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4422 rc = -EIO; /* bad smb */
4424 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4425 memcpy((char *) pFindData,
4426 (char *) &pSMBr->hdr.Protocol +
4428 sizeof(FILE_UNIX_BASIC_INFO));
4431 cifs_buf_release(pSMB);
4433 goto UnixQPathInfoRetry;
4438 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4440 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4441 const char *searchName, struct cifs_sb_info *cifs_sb,
4442 __u16 *pnetfid, __u16 search_flags,
4443 struct cifs_search_info *psrch_inf, bool msearch)
4445 /* level 257 SMB_ */
4446 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4447 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4448 T2_FFIRST_RSP_PARMS *parms;
4450 int bytes_returned = 0;
4451 int name_len, remap;
4452 __u16 params, byte_count;
4453 struct nls_table *nls_codepage;
4455 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4458 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4463 nls_codepage = cifs_sb->local_nls;
4464 remap = cifs_remap(cifs_sb);
4466 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4468 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4469 PATH_MAX, nls_codepage, remap);
4470 /* We can not add the asterik earlier in case
4471 it got remapped to 0xF03A as if it were part of the
4472 directory name instead of a wildcard */
4475 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4476 pSMB->FileName[name_len+1] = 0;
4477 pSMB->FileName[name_len+2] = '*';
4478 pSMB->FileName[name_len+3] = 0;
4479 name_len += 4; /* now the trailing null */
4480 /* null terminate just in case */
4481 pSMB->FileName[name_len] = 0;
4482 pSMB->FileName[name_len+1] = 0;
4485 } else { /* BB add check for overrun of SMB buf BB */
4486 name_len = strnlen(searchName, PATH_MAX);
4487 /* BB fix here and in unicode clause above ie
4488 if (name_len > buffersize-header)
4489 free buffer exit; BB */
4490 strncpy(pSMB->FileName, searchName, name_len);
4492 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4493 pSMB->FileName[name_len+1] = '*';
4494 pSMB->FileName[name_len+2] = 0;
4499 params = 12 + name_len /* includes null */ ;
4500 pSMB->TotalDataCount = 0; /* no EAs */
4501 pSMB->MaxParameterCount = cpu_to_le16(10);
4502 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4503 pSMB->MaxSetupCount = 0;
4507 pSMB->Reserved2 = 0;
4508 byte_count = params + 1 /* pad */ ;
4509 pSMB->TotalParameterCount = cpu_to_le16(params);
4510 pSMB->ParameterCount = pSMB->TotalParameterCount;
4511 pSMB->ParameterOffset = cpu_to_le16(
4512 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4514 pSMB->DataCount = 0;
4515 pSMB->DataOffset = 0;
4516 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4517 pSMB->Reserved3 = 0;
4518 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4519 pSMB->SearchAttributes =
4520 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4522 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4523 pSMB->SearchFlags = cpu_to_le16(search_flags);
4524 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4526 /* BB what should we set StorageType to? Does it matter? BB */
4527 pSMB->SearchStorageType = 0;
4528 inc_rfc1001_len(pSMB, byte_count);
4529 pSMB->ByteCount = cpu_to_le16(byte_count);
4531 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4532 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4533 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4535 if (rc) {/* BB add logic to retry regular search if Unix search
4536 rejected unexpectedly by server */
4537 /* BB Add code to handle unsupported level rc */
4538 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4540 cifs_buf_release(pSMB);
4542 /* BB eventually could optimize out free and realloc of buf */
4545 goto findFirstRetry;
4546 } else { /* decode response */
4547 /* BB remember to free buffer if error BB */
4548 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4552 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4553 psrch_inf->unicode = true;
4555 psrch_inf->unicode = false;
4557 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4558 psrch_inf->smallBuf = 0;
4559 psrch_inf->srch_entries_start =
4560 (char *) &pSMBr->hdr.Protocol +
4561 le16_to_cpu(pSMBr->t2.DataOffset);
4562 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4563 le16_to_cpu(pSMBr->t2.ParameterOffset));
4565 if (parms->EndofSearch)
4566 psrch_inf->endOfSearch = true;
4568 psrch_inf->endOfSearch = false;
4570 psrch_inf->entries_in_buffer =
4571 le16_to_cpu(parms->SearchCount);
4572 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4573 psrch_inf->entries_in_buffer;
4574 lnoff = le16_to_cpu(parms->LastNameOffset);
4575 if (CIFSMaxBufSize < lnoff) {
4576 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4577 psrch_inf->last_entry = NULL;
4581 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4585 *pnetfid = parms->SearchHandle;
4587 cifs_buf_release(pSMB);
4594 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4595 __u16 searchHandle, __u16 search_flags,
4596 struct cifs_search_info *psrch_inf)
4598 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4599 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4600 T2_FNEXT_RSP_PARMS *parms;
4601 char *response_data;
4604 unsigned int name_len;
4605 __u16 params, byte_count;
4607 cifs_dbg(FYI, "In FindNext\n");
4609 if (psrch_inf->endOfSearch)
4612 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4617 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4619 pSMB->TotalDataCount = 0; /* no EAs */
4620 pSMB->MaxParameterCount = cpu_to_le16(8);
4621 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4622 pSMB->MaxSetupCount = 0;
4626 pSMB->Reserved2 = 0;
4627 pSMB->ParameterOffset = cpu_to_le16(
4628 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4629 pSMB->DataCount = 0;
4630 pSMB->DataOffset = 0;
4631 pSMB->SetupCount = 1;
4632 pSMB->Reserved3 = 0;
4633 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4634 pSMB->SearchHandle = searchHandle; /* always kept as le */
4636 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4637 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4638 pSMB->ResumeKey = psrch_inf->resume_key;
4639 pSMB->SearchFlags = cpu_to_le16(search_flags);
4641 name_len = psrch_inf->resume_name_len;
4643 if (name_len < PATH_MAX) {
4644 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4645 byte_count += name_len;
4646 /* 14 byte parm len above enough for 2 byte null terminator */
4647 pSMB->ResumeFileName[name_len] = 0;
4648 pSMB->ResumeFileName[name_len+1] = 0;
4651 goto FNext2_err_exit;
4653 byte_count = params + 1 /* pad */ ;
4654 pSMB->TotalParameterCount = cpu_to_le16(params);
4655 pSMB->ParameterCount = pSMB->TotalParameterCount;
4656 inc_rfc1001_len(pSMB, byte_count);
4657 pSMB->ByteCount = cpu_to_le16(byte_count);
4659 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4660 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4661 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4664 psrch_inf->endOfSearch = true;
4665 cifs_buf_release(pSMB);
4666 rc = 0; /* search probably was closed at end of search*/
4668 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4669 } else { /* decode response */
4670 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4675 /* BB fixme add lock for file (srch_info) struct here */
4676 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4677 psrch_inf->unicode = true;
4679 psrch_inf->unicode = false;
4680 response_data = (char *) &pSMBr->hdr.Protocol +
4681 le16_to_cpu(pSMBr->t2.ParameterOffset);
4682 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4683 response_data = (char *)&pSMBr->hdr.Protocol +
4684 le16_to_cpu(pSMBr->t2.DataOffset);
4685 if (psrch_inf->smallBuf)
4686 cifs_small_buf_release(
4687 psrch_inf->ntwrk_buf_start);
4689 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4690 psrch_inf->srch_entries_start = response_data;
4691 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4692 psrch_inf->smallBuf = 0;
4693 if (parms->EndofSearch)
4694 psrch_inf->endOfSearch = true;
4696 psrch_inf->endOfSearch = false;
4697 psrch_inf->entries_in_buffer =
4698 le16_to_cpu(parms->SearchCount);
4699 psrch_inf->index_of_last_entry +=
4700 psrch_inf->entries_in_buffer;
4701 lnoff = le16_to_cpu(parms->LastNameOffset);
4702 if (CIFSMaxBufSize < lnoff) {
4703 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4704 psrch_inf->last_entry = NULL;
4707 psrch_inf->last_entry =
4708 psrch_inf->srch_entries_start + lnoff;
4710 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4711 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4713 /* BB fixme add unlock here */
4718 /* BB On error, should we leave previous search buf (and count and
4719 last entry fields) intact or free the previous one? */
4721 /* Note: On -EAGAIN error only caller can retry on handle based calls
4722 since file handle passed in no longer valid */
4725 cifs_buf_release(pSMB);
4730 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4731 const __u16 searchHandle)
4734 FINDCLOSE_REQ *pSMB = NULL;
4736 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4737 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4739 /* no sense returning error if session restarted
4740 as file handle has been closed */
4746 pSMB->FileID = searchHandle;
4747 pSMB->ByteCount = 0;
4748 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4749 cifs_small_buf_release(pSMB);
4751 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4753 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4755 /* Since session is dead, search handle closed on server already */
4763 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4764 const char *search_name, __u64 *inode_number,
4765 const struct nls_table *nls_codepage, int remap)
4768 TRANSACTION2_QPI_REQ *pSMB = NULL;
4769 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4770 int name_len, bytes_returned;
4771 __u16 params, byte_count;
4773 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4777 GetInodeNumberRetry:
4778 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4783 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4785 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4786 search_name, PATH_MAX, nls_codepage,
4788 name_len++; /* trailing null */
4790 } else { /* BB improve the check for buffer overruns BB */
4791 name_len = strnlen(search_name, PATH_MAX);
4792 name_len++; /* trailing null */
4793 strncpy(pSMB->FileName, search_name, name_len);
4796 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4797 pSMB->TotalDataCount = 0;
4798 pSMB->MaxParameterCount = cpu_to_le16(2);
4799 /* BB find exact max data count below from sess structure BB */
4800 pSMB->MaxDataCount = cpu_to_le16(4000);
4801 pSMB->MaxSetupCount = 0;
4805 pSMB->Reserved2 = 0;
4806 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4807 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4808 pSMB->DataCount = 0;
4809 pSMB->DataOffset = 0;
4810 pSMB->SetupCount = 1;
4811 pSMB->Reserved3 = 0;
4812 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4813 byte_count = params + 1 /* pad */ ;
4814 pSMB->TotalParameterCount = cpu_to_le16(params);
4815 pSMB->ParameterCount = pSMB->TotalParameterCount;
4816 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4817 pSMB->Reserved4 = 0;
4818 inc_rfc1001_len(pSMB, byte_count);
4819 pSMB->ByteCount = cpu_to_le16(byte_count);
4821 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4822 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4824 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4826 /* decode response */
4827 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4828 /* BB also check enough total bytes returned */
4829 if (rc || get_bcc(&pSMBr->hdr) < 2)
4830 /* If rc should we check for EOPNOSUPP and
4831 disable the srvino flag? or in caller? */
4832 rc = -EIO; /* bad smb */
4834 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4835 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4836 struct file_internal_info *pfinfo;
4837 /* BB Do we need a cast or hash here ? */
4839 cifs_dbg(FYI, "Illegal size ret in QryIntrnlInf\n");
4841 goto GetInodeNumOut;
4843 pfinfo = (struct file_internal_info *)
4844 (data_offset + (char *) &pSMBr->hdr.Protocol);
4845 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4849 cifs_buf_release(pSMB);
4851 goto GetInodeNumberRetry;
4856 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4857 const char *search_name, struct dfs_info3_param **target_nodes,
4858 unsigned int *num_of_nodes,
4859 const struct nls_table *nls_codepage, int remap)
4861 /* TRANS2_GET_DFS_REFERRAL */
4862 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4863 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4867 __u16 params, byte_count;
4869 *target_nodes = NULL;
4871 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4872 if (ses == NULL || ses->tcon_ipc == NULL)
4876 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4881 /* server pointer checked in called function,
4882 but should never be null here anyway */
4883 pSMB->hdr.Mid = get_next_mid(ses->server);
4884 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4885 pSMB->hdr.Uid = ses->Suid;
4886 if (ses->capabilities & CAP_STATUS32)
4887 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4888 if (ses->capabilities & CAP_DFS)
4889 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4891 if (ses->capabilities & CAP_UNICODE) {
4892 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4894 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4895 search_name, PATH_MAX, nls_codepage,
4897 name_len++; /* trailing null */
4899 } else { /* BB improve the check for buffer overruns BB */
4900 name_len = strnlen(search_name, PATH_MAX);
4901 name_len++; /* trailing null */
4902 strncpy(pSMB->RequestFileName, search_name, name_len);
4905 if (ses->server->sign)
4906 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4908 pSMB->hdr.Uid = ses->Suid;
4910 params = 2 /* level */ + name_len /*includes null */ ;
4911 pSMB->TotalDataCount = 0;
4912 pSMB->DataCount = 0;
4913 pSMB->DataOffset = 0;
4914 pSMB->MaxParameterCount = 0;
4915 /* BB find exact max SMB PDU from sess structure BB */
4916 pSMB->MaxDataCount = cpu_to_le16(4000);
4917 pSMB->MaxSetupCount = 0;
4921 pSMB->Reserved2 = 0;
4922 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4923 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4924 pSMB->SetupCount = 1;
4925 pSMB->Reserved3 = 0;
4926 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4927 byte_count = params + 3 /* pad */ ;
4928 pSMB->ParameterCount = cpu_to_le16(params);
4929 pSMB->TotalParameterCount = pSMB->ParameterCount;
4930 pSMB->MaxReferralLevel = cpu_to_le16(3);
4931 inc_rfc1001_len(pSMB, byte_count);
4932 pSMB->ByteCount = cpu_to_le16(byte_count);
4934 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4935 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4937 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4940 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4942 /* BB Also check if enough total bytes returned? */
4943 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4944 rc = -EIO; /* bad smb */
4948 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4949 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4951 /* parse returned result into more usable form */
4952 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4953 le16_to_cpu(pSMBr->t2.DataCount),
4954 num_of_nodes, target_nodes, nls_codepage,
4956 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4959 cifs_buf_release(pSMB);
4967 /* Query File System Info such as free space to old servers such as Win 9x */
4969 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4970 struct kstatfs *FSData)
4972 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4973 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4974 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4975 FILE_SYSTEM_ALLOC_INFO *response_data;
4977 int bytes_returned = 0;
4978 __u16 params, byte_count;
4980 cifs_dbg(FYI, "OldQFSInfo\n");
4982 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4987 params = 2; /* level */
4988 pSMB->TotalDataCount = 0;
4989 pSMB->MaxParameterCount = cpu_to_le16(2);
4990 pSMB->MaxDataCount = cpu_to_le16(1000);
4991 pSMB->MaxSetupCount = 0;
4995 pSMB->Reserved2 = 0;
4996 byte_count = params + 1 /* pad */ ;
4997 pSMB->TotalParameterCount = cpu_to_le16(params);
4998 pSMB->ParameterCount = pSMB->TotalParameterCount;
4999 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5000 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5001 pSMB->DataCount = 0;
5002 pSMB->DataOffset = 0;
5003 pSMB->SetupCount = 1;
5004 pSMB->Reserved3 = 0;
5005 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5006 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
5007 inc_rfc1001_len(pSMB, byte_count);
5008 pSMB->ByteCount = cpu_to_le16(byte_count);
5010 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5011 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5013 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5014 } else { /* decode response */
5015 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5017 if (rc || get_bcc(&pSMBr->hdr) < 18)
5018 rc = -EIO; /* bad smb */
5020 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5021 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
5022 get_bcc(&pSMBr->hdr), data_offset);
5024 response_data = (FILE_SYSTEM_ALLOC_INFO *)
5025 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5027 le16_to_cpu(response_data->BytesPerSector) *
5028 le32_to_cpu(response_data->
5029 SectorsPerAllocationUnit);
5031 le32_to_cpu(response_data->TotalAllocationUnits);
5032 FSData->f_bfree = FSData->f_bavail =
5033 le32_to_cpu(response_data->FreeAllocationUnits);
5034 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5035 (unsigned long long)FSData->f_blocks,
5036 (unsigned long long)FSData->f_bfree,
5040 cifs_buf_release(pSMB);
5043 goto oldQFSInfoRetry;
5049 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
5050 struct kstatfs *FSData)
5052 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5053 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5054 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5055 FILE_SYSTEM_INFO *response_data;
5057 int bytes_returned = 0;
5058 __u16 params, byte_count;
5060 cifs_dbg(FYI, "In QFSInfo\n");
5062 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5067 params = 2; /* level */
5068 pSMB->TotalDataCount = 0;
5069 pSMB->MaxParameterCount = cpu_to_le16(2);
5070 pSMB->MaxDataCount = cpu_to_le16(1000);
5071 pSMB->MaxSetupCount = 0;
5075 pSMB->Reserved2 = 0;
5076 byte_count = params + 1 /* pad */ ;
5077 pSMB->TotalParameterCount = cpu_to_le16(params);
5078 pSMB->ParameterCount = pSMB->TotalParameterCount;
5079 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5080 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5081 pSMB->DataCount = 0;
5082 pSMB->DataOffset = 0;
5083 pSMB->SetupCount = 1;
5084 pSMB->Reserved3 = 0;
5085 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5086 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5087 inc_rfc1001_len(pSMB, byte_count);
5088 pSMB->ByteCount = cpu_to_le16(byte_count);
5090 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5091 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5093 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5094 } else { /* decode response */
5095 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5097 if (rc || get_bcc(&pSMBr->hdr) < 24)
5098 rc = -EIO; /* bad smb */
5100 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5104 *) (((char *) &pSMBr->hdr.Protocol) +
5107 le32_to_cpu(response_data->BytesPerSector) *
5108 le32_to_cpu(response_data->
5109 SectorsPerAllocationUnit);
5111 le64_to_cpu(response_data->TotalAllocationUnits);
5112 FSData->f_bfree = FSData->f_bavail =
5113 le64_to_cpu(response_data->FreeAllocationUnits);
5114 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5115 (unsigned long long)FSData->f_blocks,
5116 (unsigned long long)FSData->f_bfree,
5120 cifs_buf_release(pSMB);
5129 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5131 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5132 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5133 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5134 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5136 int bytes_returned = 0;
5137 __u16 params, byte_count;
5139 cifs_dbg(FYI, "In QFSAttributeInfo\n");
5141 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5146 params = 2; /* level */
5147 pSMB->TotalDataCount = 0;
5148 pSMB->MaxParameterCount = cpu_to_le16(2);
5149 /* BB find exact max SMB PDU from sess structure BB */
5150 pSMB->MaxDataCount = cpu_to_le16(1000);
5151 pSMB->MaxSetupCount = 0;
5155 pSMB->Reserved2 = 0;
5156 byte_count = params + 1 /* pad */ ;
5157 pSMB->TotalParameterCount = cpu_to_le16(params);
5158 pSMB->ParameterCount = pSMB->TotalParameterCount;
5159 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5160 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5161 pSMB->DataCount = 0;
5162 pSMB->DataOffset = 0;
5163 pSMB->SetupCount = 1;
5164 pSMB->Reserved3 = 0;
5165 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5166 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5167 inc_rfc1001_len(pSMB, byte_count);
5168 pSMB->ByteCount = cpu_to_le16(byte_count);
5170 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5171 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5173 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5174 } else { /* decode response */
5175 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5177 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5178 /* BB also check if enough bytes returned */
5179 rc = -EIO; /* bad smb */
5181 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5183 (FILE_SYSTEM_ATTRIBUTE_INFO
5184 *) (((char *) &pSMBr->hdr.Protocol) +
5186 memcpy(&tcon->fsAttrInfo, response_data,
5187 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5190 cifs_buf_release(pSMB);
5193 goto QFSAttributeRetry;
5199 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5201 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5202 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5203 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5204 FILE_SYSTEM_DEVICE_INFO *response_data;
5206 int bytes_returned = 0;
5207 __u16 params, byte_count;
5209 cifs_dbg(FYI, "In QFSDeviceInfo\n");
5211 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5216 params = 2; /* level */
5217 pSMB->TotalDataCount = 0;
5218 pSMB->MaxParameterCount = cpu_to_le16(2);
5219 /* BB find exact max SMB PDU from sess structure BB */
5220 pSMB->MaxDataCount = cpu_to_le16(1000);
5221 pSMB->MaxSetupCount = 0;
5225 pSMB->Reserved2 = 0;
5226 byte_count = params + 1 /* pad */ ;
5227 pSMB->TotalParameterCount = cpu_to_le16(params);
5228 pSMB->ParameterCount = pSMB->TotalParameterCount;
5229 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5230 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5232 pSMB->DataCount = 0;
5233 pSMB->DataOffset = 0;
5234 pSMB->SetupCount = 1;
5235 pSMB->Reserved3 = 0;
5236 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5237 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5238 inc_rfc1001_len(pSMB, byte_count);
5239 pSMB->ByteCount = cpu_to_le16(byte_count);
5241 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5242 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5244 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5245 } else { /* decode response */
5246 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5248 if (rc || get_bcc(&pSMBr->hdr) <
5249 sizeof(FILE_SYSTEM_DEVICE_INFO))
5250 rc = -EIO; /* bad smb */
5252 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5254 (FILE_SYSTEM_DEVICE_INFO *)
5255 (((char *) &pSMBr->hdr.Protocol) +
5257 memcpy(&tcon->fsDevInfo, response_data,
5258 sizeof(FILE_SYSTEM_DEVICE_INFO));
5261 cifs_buf_release(pSMB);
5264 goto QFSDeviceRetry;
5270 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5272 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5273 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5274 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5275 FILE_SYSTEM_UNIX_INFO *response_data;
5277 int bytes_returned = 0;
5278 __u16 params, byte_count;
5280 cifs_dbg(FYI, "In QFSUnixInfo\n");
5282 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5283 (void **) &pSMB, (void **) &pSMBr);
5287 params = 2; /* level */
5288 pSMB->TotalDataCount = 0;
5289 pSMB->DataCount = 0;
5290 pSMB->DataOffset = 0;
5291 pSMB->MaxParameterCount = cpu_to_le16(2);
5292 /* BB find exact max SMB PDU from sess structure BB */
5293 pSMB->MaxDataCount = cpu_to_le16(100);
5294 pSMB->MaxSetupCount = 0;
5298 pSMB->Reserved2 = 0;
5299 byte_count = params + 1 /* pad */ ;
5300 pSMB->ParameterCount = cpu_to_le16(params);
5301 pSMB->TotalParameterCount = pSMB->ParameterCount;
5302 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5303 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5304 pSMB->SetupCount = 1;
5305 pSMB->Reserved3 = 0;
5306 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5307 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5308 inc_rfc1001_len(pSMB, byte_count);
5309 pSMB->ByteCount = cpu_to_le16(byte_count);
5311 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5312 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5314 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5315 } else { /* decode response */
5316 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5318 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5319 rc = -EIO; /* bad smb */
5321 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5323 (FILE_SYSTEM_UNIX_INFO
5324 *) (((char *) &pSMBr->hdr.Protocol) +
5326 memcpy(&tcon->fsUnixInfo, response_data,
5327 sizeof(FILE_SYSTEM_UNIX_INFO));
5330 cifs_buf_release(pSMB);
5340 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5342 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5343 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5344 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5346 int bytes_returned = 0;
5347 __u16 params, param_offset, offset, byte_count;
5349 cifs_dbg(FYI, "In SETFSUnixInfo\n");
5351 /* BB switch to small buf init to save memory */
5352 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5353 (void **) &pSMB, (void **) &pSMBr);
5357 params = 4; /* 2 bytes zero followed by info level. */
5358 pSMB->MaxSetupCount = 0;
5362 pSMB->Reserved2 = 0;
5363 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5365 offset = param_offset + params;
5367 pSMB->MaxParameterCount = cpu_to_le16(4);
5368 /* BB find exact max SMB PDU from sess structure BB */
5369 pSMB->MaxDataCount = cpu_to_le16(100);
5370 pSMB->SetupCount = 1;
5371 pSMB->Reserved3 = 0;
5372 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5373 byte_count = 1 /* pad */ + params + 12;
5375 pSMB->DataCount = cpu_to_le16(12);
5376 pSMB->ParameterCount = cpu_to_le16(params);
5377 pSMB->TotalDataCount = pSMB->DataCount;
5378 pSMB->TotalParameterCount = pSMB->ParameterCount;
5379 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5380 pSMB->DataOffset = cpu_to_le16(offset);
5384 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5387 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5388 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5389 pSMB->ClientUnixCap = cpu_to_le64(cap);
5391 inc_rfc1001_len(pSMB, byte_count);
5392 pSMB->ByteCount = cpu_to_le16(byte_count);
5394 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5395 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5397 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5398 } else { /* decode response */
5399 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5401 rc = -EIO; /* bad smb */
5403 cifs_buf_release(pSMB);
5406 goto SETFSUnixRetry;
5414 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5415 struct kstatfs *FSData)
5417 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5418 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5419 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5420 FILE_SYSTEM_POSIX_INFO *response_data;
5422 int bytes_returned = 0;
5423 __u16 params, byte_count;
5425 cifs_dbg(FYI, "In QFSPosixInfo\n");
5427 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5432 params = 2; /* level */
5433 pSMB->TotalDataCount = 0;
5434 pSMB->DataCount = 0;
5435 pSMB->DataOffset = 0;
5436 pSMB->MaxParameterCount = cpu_to_le16(2);
5437 /* BB find exact max SMB PDU from sess structure BB */
5438 pSMB->MaxDataCount = cpu_to_le16(100);
5439 pSMB->MaxSetupCount = 0;
5443 pSMB->Reserved2 = 0;
5444 byte_count = params + 1 /* pad */ ;
5445 pSMB->ParameterCount = cpu_to_le16(params);
5446 pSMB->TotalParameterCount = pSMB->ParameterCount;
5447 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5448 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5449 pSMB->SetupCount = 1;
5450 pSMB->Reserved3 = 0;
5451 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5452 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5453 inc_rfc1001_len(pSMB, byte_count);
5454 pSMB->ByteCount = cpu_to_le16(byte_count);
5456 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5457 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5459 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5460 } else { /* decode response */
5461 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5463 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5464 rc = -EIO; /* bad smb */
5466 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5468 (FILE_SYSTEM_POSIX_INFO
5469 *) (((char *) &pSMBr->hdr.Protocol) +
5472 le32_to_cpu(response_data->BlockSize);
5474 le64_to_cpu(response_data->TotalBlocks);
5476 le64_to_cpu(response_data->BlocksAvail);
5477 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5478 FSData->f_bavail = FSData->f_bfree;
5481 le64_to_cpu(response_data->UserBlocksAvail);
5483 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5485 le64_to_cpu(response_data->TotalFileNodes);
5486 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5488 le64_to_cpu(response_data->FreeFileNodes);
5491 cifs_buf_release(pSMB);
5501 * We can not use write of zero bytes trick to set file size due to need for
5502 * large file support. Also note that this SetPathInfo is preferred to
5503 * SetFileInfo based method in next routine which is only needed to work around
5504 * a sharing violation bugin Samba which this routine can run into.
5507 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5508 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5509 bool set_allocation)
5511 struct smb_com_transaction2_spi_req *pSMB = NULL;
5512 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5513 struct file_end_of_file_info *parm_data;
5516 int bytes_returned = 0;
5517 int remap = cifs_remap(cifs_sb);
5519 __u16 params, byte_count, data_count, param_offset, offset;
5521 cifs_dbg(FYI, "In SetEOF\n");
5523 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5528 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5530 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5531 PATH_MAX, cifs_sb->local_nls, remap);
5532 name_len++; /* trailing null */
5534 } else { /* BB improve the check for buffer overruns BB */
5535 name_len = strnlen(file_name, PATH_MAX);
5536 name_len++; /* trailing null */
5537 strncpy(pSMB->FileName, file_name, name_len);
5539 params = 6 + name_len;
5540 data_count = sizeof(struct file_end_of_file_info);
5541 pSMB->MaxParameterCount = cpu_to_le16(2);
5542 pSMB->MaxDataCount = cpu_to_le16(4100);
5543 pSMB->MaxSetupCount = 0;
5547 pSMB->Reserved2 = 0;
5548 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5549 InformationLevel) - 4;
5550 offset = param_offset + params;
5551 if (set_allocation) {
5552 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5553 pSMB->InformationLevel =
5554 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5556 pSMB->InformationLevel =
5557 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5558 } else /* Set File Size */ {
5559 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5560 pSMB->InformationLevel =
5561 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5563 pSMB->InformationLevel =
5564 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5568 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5570 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5571 pSMB->DataOffset = cpu_to_le16(offset);
5572 pSMB->SetupCount = 1;
5573 pSMB->Reserved3 = 0;
5574 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5575 byte_count = 3 /* pad */ + params + data_count;
5576 pSMB->DataCount = cpu_to_le16(data_count);
5577 pSMB->TotalDataCount = pSMB->DataCount;
5578 pSMB->ParameterCount = cpu_to_le16(params);
5579 pSMB->TotalParameterCount = pSMB->ParameterCount;
5580 pSMB->Reserved4 = 0;
5581 inc_rfc1001_len(pSMB, byte_count);
5582 parm_data->FileSize = cpu_to_le64(size);
5583 pSMB->ByteCount = cpu_to_le16(byte_count);
5584 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5585 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5587 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5589 cifs_buf_release(pSMB);
5598 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5599 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5601 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5602 struct file_end_of_file_info *parm_data;
5604 __u16 params, param_offset, offset, byte_count, count;
5606 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5608 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5613 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5614 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5617 pSMB->MaxSetupCount = 0;
5621 pSMB->Reserved2 = 0;
5622 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5623 offset = param_offset + params;
5625 count = sizeof(struct file_end_of_file_info);
5626 pSMB->MaxParameterCount = cpu_to_le16(2);
5627 /* BB find exact max SMB PDU from sess structure BB */
5628 pSMB->MaxDataCount = cpu_to_le16(1000);
5629 pSMB->SetupCount = 1;
5630 pSMB->Reserved3 = 0;
5631 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5632 byte_count = 3 /* pad */ + params + count;
5633 pSMB->DataCount = cpu_to_le16(count);
5634 pSMB->ParameterCount = cpu_to_le16(params);
5635 pSMB->TotalDataCount = pSMB->DataCount;
5636 pSMB->TotalParameterCount = pSMB->ParameterCount;
5637 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5639 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5641 pSMB->DataOffset = cpu_to_le16(offset);
5642 parm_data->FileSize = cpu_to_le64(size);
5643 pSMB->Fid = cfile->fid.netfid;
5644 if (set_allocation) {
5645 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5646 pSMB->InformationLevel =
5647 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5649 pSMB->InformationLevel =
5650 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5651 } else /* Set File Size */ {
5652 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5653 pSMB->InformationLevel =
5654 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5656 pSMB->InformationLevel =
5657 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5659 pSMB->Reserved4 = 0;
5660 inc_rfc1001_len(pSMB, byte_count);
5661 pSMB->ByteCount = cpu_to_le16(byte_count);
5662 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5663 cifs_small_buf_release(pSMB);
5665 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5669 /* Note: On -EAGAIN error only caller can retry on handle based calls
5670 since file handle passed in no longer valid */
5675 /* Some legacy servers such as NT4 require that the file times be set on
5676 an open handle, rather than by pathname - this is awkward due to
5677 potential access conflicts on the open, but it is unavoidable for these
5678 old servers since the only other choice is to go from 100 nanosecond DCE
5679 time and resort to the original setpathinfo level which takes the ancient
5680 DOS time format with 2 second granularity */
5682 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5683 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5685 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5688 __u16 params, param_offset, offset, byte_count, count;
5690 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5691 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5696 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5697 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5700 pSMB->MaxSetupCount = 0;
5704 pSMB->Reserved2 = 0;
5705 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5706 offset = param_offset + params;
5708 data_offset = (char *)pSMB +
5709 offsetof(struct smb_hdr, Protocol) + offset;
5711 count = sizeof(FILE_BASIC_INFO);
5712 pSMB->MaxParameterCount = cpu_to_le16(2);
5713 /* BB find max SMB PDU from sess */
5714 pSMB->MaxDataCount = cpu_to_le16(1000);
5715 pSMB->SetupCount = 1;
5716 pSMB->Reserved3 = 0;
5717 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5718 byte_count = 3 /* pad */ + params + count;
5719 pSMB->DataCount = cpu_to_le16(count);
5720 pSMB->ParameterCount = cpu_to_le16(params);
5721 pSMB->TotalDataCount = pSMB->DataCount;
5722 pSMB->TotalParameterCount = pSMB->ParameterCount;
5723 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5724 pSMB->DataOffset = cpu_to_le16(offset);
5726 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5727 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5729 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5730 pSMB->Reserved4 = 0;
5731 inc_rfc1001_len(pSMB, byte_count);
5732 pSMB->ByteCount = cpu_to_le16(byte_count);
5733 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5734 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5735 cifs_small_buf_release(pSMB);
5737 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5740 /* Note: On -EAGAIN error only caller can retry on handle based calls
5741 since file handle passed in no longer valid */
5747 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5748 bool delete_file, __u16 fid, __u32 pid_of_opener)
5750 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5753 __u16 params, param_offset, offset, byte_count, count;
5755 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5756 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5761 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5762 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5765 pSMB->MaxSetupCount = 0;
5769 pSMB->Reserved2 = 0;
5770 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5771 offset = param_offset + params;
5773 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5776 pSMB->MaxParameterCount = cpu_to_le16(2);
5777 /* BB find max SMB PDU from sess */
5778 pSMB->MaxDataCount = cpu_to_le16(1000);
5779 pSMB->SetupCount = 1;
5780 pSMB->Reserved3 = 0;
5781 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5782 byte_count = 3 /* pad */ + params + count;
5783 pSMB->DataCount = cpu_to_le16(count);
5784 pSMB->ParameterCount = cpu_to_le16(params);
5785 pSMB->TotalDataCount = pSMB->DataCount;
5786 pSMB->TotalParameterCount = pSMB->ParameterCount;
5787 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5788 pSMB->DataOffset = cpu_to_le16(offset);
5790 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5791 pSMB->Reserved4 = 0;
5792 inc_rfc1001_len(pSMB, byte_count);
5793 pSMB->ByteCount = cpu_to_le16(byte_count);
5794 *data_offset = delete_file ? 1 : 0;
5795 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5796 cifs_small_buf_release(pSMB);
5798 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5804 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5805 const char *fileName, const FILE_BASIC_INFO *data,
5806 const struct nls_table *nls_codepage, int remap)
5808 TRANSACTION2_SPI_REQ *pSMB = NULL;
5809 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5812 int bytes_returned = 0;
5814 __u16 params, param_offset, offset, byte_count, count;
5816 cifs_dbg(FYI, "In SetTimes\n");
5819 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5824 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5826 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5827 PATH_MAX, nls_codepage, remap);
5828 name_len++; /* trailing null */
5830 } else { /* BB improve the check for buffer overruns BB */
5831 name_len = strnlen(fileName, PATH_MAX);
5832 name_len++; /* trailing null */
5833 strncpy(pSMB->FileName, fileName, name_len);
5836 params = 6 + name_len;
5837 count = sizeof(FILE_BASIC_INFO);
5838 pSMB->MaxParameterCount = cpu_to_le16(2);
5839 /* BB find max SMB PDU from sess structure BB */
5840 pSMB->MaxDataCount = cpu_to_le16(1000);
5841 pSMB->MaxSetupCount = 0;
5845 pSMB->Reserved2 = 0;
5846 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5847 InformationLevel) - 4;
5848 offset = param_offset + params;
5849 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5850 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5851 pSMB->DataOffset = cpu_to_le16(offset);
5852 pSMB->SetupCount = 1;
5853 pSMB->Reserved3 = 0;
5854 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5855 byte_count = 3 /* pad */ + params + count;
5857 pSMB->DataCount = cpu_to_le16(count);
5858 pSMB->ParameterCount = cpu_to_le16(params);
5859 pSMB->TotalDataCount = pSMB->DataCount;
5860 pSMB->TotalParameterCount = pSMB->ParameterCount;
5861 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5862 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5864 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5865 pSMB->Reserved4 = 0;
5866 inc_rfc1001_len(pSMB, byte_count);
5867 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5868 pSMB->ByteCount = cpu_to_le16(byte_count);
5869 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5870 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5872 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5874 cifs_buf_release(pSMB);
5882 /* Can not be used to set time stamps yet (due to old DOS time format) */
5883 /* Can be used to set attributes */
5884 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5885 handling it anyway and NT4 was what we thought it would be needed for
5886 Do not delete it until we prove whether needed for Win9x though */
5888 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
5889 __u16 dos_attrs, const struct nls_table *nls_codepage)
5891 SETATTR_REQ *pSMB = NULL;
5892 SETATTR_RSP *pSMBr = NULL;
5897 cifs_dbg(FYI, "In SetAttrLegacy\n");
5900 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5905 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5907 ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
5908 PATH_MAX, nls_codepage);
5909 name_len++; /* trailing null */
5911 } else { /* BB improve the check for buffer overruns BB */
5912 name_len = strnlen(fileName, PATH_MAX);
5913 name_len++; /* trailing null */
5914 strncpy(pSMB->fileName, fileName, name_len);
5916 pSMB->attr = cpu_to_le16(dos_attrs);
5917 pSMB->BufferFormat = 0x04;
5918 inc_rfc1001_len(pSMB, name_len + 1);
5919 pSMB->ByteCount = cpu_to_le16(name_len + 1);
5920 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5921 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5923 cifs_dbg(FYI, "Error in LegacySetAttr = %d\n", rc);
5925 cifs_buf_release(pSMB);
5928 goto SetAttrLgcyRetry;
5932 #endif /* temporarily unneeded SetAttr legacy function */
5935 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5936 const struct cifs_unix_set_info_args *args)
5938 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5939 u64 mode = args->mode;
5941 if (uid_valid(args->uid))
5942 uid = from_kuid(&init_user_ns, args->uid);
5943 if (gid_valid(args->gid))
5944 gid = from_kgid(&init_user_ns, args->gid);
5947 * Samba server ignores set of file size to zero due to bugs in some
5948 * older clients, but we should be precise - we use SetFileSize to
5949 * set file size and do not want to truncate file size to zero
5950 * accidentally as happened on one Samba server beta by putting
5951 * zero instead of -1 here
5953 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5954 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5955 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5956 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5957 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5958 data_offset->Uid = cpu_to_le64(uid);
5959 data_offset->Gid = cpu_to_le64(gid);
5960 /* better to leave device as zero when it is */
5961 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5962 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5963 data_offset->Permissions = cpu_to_le64(mode);
5966 data_offset->Type = cpu_to_le32(UNIX_FILE);
5967 else if (S_ISDIR(mode))
5968 data_offset->Type = cpu_to_le32(UNIX_DIR);
5969 else if (S_ISLNK(mode))
5970 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5971 else if (S_ISCHR(mode))
5972 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5973 else if (S_ISBLK(mode))
5974 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5975 else if (S_ISFIFO(mode))
5976 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5977 else if (S_ISSOCK(mode))
5978 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5982 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5983 const struct cifs_unix_set_info_args *args,
5984 u16 fid, u32 pid_of_opener)
5986 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5989 u16 params, param_offset, offset, byte_count, count;
5991 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5992 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5997 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5998 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
6001 pSMB->MaxSetupCount = 0;
6005 pSMB->Reserved2 = 0;
6006 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
6007 offset = param_offset + params;
6009 data_offset = (char *)pSMB +
6010 offsetof(struct smb_hdr, Protocol) + offset;
6012 count = sizeof(FILE_UNIX_BASIC_INFO);
6014 pSMB->MaxParameterCount = cpu_to_le16(2);
6015 /* BB find max SMB PDU from sess */
6016 pSMB->MaxDataCount = cpu_to_le16(1000);
6017 pSMB->SetupCount = 1;
6018 pSMB->Reserved3 = 0;
6019 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
6020 byte_count = 3 /* pad */ + params + count;
6021 pSMB->DataCount = cpu_to_le16(count);
6022 pSMB->ParameterCount = cpu_to_le16(params);
6023 pSMB->TotalDataCount = pSMB->DataCount;
6024 pSMB->TotalParameterCount = pSMB->ParameterCount;
6025 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6026 pSMB->DataOffset = cpu_to_le16(offset);
6028 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6029 pSMB->Reserved4 = 0;
6030 inc_rfc1001_len(pSMB, byte_count);
6031 pSMB->ByteCount = cpu_to_le16(byte_count);
6033 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
6035 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
6036 cifs_small_buf_release(pSMB);
6038 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
6041 /* Note: On -EAGAIN error only caller can retry on handle based calls
6042 since file handle passed in no longer valid */
6048 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
6049 const char *file_name,
6050 const struct cifs_unix_set_info_args *args,
6051 const struct nls_table *nls_codepage, int remap)
6053 TRANSACTION2_SPI_REQ *pSMB = NULL;
6054 TRANSACTION2_SPI_RSP *pSMBr = NULL;
6057 int bytes_returned = 0;
6058 FILE_UNIX_BASIC_INFO *data_offset;
6059 __u16 params, param_offset, offset, count, byte_count;
6061 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
6063 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6068 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6070 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6071 PATH_MAX, nls_codepage, remap);
6072 name_len++; /* trailing null */
6074 } else { /* BB improve the check for buffer overruns BB */
6075 name_len = strnlen(file_name, PATH_MAX);
6076 name_len++; /* trailing null */
6077 strncpy(pSMB->FileName, file_name, name_len);
6080 params = 6 + name_len;
6081 count = sizeof(FILE_UNIX_BASIC_INFO);
6082 pSMB->MaxParameterCount = cpu_to_le16(2);
6083 /* BB find max SMB PDU from sess structure BB */
6084 pSMB->MaxDataCount = cpu_to_le16(1000);
6085 pSMB->MaxSetupCount = 0;
6089 pSMB->Reserved2 = 0;
6090 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6091 InformationLevel) - 4;
6092 offset = param_offset + params;
6094 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
6096 memset(data_offset, 0, count);
6097 pSMB->DataOffset = cpu_to_le16(offset);
6098 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6099 pSMB->SetupCount = 1;
6100 pSMB->Reserved3 = 0;
6101 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6102 byte_count = 3 /* pad */ + params + count;
6103 pSMB->ParameterCount = cpu_to_le16(params);
6104 pSMB->DataCount = cpu_to_le16(count);
6105 pSMB->TotalParameterCount = pSMB->ParameterCount;
6106 pSMB->TotalDataCount = pSMB->DataCount;
6107 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6108 pSMB->Reserved4 = 0;
6109 inc_rfc1001_len(pSMB, byte_count);
6111 cifs_fill_unix_set_info(data_offset, args);
6113 pSMB->ByteCount = cpu_to_le16(byte_count);
6114 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6115 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6117 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6119 cifs_buf_release(pSMB);
6125 #ifdef CONFIG_CIFS_XATTR
6127 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6128 * function used by listxattr and getxattr type calls. When ea_name is set,
6129 * it looks for that attribute name and stuffs that value into the EAData
6130 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6131 * buffer. In both cases, the return value is either the length of the
6132 * resulting data or a negative error code. If EAData is a NULL pointer then
6133 * the data isn't copied to it, but the length is returned.
6136 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6137 const unsigned char *searchName, const unsigned char *ea_name,
6138 char *EAData, size_t buf_size,
6139 struct cifs_sb_info *cifs_sb)
6141 /* BB assumes one setup word */
6142 TRANSACTION2_QPI_REQ *pSMB = NULL;
6143 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6144 int remap = cifs_remap(cifs_sb);
6145 struct nls_table *nls_codepage = cifs_sb->local_nls;
6149 struct fealist *ea_response_data;
6150 struct fea *temp_fea;
6153 __u16 params, byte_count, data_offset;
6154 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6156 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6158 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6163 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6165 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6166 PATH_MAX, nls_codepage, remap);
6167 list_len++; /* trailing null */
6169 } else { /* BB improve the check for buffer overruns BB */
6170 list_len = strnlen(searchName, PATH_MAX);
6171 list_len++; /* trailing null */
6172 strncpy(pSMB->FileName, searchName, list_len);
6175 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6176 pSMB->TotalDataCount = 0;
6177 pSMB->MaxParameterCount = cpu_to_le16(2);
6178 /* BB find exact max SMB PDU from sess structure BB */
6179 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6180 pSMB->MaxSetupCount = 0;
6184 pSMB->Reserved2 = 0;
6185 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6186 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6187 pSMB->DataCount = 0;
6188 pSMB->DataOffset = 0;
6189 pSMB->SetupCount = 1;
6190 pSMB->Reserved3 = 0;
6191 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6192 byte_count = params + 1 /* pad */ ;
6193 pSMB->TotalParameterCount = cpu_to_le16(params);
6194 pSMB->ParameterCount = pSMB->TotalParameterCount;
6195 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6196 pSMB->Reserved4 = 0;
6197 inc_rfc1001_len(pSMB, byte_count);
6198 pSMB->ByteCount = cpu_to_le16(byte_count);
6200 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6201 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6203 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6208 /* BB also check enough total bytes returned */
6209 /* BB we need to improve the validity checking
6210 of these trans2 responses */
6212 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6213 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6214 rc = -EIO; /* bad smb */
6218 /* check that length of list is not more than bcc */
6219 /* check that each entry does not go beyond length
6221 /* check that each element of each entry does not
6222 go beyond end of list */
6223 /* validate_trans2_offsets() */
6224 /* BB check if start of smb + data_offset > &bcc+ bcc */
6226 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6227 ea_response_data = (struct fealist *)
6228 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6230 list_len = le32_to_cpu(ea_response_data->list_len);
6231 cifs_dbg(FYI, "ea length %d\n", list_len);
6232 if (list_len <= 8) {
6233 cifs_dbg(FYI, "empty EA list returned from server\n");
6234 /* didn't find the named attribute */
6240 /* make sure list_len doesn't go past end of SMB */
6241 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6242 if ((char *)ea_response_data + list_len > end_of_smb) {
6243 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6248 /* account for ea list len */
6250 temp_fea = ea_response_data->list;
6251 temp_ptr = (char *)temp_fea;
6252 while (list_len > 0) {
6253 unsigned int name_len;
6258 /* make sure we can read name_len and value_len */
6260 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6265 name_len = temp_fea->name_len;
6266 value_len = le16_to_cpu(temp_fea->value_len);
6267 list_len -= name_len + 1 + value_len;
6269 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6275 if (ea_name_len == name_len &&
6276 memcmp(ea_name, temp_ptr, name_len) == 0) {
6277 temp_ptr += name_len + 1;
6281 if ((size_t)value_len > buf_size) {
6285 memcpy(EAData, temp_ptr, value_len);
6289 /* account for prefix user. and trailing null */
6290 rc += (5 + 1 + name_len);
6291 if (rc < (int) buf_size) {
6292 memcpy(EAData, "user.", 5);
6294 memcpy(EAData, temp_ptr, name_len);
6296 /* null terminate name */
6299 } else if (buf_size == 0) {
6300 /* skip copy - calc size only */
6302 /* stop before overrun buffer */
6307 temp_ptr += name_len + 1 + value_len;
6308 temp_fea = (struct fea *)temp_ptr;
6311 /* didn't find the named attribute */
6316 cifs_buf_release(pSMB);
6324 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6325 const char *fileName, const char *ea_name, const void *ea_value,
6326 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6327 struct cifs_sb_info *cifs_sb)
6329 struct smb_com_transaction2_spi_req *pSMB = NULL;
6330 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6331 struct fealist *parm_data;
6334 int bytes_returned = 0;
6335 __u16 params, param_offset, byte_count, offset, count;
6336 int remap = cifs_remap(cifs_sb);
6338 cifs_dbg(FYI, "In SetEA\n");
6340 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6345 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6347 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6348 PATH_MAX, nls_codepage, remap);
6349 name_len++; /* trailing null */
6351 } else { /* BB improve the check for buffer overruns BB */
6352 name_len = strnlen(fileName, PATH_MAX);
6353 name_len++; /* trailing null */
6354 strncpy(pSMB->FileName, fileName, name_len);
6357 params = 6 + name_len;
6359 /* done calculating parms using name_len of file name,
6360 now use name_len to calculate length of ea name
6361 we are going to create in the inode xattrs */
6362 if (ea_name == NULL)
6365 name_len = strnlen(ea_name, 255);
6367 count = sizeof(*parm_data) + ea_value_len + name_len;
6368 pSMB->MaxParameterCount = cpu_to_le16(2);
6369 /* BB find max SMB PDU from sess */
6370 pSMB->MaxDataCount = cpu_to_le16(1000);
6371 pSMB->MaxSetupCount = 0;
6375 pSMB->Reserved2 = 0;
6376 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6377 InformationLevel) - 4;
6378 offset = param_offset + params;
6379 pSMB->InformationLevel =
6380 cpu_to_le16(SMB_SET_FILE_EA);
6382 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6383 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6384 pSMB->DataOffset = cpu_to_le16(offset);
6385 pSMB->SetupCount = 1;
6386 pSMB->Reserved3 = 0;
6387 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6388 byte_count = 3 /* pad */ + params + count;
6389 pSMB->DataCount = cpu_to_le16(count);
6390 parm_data->list_len = cpu_to_le32(count);
6391 parm_data->list[0].EA_flags = 0;
6392 /* we checked above that name len is less than 255 */
6393 parm_data->list[0].name_len = (__u8)name_len;
6394 /* EA names are always ASCII */
6396 strncpy(parm_data->list[0].name, ea_name, name_len);
6397 parm_data->list[0].name[name_len] = 0;
6398 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6399 /* caller ensures that ea_value_len is less than 64K but
6400 we need to ensure that it fits within the smb */
6402 /*BB add length check to see if it would fit in
6403 negotiated SMB buffer size BB */
6404 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6406 memcpy(parm_data->list[0].name+name_len+1,
6407 ea_value, ea_value_len);
6409 pSMB->TotalDataCount = pSMB->DataCount;
6410 pSMB->ParameterCount = cpu_to_le16(params);
6411 pSMB->TotalParameterCount = pSMB->ParameterCount;
6412 pSMB->Reserved4 = 0;
6413 inc_rfc1001_len(pSMB, byte_count);
6414 pSMB->ByteCount = cpu_to_le16(byte_count);
6415 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6416 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6418 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6420 cifs_buf_release(pSMB);
6429 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6431 * Years ago the kernel added a "dnotify" function for Samba server,
6432 * to allow network clients (such as Windows) to display updated
6433 * lists of files in directory listings automatically when
6434 * files are added by one user when another user has the
6435 * same directory open on their desktop. The Linux cifs kernel
6436 * client hooked into the kernel side of this interface for
6437 * the same reason, but ironically when the VFS moved from
6438 * "dnotify" to "inotify" it became harder to plug in Linux
6439 * network file system clients (the most obvious use case
6440 * for notify interfaces is when multiple users can update
6441 * the contents of the same directory - exactly what network
6442 * file systems can do) although the server (Samba) could
6443 * still use it. For the short term we leave the worker
6444 * function ifdeffed out (below) until inotify is fixed
6445 * in the VFS to make it easier to plug in network file
6446 * system clients. If inotify turns out to be permanently
6447 * incompatible for network fs clients, we could instead simply
6448 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6450 int CIFSSMBNotify(const unsigned int xid, struct cifs_tcon *tcon,
6451 const int notify_subdirs, const __u16 netfid,
6452 __u32 filter, struct file *pfile, int multishot,
6453 const struct nls_table *nls_codepage)
6456 struct smb_com_transaction_change_notify_req *pSMB = NULL;
6457 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6458 struct dir_notify_req *dnotify_req;
6461 cifs_dbg(FYI, "In CIFSSMBNotify for file handle %d\n", (int)netfid);
6462 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6467 pSMB->TotalParameterCount = 0 ;
6468 pSMB->TotalDataCount = 0;
6469 pSMB->MaxParameterCount = cpu_to_le32(2);
6470 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6471 pSMB->MaxSetupCount = 4;
6473 pSMB->ParameterOffset = 0;
6474 pSMB->DataCount = 0;
6475 pSMB->DataOffset = 0;
6476 pSMB->SetupCount = 4; /* single byte does not need le conversion */
6477 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6478 pSMB->ParameterCount = pSMB->TotalParameterCount;
6480 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6481 pSMB->Reserved2 = 0;
6482 pSMB->CompletionFilter = cpu_to_le32(filter);
6483 pSMB->Fid = netfid; /* file handle always le */
6484 pSMB->ByteCount = 0;
6486 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6487 (struct smb_hdr *)pSMBr, &bytes_returned,
6490 cifs_dbg(FYI, "Error in Notify = %d\n", rc);
6492 /* Add file to outstanding requests */
6493 /* BB change to kmem cache alloc */
6494 dnotify_req = kmalloc(
6495 sizeof(struct dir_notify_req),
6498 dnotify_req->Pid = pSMB->hdr.Pid;
6499 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6500 dnotify_req->Mid = pSMB->hdr.Mid;
6501 dnotify_req->Tid = pSMB->hdr.Tid;
6502 dnotify_req->Uid = pSMB->hdr.Uid;
6503 dnotify_req->netfid = netfid;
6504 dnotify_req->pfile = pfile;
6505 dnotify_req->filter = filter;
6506 dnotify_req->multishot = multishot;
6507 spin_lock(&GlobalMid_Lock);
6508 list_add_tail(&dnotify_req->lhead,
6509 &GlobalDnotifyReqList);
6510 spin_unlock(&GlobalMid_Lock);
6514 cifs_buf_release(pSMB);
6517 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */