4 * Copyright (C) International Business Machines Corp., 2002,2010
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Contains the routines for constructing the SMB PDUs themselves
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
25 /* These are mostly routines that operate on a pathname, or on a tree id */
26 /* (mounted volume), but there are eight handle based routines which must be */
27 /* treated slightly differently for reconnection purposes since we never */
28 /* want to reuse a stale file handle and only the caller knows the file info */
31 #include <linux/kernel.h>
32 #include <linux/vfs.h>
33 #include <linux/slab.h>
34 #include <linux/posix_acl_xattr.h>
35 #include <linux/pagemap.h>
36 #include <linux/swap.h>
37 #include <linux/task_io_accounting_ops.h>
38 #include <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 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
115 /* reconnect the socket, tcon, and smb session if needed */
117 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
120 struct cifs_ses *ses;
121 struct TCP_Server_Info *server;
122 struct nls_table *nls_codepage;
125 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
126 * tcp and smb session status done differently for those three - in the
133 server = ses->server;
136 * only tree disconnect, open, and write, (and ulogoff which does not
137 * have tcon) are allowed as we start force umount
139 if (tcon->tidStatus == CifsExiting) {
140 if (smb_command != SMB_COM_WRITE_ANDX &&
141 smb_command != SMB_COM_OPEN_ANDX &&
142 smb_command != SMB_COM_TREE_DISCONNECT) {
143 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
150 * Give demultiplex thread up to 10 seconds to reconnect, should be
151 * greater than cifs socket timeout which is 7 seconds
153 while (server->tcpStatus == CifsNeedReconnect) {
154 wait_event_interruptible_timeout(server->response_q,
155 (server->tcpStatus != CifsNeedReconnect), 10 * HZ);
157 /* are we still trying to reconnect? */
158 if (server->tcpStatus != CifsNeedReconnect)
162 * on "soft" mounts we wait once. Hard mounts keep
163 * retrying until process is killed or server comes
167 cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
172 if (!ses->need_reconnect && !tcon->need_reconnect)
175 nls_codepage = load_nls_default();
178 * need to prevent multiple threads trying to simultaneously
179 * reconnect the same SMB session
181 mutex_lock(&ses->session_mutex);
184 * Recheck after acquire mutex. If another thread is negotiating
185 * and the server never sends an answer the socket will be closed
186 * and tcpStatus set to reconnect.
188 if (server->tcpStatus == CifsNeedReconnect) {
190 mutex_unlock(&ses->session_mutex);
194 rc = cifs_negotiate_protocol(0, ses);
195 if (rc == 0 && ses->need_reconnect)
196 rc = cifs_setup_session(0, ses, nls_codepage);
198 /* do we need to reconnect tcon? */
199 if (rc || !tcon->need_reconnect) {
200 mutex_unlock(&ses->session_mutex);
204 cifs_mark_open_files_invalid(tcon);
205 rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage);
206 mutex_unlock(&ses->session_mutex);
207 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
210 printk_once(KERN_WARNING "reconnect tcon failed rc = %d\n", rc);
214 atomic_inc(&tconInfoReconnectCount);
216 /* tell server Unix caps we support */
217 if (ses->capabilities & CAP_UNIX)
218 reset_cifs_unix_caps(0, tcon, NULL, NULL);
221 * Removed call to reopen open files here. It is safer (and faster) to
222 * reopen files one at a time as needed in read and write.
224 * FIXME: what about file locks? don't we need to reclaim them ASAP?
229 * Check if handle based operation so we know whether we can continue
230 * or not without returning to caller to reset file handle
232 switch (smb_command) {
233 case SMB_COM_READ_ANDX:
234 case SMB_COM_WRITE_ANDX:
236 case SMB_COM_FIND_CLOSE2:
237 case SMB_COM_LOCKING_ANDX:
241 unload_nls(nls_codepage);
245 /* Allocate and return pointer to an SMB request buffer, and set basic
246 SMB information in the SMB header. If the return code is zero, this
247 function must have filled in request_buf pointer */
249 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
254 rc = cifs_reconnect_tcon(tcon, smb_command);
258 *request_buf = cifs_small_buf_get();
259 if (*request_buf == NULL) {
260 /* BB should we add a retry in here if not a writepage? */
264 header_assemble((struct smb_hdr *) *request_buf, smb_command,
268 cifs_stats_inc(&tcon->num_smbs_sent);
274 small_smb_init_no_tc(const int smb_command, const int wct,
275 struct cifs_ses *ses, void **request_buf)
278 struct smb_hdr *buffer;
280 rc = small_smb_init(smb_command, wct, NULL, request_buf);
284 buffer = (struct smb_hdr *)*request_buf;
285 buffer->Mid = get_next_mid(ses->server);
286 if (ses->capabilities & CAP_UNICODE)
287 buffer->Flags2 |= SMBFLG2_UNICODE;
288 if (ses->capabilities & CAP_STATUS32)
289 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
291 /* uid, tid can stay at zero as set in header assemble */
293 /* BB add support for turning on the signing when
294 this function is used after 1st of session setup requests */
299 /* If the return code is zero, this function must fill in request_buf pointer */
301 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
302 void **request_buf, void **response_buf)
304 *request_buf = cifs_buf_get();
305 if (*request_buf == NULL) {
306 /* BB should we add a retry in here if not a writepage? */
309 /* Although the original thought was we needed the response buf for */
310 /* potential retries of smb operations it turns out we can determine */
311 /* from the mid flags when the request buffer can be resent without */
312 /* having to use a second distinct buffer for the response */
314 *response_buf = *request_buf;
316 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
320 cifs_stats_inc(&tcon->num_smbs_sent);
325 /* If the return code is zero, this function must fill in request_buf pointer */
327 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
328 void **request_buf, void **response_buf)
332 rc = cifs_reconnect_tcon(tcon, smb_command);
336 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
340 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
341 void **request_buf, void **response_buf)
343 if (tcon->ses->need_reconnect || tcon->need_reconnect)
346 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
349 static int validate_t2(struct smb_t2_rsp *pSMB)
351 unsigned int total_size;
353 /* check for plausible wct */
354 if (pSMB->hdr.WordCount < 10)
357 /* check for parm and data offset going beyond end of smb */
358 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
359 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
362 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
363 if (total_size >= 512)
366 /* check that bcc is at least as big as parms + data, and that it is
367 * less than negotiated smb buffer
369 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
370 if (total_size > get_bcc(&pSMB->hdr) ||
371 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
376 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
377 sizeof(struct smb_t2_rsp) + 16);
382 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
386 char *guid = pSMBr->u.extended_response.GUID;
387 struct TCP_Server_Info *server = ses->server;
389 count = get_bcc(&pSMBr->hdr);
390 if (count < SMB1_CLIENT_GUID_SIZE)
393 spin_lock(&cifs_tcp_ses_lock);
394 if (server->srv_count > 1) {
395 spin_unlock(&cifs_tcp_ses_lock);
396 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
397 cifs_dbg(FYI, "server UID changed\n");
398 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
401 spin_unlock(&cifs_tcp_ses_lock);
402 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
405 if (count == SMB1_CLIENT_GUID_SIZE) {
406 server->sec_ntlmssp = true;
408 count -= SMB1_CLIENT_GUID_SIZE;
409 rc = decode_negTokenInit(
410 pSMBr->u.extended_response.SecurityBlob, count, server);
419 cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
421 bool srv_sign_required = server->sec_mode & server->vals->signing_required;
422 bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
423 bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
426 * Is signing required by mnt options? If not then check
427 * global_secflags to see if it is there.
429 if (!mnt_sign_required)
430 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
434 * If signing is required then it's automatically enabled too,
435 * otherwise, check to see if the secflags allow it.
437 mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
438 (global_secflags & CIFSSEC_MAY_SIGN);
440 /* If server requires signing, does client allow it? */
441 if (srv_sign_required) {
442 if (!mnt_sign_enabled) {
443 cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!");
449 /* If client requires signing, does server allow it? */
450 if (mnt_sign_required) {
451 if (!srv_sign_enabled) {
452 cifs_dbg(VFS, "Server does not support signing!");
458 if (cifs_rdma_enabled(server) && server->sign)
459 cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled");
464 #ifdef CONFIG_CIFS_WEAK_PW_HASH
466 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
469 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
471 if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT)
474 server->sec_mode = le16_to_cpu(rsp->SecurityMode);
475 server->maxReq = min_t(unsigned int,
476 le16_to_cpu(rsp->MaxMpxCount),
478 set_credits(server, server->maxReq);
479 server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
480 /* even though we do not use raw we might as well set this
481 accurately, in case we ever find a need for it */
482 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
483 server->max_rw = 0xFF00;
484 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
486 server->max_rw = 0;/* do not need to use raw anyway */
487 server->capabilities = CAP_MPX_MODE;
489 tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
491 /* OS/2 often does not set timezone therefore
492 * we must use server time to calc time zone.
493 * Could deviate slightly from the right zone.
494 * Smallest defined timezone difference is 15 minutes
495 * (i.e. Nepal). Rounding up/down is done to match
498 int val, seconds, remain, result;
500 unsigned long utc = ktime_get_real_seconds();
501 ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
502 rsp->SrvTime.Time, 0);
503 cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
504 (int)ts.tv_sec, (int)utc,
505 (int)(utc - ts.tv_sec));
506 val = (int)(utc - ts.tv_sec);
508 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
509 remain = seconds % MIN_TZ_ADJ;
510 if (remain >= (MIN_TZ_ADJ / 2))
511 result += MIN_TZ_ADJ;
514 server->timeAdj = result;
516 server->timeAdj = (int)tmp;
517 server->timeAdj *= 60; /* also in seconds */
519 cifs_dbg(FYI, "server->timeAdj: %d seconds\n", server->timeAdj);
522 /* BB get server time for time conversions and add
523 code to use it and timezone since this is not UTC */
525 if (rsp->EncryptionKeyLength ==
526 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
527 memcpy(server->cryptkey, rsp->EncryptionKey,
528 CIFS_CRYPTO_KEY_SIZE);
529 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
530 return -EIO; /* need cryptkey unless plain text */
533 cifs_dbg(FYI, "LANMAN negotiated\n");
538 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
540 cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
546 should_set_ext_sec_flag(enum securityEnum sectype)
553 if (global_secflags &
554 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
563 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
566 NEGOTIATE_RSP *pSMBr;
570 struct TCP_Server_Info *server = ses->server;
574 WARN(1, "%s: server is NULL!\n", __func__);
578 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
579 (void **) &pSMB, (void **) &pSMBr);
583 pSMB->hdr.Mid = get_next_mid(server);
584 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
586 if (should_set_ext_sec_flag(ses->sectype)) {
587 cifs_dbg(FYI, "Requesting extended security.");
588 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
592 for (i = 0; i < CIFS_NUM_PROT; i++) {
593 strncpy(pSMB->DialectsArray+count, protocols[i].name, 16);
594 count += strlen(protocols[i].name) + 1;
595 /* null at end of source and target buffers anyway */
597 inc_rfc1001_len(pSMB, count);
598 pSMB->ByteCount = cpu_to_le16(count);
600 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
601 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
605 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
606 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
607 /* Check wct = 1 error case */
608 if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
609 /* core returns wct = 1, but we do not ask for core - otherwise
610 small wct just comes when dialect index is -1 indicating we
611 could not negotiate a common dialect */
614 } else if (pSMBr->hdr.WordCount == 13) {
615 server->negflavor = CIFS_NEGFLAVOR_LANMAN;
616 rc = decode_lanman_negprot_rsp(server, pSMBr);
618 } else if (pSMBr->hdr.WordCount != 17) {
623 /* else wct == 17, NTLM or better */
625 server->sec_mode = pSMBr->SecurityMode;
626 if ((server->sec_mode & SECMODE_USER) == 0)
627 cifs_dbg(FYI, "share mode security\n");
629 /* one byte, so no need to convert this or EncryptionKeyLen from
631 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
633 set_credits(server, server->maxReq);
634 /* probably no need to store and check maxvcs */
635 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
636 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
637 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
638 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
639 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
640 server->timeAdj *= 60;
642 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
643 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
644 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
645 CIFS_CRYPTO_KEY_SIZE);
646 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
647 server->capabilities & CAP_EXTENDED_SECURITY) {
648 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
649 rc = decode_ext_sec_blob(ses, pSMBr);
650 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
651 rc = -EIO; /* no crypt key only if plain text pwd */
653 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
654 server->capabilities &= ~CAP_EXTENDED_SECURITY;
659 rc = cifs_enable_signing(server, ses->sign);
661 cifs_buf_release(pSMB);
663 cifs_dbg(FYI, "negprot rc %d\n", rc);
668 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
670 struct smb_hdr *smb_buffer;
673 cifs_dbg(FYI, "In tree disconnect\n");
675 /* BB: do we need to check this? These should never be NULL. */
676 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
680 * No need to return error on this operation if tid invalidated and
681 * closed on server already e.g. due to tcp session crashing. Also,
682 * the tcon is no longer on the list, so no need to take lock before
685 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
688 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
689 (void **)&smb_buffer);
693 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
694 cifs_small_buf_release(smb_buffer);
696 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
698 /* No need to return error on this operation if tid invalidated and
699 closed on server already e.g. due to tcp session crashing */
707 * This is a no-op for now. We're not really interested in the reply, but
708 * rather in the fact that the server sent one and that server->lstrp
711 * FIXME: maybe we should consider checking that the reply matches request?
714 cifs_echo_callback(struct mid_q_entry *mid)
716 struct TCP_Server_Info *server = mid->callback_data;
718 DeleteMidQEntry(mid);
719 add_credits(server, 1, CIFS_ECHO_OP);
723 CIFSSMBEcho(struct TCP_Server_Info *server)
728 struct smb_rqst rqst = { .rq_iov = iov,
731 cifs_dbg(FYI, "In echo request\n");
733 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
737 if (server->capabilities & CAP_UNICODE)
738 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
740 /* set up echo request */
741 smb->hdr.Tid = 0xffff;
742 smb->hdr.WordCount = 1;
743 put_unaligned_le16(1, &smb->EchoCount);
744 put_bcc(1, &smb->hdr);
746 inc_rfc1001_len(smb, 3);
749 iov[0].iov_base = smb;
750 iov[1].iov_len = get_rfc1002_length(smb);
751 iov[1].iov_base = (char *)smb + 4;
753 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
754 server, CIFS_ASYNC_OP | CIFS_ECHO_OP);
756 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
758 cifs_small_buf_release(smb);
764 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
766 LOGOFF_ANDX_REQ *pSMB;
769 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
772 * BB: do we need to check validity of ses and server? They should
773 * always be valid since we have an active reference. If not, that
774 * should probably be a BUG()
776 if (!ses || !ses->server)
779 mutex_lock(&ses->session_mutex);
780 if (ses->need_reconnect)
781 goto session_already_dead; /* no need to send SMBlogoff if uid
782 already closed due to reconnect */
783 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
785 mutex_unlock(&ses->session_mutex);
789 pSMB->hdr.Mid = get_next_mid(ses->server);
791 if (ses->server->sign)
792 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
794 pSMB->hdr.Uid = ses->Suid;
796 pSMB->AndXCommand = 0xFF;
797 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
798 cifs_small_buf_release(pSMB);
799 session_already_dead:
800 mutex_unlock(&ses->session_mutex);
802 /* if session dead then we do not need to do ulogoff,
803 since server closed smb session, no sense reporting
811 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
812 const char *fileName, __u16 type,
813 const struct nls_table *nls_codepage, int remap)
815 TRANSACTION2_SPI_REQ *pSMB = NULL;
816 TRANSACTION2_SPI_RSP *pSMBr = NULL;
817 struct unlink_psx_rq *pRqD;
820 int bytes_returned = 0;
821 __u16 params, param_offset, offset, byte_count;
823 cifs_dbg(FYI, "In POSIX delete\n");
825 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
830 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
832 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
833 PATH_MAX, nls_codepage, remap);
834 name_len++; /* trailing null */
836 } else { /* BB add path length overrun check */
837 name_len = strnlen(fileName, PATH_MAX);
838 name_len++; /* trailing null */
839 strncpy(pSMB->FileName, fileName, name_len);
842 params = 6 + name_len;
843 pSMB->MaxParameterCount = cpu_to_le16(2);
844 pSMB->MaxDataCount = 0; /* BB double check this with jra */
845 pSMB->MaxSetupCount = 0;
850 param_offset = offsetof(struct smb_com_transaction2_spi_req,
851 InformationLevel) - 4;
852 offset = param_offset + params;
854 /* Setup pointer to Request Data (inode type) */
855 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
856 pRqD->type = cpu_to_le16(type);
857 pSMB->ParameterOffset = cpu_to_le16(param_offset);
858 pSMB->DataOffset = cpu_to_le16(offset);
859 pSMB->SetupCount = 1;
861 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
862 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
864 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
865 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
866 pSMB->ParameterCount = cpu_to_le16(params);
867 pSMB->TotalParameterCount = pSMB->ParameterCount;
868 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
870 inc_rfc1001_len(pSMB, byte_count);
871 pSMB->ByteCount = cpu_to_le16(byte_count);
872 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
873 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
875 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
876 cifs_buf_release(pSMB);
878 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
887 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
888 struct cifs_sb_info *cifs_sb)
890 DELETE_FILE_REQ *pSMB = NULL;
891 DELETE_FILE_RSP *pSMBr = NULL;
895 int remap = cifs_remap(cifs_sb);
898 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
903 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
904 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
905 PATH_MAX, cifs_sb->local_nls,
907 name_len++; /* trailing null */
909 } else { /* BB improve check for buffer overruns BB */
910 name_len = strnlen(name, PATH_MAX);
911 name_len++; /* trailing null */
912 strncpy(pSMB->fileName, name, name_len);
914 pSMB->SearchAttributes =
915 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
916 pSMB->BufferFormat = 0x04;
917 inc_rfc1001_len(pSMB, name_len + 1);
918 pSMB->ByteCount = cpu_to_le16(name_len + 1);
919 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
920 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
921 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
923 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
925 cifs_buf_release(pSMB);
933 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
934 struct cifs_sb_info *cifs_sb)
936 DELETE_DIRECTORY_REQ *pSMB = NULL;
937 DELETE_DIRECTORY_RSP *pSMBr = NULL;
941 int remap = cifs_remap(cifs_sb);
943 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
945 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
950 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
951 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
952 PATH_MAX, cifs_sb->local_nls,
954 name_len++; /* trailing null */
956 } else { /* BB improve check for buffer overruns BB */
957 name_len = strnlen(name, PATH_MAX);
958 name_len++; /* trailing null */
959 strncpy(pSMB->DirName, name, name_len);
962 pSMB->BufferFormat = 0x04;
963 inc_rfc1001_len(pSMB, name_len + 1);
964 pSMB->ByteCount = cpu_to_le16(name_len + 1);
965 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
966 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
967 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
969 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
971 cifs_buf_release(pSMB);
978 CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
979 struct cifs_sb_info *cifs_sb)
982 CREATE_DIRECTORY_REQ *pSMB = NULL;
983 CREATE_DIRECTORY_RSP *pSMBr = NULL;
986 int remap = cifs_remap(cifs_sb);
988 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
990 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
995 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
996 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
997 PATH_MAX, cifs_sb->local_nls,
999 name_len++; /* trailing null */
1001 } else { /* BB improve check for buffer overruns BB */
1002 name_len = strnlen(name, PATH_MAX);
1003 name_len++; /* trailing null */
1004 strncpy(pSMB->DirName, name, name_len);
1007 pSMB->BufferFormat = 0x04;
1008 inc_rfc1001_len(pSMB, name_len + 1);
1009 pSMB->ByteCount = cpu_to_le16(name_len + 1);
1010 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1011 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1012 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1014 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
1016 cifs_buf_release(pSMB);
1023 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1024 __u32 posix_flags, __u64 mode, __u16 *netfid,
1025 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1026 const char *name, const struct nls_table *nls_codepage,
1029 TRANSACTION2_SPI_REQ *pSMB = NULL;
1030 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1033 int bytes_returned = 0;
1034 __u16 params, param_offset, offset, byte_count, count;
1035 OPEN_PSX_REQ *pdata;
1036 OPEN_PSX_RSP *psx_rsp;
1038 cifs_dbg(FYI, "In POSIX Create\n");
1040 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1045 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1047 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1048 PATH_MAX, nls_codepage, remap);
1049 name_len++; /* trailing null */
1051 } else { /* BB improve the check for buffer overruns BB */
1052 name_len = strnlen(name, PATH_MAX);
1053 name_len++; /* trailing null */
1054 strncpy(pSMB->FileName, name, name_len);
1057 params = 6 + name_len;
1058 count = sizeof(OPEN_PSX_REQ);
1059 pSMB->MaxParameterCount = cpu_to_le16(2);
1060 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1061 pSMB->MaxSetupCount = 0;
1065 pSMB->Reserved2 = 0;
1066 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1067 InformationLevel) - 4;
1068 offset = param_offset + params;
1069 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1070 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1071 pdata->Permissions = cpu_to_le64(mode);
1072 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1073 pdata->OpenFlags = cpu_to_le32(*pOplock);
1074 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1075 pSMB->DataOffset = cpu_to_le16(offset);
1076 pSMB->SetupCount = 1;
1077 pSMB->Reserved3 = 0;
1078 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1079 byte_count = 3 /* pad */ + params + count;
1081 pSMB->DataCount = cpu_to_le16(count);
1082 pSMB->ParameterCount = cpu_to_le16(params);
1083 pSMB->TotalDataCount = pSMB->DataCount;
1084 pSMB->TotalParameterCount = pSMB->ParameterCount;
1085 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1086 pSMB->Reserved4 = 0;
1087 inc_rfc1001_len(pSMB, byte_count);
1088 pSMB->ByteCount = cpu_to_le16(byte_count);
1089 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1090 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1092 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1093 goto psx_create_err;
1096 cifs_dbg(FYI, "copying inode info\n");
1097 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1099 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1100 rc = -EIO; /* bad smb */
1101 goto psx_create_err;
1104 /* copy return information to pRetData */
1105 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1106 + le16_to_cpu(pSMBr->t2.DataOffset));
1108 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1110 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1111 /* Let caller know file was created so we can set the mode. */
1112 /* Do we care about the CreateAction in any other cases? */
1113 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1114 *pOplock |= CIFS_CREATE_ACTION;
1115 /* check to make sure response data is there */
1116 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1117 pRetData->Type = cpu_to_le32(-1); /* unknown */
1118 cifs_dbg(NOISY, "unknown type\n");
1120 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1121 + sizeof(FILE_UNIX_BASIC_INFO)) {
1122 cifs_dbg(VFS, "Open response data too small\n");
1123 pRetData->Type = cpu_to_le32(-1);
1124 goto psx_create_err;
1126 memcpy((char *) pRetData,
1127 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1128 sizeof(FILE_UNIX_BASIC_INFO));
1132 cifs_buf_release(pSMB);
1134 if (posix_flags & SMB_O_DIRECTORY)
1135 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1137 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1145 static __u16 convert_disposition(int disposition)
1149 switch (disposition) {
1150 case FILE_SUPERSEDE:
1151 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1154 ofun = SMBOPEN_OAPPEND;
1157 ofun = SMBOPEN_OCREATE;
1160 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1162 case FILE_OVERWRITE:
1163 ofun = SMBOPEN_OTRUNC;
1165 case FILE_OVERWRITE_IF:
1166 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1169 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1170 ofun = SMBOPEN_OAPPEND; /* regular open */
1176 access_flags_to_smbopen_mode(const int access_flags)
1178 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1180 if (masked_flags == GENERIC_READ)
1181 return SMBOPEN_READ;
1182 else if (masked_flags == GENERIC_WRITE)
1183 return SMBOPEN_WRITE;
1185 /* just go for read/write */
1186 return SMBOPEN_READWRITE;
1190 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1191 const char *fileName, const int openDisposition,
1192 const int access_flags, const int create_options, __u16 *netfid,
1193 int *pOplock, FILE_ALL_INFO *pfile_info,
1194 const struct nls_table *nls_codepage, int remap)
1197 OPENX_REQ *pSMB = NULL;
1198 OPENX_RSP *pSMBr = NULL;
1204 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1209 pSMB->AndXCommand = 0xFF; /* none */
1211 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1212 count = 1; /* account for one byte pad to word boundary */
1214 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1215 fileName, PATH_MAX, nls_codepage, remap);
1216 name_len++; /* trailing null */
1218 } else { /* BB improve check for buffer overruns BB */
1219 count = 0; /* no pad */
1220 name_len = strnlen(fileName, PATH_MAX);
1221 name_len++; /* trailing null */
1222 strncpy(pSMB->fileName, fileName, name_len);
1224 if (*pOplock & REQ_OPLOCK)
1225 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1226 else if (*pOplock & REQ_BATCHOPLOCK)
1227 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1229 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1230 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1231 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1232 /* set file as system file if special file such
1233 as fifo and server expecting SFU style and
1234 no Unix extensions */
1236 if (create_options & CREATE_OPTION_SPECIAL)
1237 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1238 else /* BB FIXME BB */
1239 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1241 if (create_options & CREATE_OPTION_READONLY)
1242 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1245 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1246 CREATE_OPTIONS_MASK); */
1247 /* BB FIXME END BB */
1249 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1250 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1252 inc_rfc1001_len(pSMB, count);
1254 pSMB->ByteCount = cpu_to_le16(count);
1255 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1256 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1257 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1259 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1261 /* BB verify if wct == 15 */
1263 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1265 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1266 /* Let caller know file was created so we can set the mode. */
1267 /* Do we care about the CreateAction in any other cases? */
1269 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1270 *pOplock |= CIFS_CREATE_ACTION; */
1274 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1275 pfile_info->LastAccessTime = 0; /* BB fixme */
1276 pfile_info->LastWriteTime = 0; /* BB fixme */
1277 pfile_info->ChangeTime = 0; /* BB fixme */
1278 pfile_info->Attributes =
1279 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1280 /* the file_info buf is endian converted by caller */
1281 pfile_info->AllocationSize =
1282 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1283 pfile_info->EndOfFile = pfile_info->AllocationSize;
1284 pfile_info->NumberOfLinks = cpu_to_le32(1);
1285 pfile_info->DeletePending = 0;
1289 cifs_buf_release(pSMB);
1296 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1300 OPEN_REQ *req = NULL;
1301 OPEN_RSP *rsp = NULL;
1305 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1306 struct cifs_tcon *tcon = oparms->tcon;
1307 int remap = cifs_remap(cifs_sb);
1308 const struct nls_table *nls = cifs_sb->local_nls;
1309 int create_options = oparms->create_options;
1310 int desired_access = oparms->desired_access;
1311 int disposition = oparms->disposition;
1312 const char *path = oparms->path;
1315 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1320 /* no commands go after this */
1321 req->AndXCommand = 0xFF;
1323 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1324 /* account for one byte pad to word boundary */
1326 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1327 path, PATH_MAX, nls, remap);
1331 req->NameLength = cpu_to_le16(name_len);
1333 /* BB improve check for buffer overruns BB */
1336 name_len = strnlen(path, PATH_MAX);
1339 req->NameLength = cpu_to_le16(name_len);
1340 strncpy(req->fileName, path, name_len);
1343 if (*oplock & REQ_OPLOCK)
1344 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1345 else if (*oplock & REQ_BATCHOPLOCK)
1346 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1348 req->DesiredAccess = cpu_to_le32(desired_access);
1349 req->AllocationSize = 0;
1352 * Set file as system file if special file such as fifo and server
1353 * expecting SFU style and no Unix extensions.
1355 if (create_options & CREATE_OPTION_SPECIAL)
1356 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1358 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1361 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1362 * sensitive checks for other servers such as Samba.
1364 if (tcon->ses->capabilities & CAP_UNIX)
1365 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1367 if (create_options & CREATE_OPTION_READONLY)
1368 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1370 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1371 req->CreateDisposition = cpu_to_le32(disposition);
1372 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1374 /* BB Expirement with various impersonation levels and verify */
1375 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1376 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1379 inc_rfc1001_len(req, count);
1381 req->ByteCount = cpu_to_le16(count);
1382 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1383 (struct smb_hdr *)rsp, &bytes_returned, 0);
1384 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1386 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1387 cifs_buf_release(req);
1393 /* 1 byte no need to le_to_cpu */
1394 *oplock = rsp->OplockLevel;
1395 /* cifs fid stays in le */
1396 oparms->fid->netfid = rsp->Fid;
1398 /* Let caller know file was created so we can set the mode. */
1399 /* Do we care about the CreateAction in any other cases? */
1400 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1401 *oplock |= CIFS_CREATE_ACTION;
1404 /* copy from CreationTime to Attributes */
1405 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1406 /* the file_info buf is endian converted by caller */
1407 buf->AllocationSize = rsp->AllocationSize;
1408 buf->EndOfFile = rsp->EndOfFile;
1409 buf->NumberOfLinks = cpu_to_le32(1);
1410 buf->DeletePending = 0;
1413 cifs_buf_release(req);
1418 * Discard any remaining data in the current SMB. To do this, we borrow the
1422 cifs_discard_remaining_data(struct TCP_Server_Info *server)
1424 unsigned int rfclen = server->pdu_size;
1425 int remaining = rfclen + server->vals->header_preamble_size -
1428 while (remaining > 0) {
1431 length = cifs_read_from_socket(server, server->bigbuf,
1432 min_t(unsigned int, remaining,
1433 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1436 server->total_read += length;
1437 remaining -= length;
1444 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1447 struct cifs_readdata *rdata = mid->callback_data;
1449 length = cifs_discard_remaining_data(server);
1450 dequeue_mid(mid, rdata->result);
1451 mid->resp_buf = server->smallbuf;
1452 server->smallbuf = NULL;
1457 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1460 unsigned int data_offset, data_len;
1461 struct cifs_readdata *rdata = mid->callback_data;
1462 char *buf = server->smallbuf;
1463 unsigned int buflen = server->pdu_size +
1464 server->vals->header_preamble_size;
1465 bool use_rdma_mr = false;
1467 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1468 __func__, mid->mid, rdata->offset, rdata->bytes);
1471 * read the rest of READ_RSP header (sans Data array), or whatever we
1472 * can if there's not enough data. At this point, we've read down to
1475 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1476 HEADER_SIZE(server) + 1;
1478 length = cifs_read_from_socket(server,
1479 buf + HEADER_SIZE(server) - 1, len);
1482 server->total_read += length;
1484 if (server->ops->is_session_expired &&
1485 server->ops->is_session_expired(buf)) {
1486 cifs_reconnect(server);
1487 wake_up(&server->response_q);
1491 if (server->ops->is_status_pending &&
1492 server->ops->is_status_pending(buf, server, 0)) {
1493 cifs_discard_remaining_data(server);
1497 /* Was the SMB read successful? */
1498 rdata->result = server->ops->map_error(buf, false);
1499 if (rdata->result != 0) {
1500 cifs_dbg(FYI, "%s: server returned error %d\n",
1501 __func__, rdata->result);
1502 return cifs_readv_discard(server, mid);
1505 /* Is there enough to get to the rest of the READ_RSP header? */
1506 if (server->total_read < server->vals->read_rsp_size) {
1507 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1508 __func__, server->total_read,
1509 server->vals->read_rsp_size);
1510 rdata->result = -EIO;
1511 return cifs_readv_discard(server, mid);
1514 data_offset = server->ops->read_data_offset(buf) +
1515 server->vals->header_preamble_size;
1516 if (data_offset < server->total_read) {
1518 * win2k8 sometimes sends an offset of 0 when the read
1519 * is beyond the EOF. Treat it as if the data starts just after
1522 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1523 __func__, data_offset);
1524 data_offset = server->total_read;
1525 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1526 /* data_offset is beyond the end of smallbuf */
1527 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1528 __func__, data_offset);
1529 rdata->result = -EIO;
1530 return cifs_readv_discard(server, mid);
1533 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1534 __func__, server->total_read, data_offset);
1536 len = data_offset - server->total_read;
1538 /* read any junk before data into the rest of smallbuf */
1539 length = cifs_read_from_socket(server,
1540 buf + server->total_read, len);
1543 server->total_read += length;
1546 /* set up first iov for signature check */
1547 rdata->iov[0].iov_base = buf;
1548 rdata->iov[0].iov_len = 4;
1549 rdata->iov[1].iov_base = buf + 4;
1550 rdata->iov[1].iov_len = server->total_read - 4;
1551 cifs_dbg(FYI, "0: iov_base=%p iov_len=%u\n",
1552 rdata->iov[0].iov_base, server->total_read);
1554 /* how much data is in the response? */
1555 #ifdef CONFIG_CIFS_SMB_DIRECT
1556 use_rdma_mr = rdata->mr;
1558 data_len = server->ops->read_data_length(buf, use_rdma_mr);
1559 if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1560 /* data_len is corrupt -- discard frame */
1561 rdata->result = -EIO;
1562 return cifs_readv_discard(server, mid);
1565 length = rdata->read_into_pages(server, rdata, data_len);
1569 server->total_read += length;
1571 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1572 server->total_read, buflen, data_len);
1574 /* discard anything left over */
1575 if (server->total_read < buflen)
1576 return cifs_readv_discard(server, mid);
1578 dequeue_mid(mid, false);
1579 mid->resp_buf = server->smallbuf;
1580 server->smallbuf = NULL;
1585 cifs_readv_callback(struct mid_q_entry *mid)
1587 struct cifs_readdata *rdata = mid->callback_data;
1588 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1589 struct TCP_Server_Info *server = tcon->ses->server;
1590 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1592 .rq_pages = rdata->pages,
1593 .rq_npages = rdata->nr_pages,
1594 .rq_pagesz = rdata->pagesz,
1595 .rq_tailsz = rdata->tailsz };
1597 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1598 __func__, mid->mid, mid->mid_state, rdata->result,
1601 switch (mid->mid_state) {
1602 case MID_RESPONSE_RECEIVED:
1603 /* result already set, check signature */
1607 rc = cifs_verify_signature(&rqst, server,
1608 mid->sequence_number);
1610 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1613 /* FIXME: should this be counted toward the initiating task? */
1614 task_io_account_read(rdata->got_bytes);
1615 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1617 case MID_REQUEST_SUBMITTED:
1618 case MID_RETRY_NEEDED:
1619 rdata->result = -EAGAIN;
1620 if (server->sign && rdata->got_bytes)
1621 /* reset bytes number since we can not check a sign */
1622 rdata->got_bytes = 0;
1623 /* FIXME: should this be counted toward the initiating task? */
1624 task_io_account_read(rdata->got_bytes);
1625 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1628 rdata->result = -EIO;
1631 queue_work(cifsiod_wq, &rdata->work);
1632 DeleteMidQEntry(mid);
1633 add_credits(server, 1, 0);
1636 /* cifs_async_readv - send an async write, and set up mid to handle result */
1638 cifs_async_readv(struct cifs_readdata *rdata)
1641 READ_REQ *smb = NULL;
1643 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1644 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1647 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1648 __func__, rdata->offset, rdata->bytes);
1650 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1653 wct = 10; /* old style read */
1654 if ((rdata->offset >> 32) > 0) {
1655 /* can not handle this big offset for old */
1660 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1664 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1665 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1667 smb->AndXCommand = 0xFF; /* none */
1668 smb->Fid = rdata->cfile->fid.netfid;
1669 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1671 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1673 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1674 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1678 /* old style read */
1679 struct smb_com_readx_req *smbr =
1680 (struct smb_com_readx_req *)smb;
1681 smbr->ByteCount = 0;
1684 /* 4 for RFC1001 length + 1 for BCC */
1685 rdata->iov[0].iov_base = smb;
1686 rdata->iov[0].iov_len = 4;
1687 rdata->iov[1].iov_base = (char *)smb + 4;
1688 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1690 kref_get(&rdata->refcount);
1691 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1692 cifs_readv_callback, NULL, rdata, 0);
1695 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1697 kref_put(&rdata->refcount, cifs_readdata_release);
1699 cifs_small_buf_release(smb);
1704 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1705 unsigned int *nbytes, char **buf, int *pbuf_type)
1708 READ_REQ *pSMB = NULL;
1709 READ_RSP *pSMBr = NULL;
1710 char *pReadData = NULL;
1712 int resp_buf_type = 0;
1714 struct kvec rsp_iov;
1715 __u32 pid = io_parms->pid;
1716 __u16 netfid = io_parms->netfid;
1717 __u64 offset = io_parms->offset;
1718 struct cifs_tcon *tcon = io_parms->tcon;
1719 unsigned int count = io_parms->length;
1721 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1722 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1725 wct = 10; /* old style read */
1726 if ((offset >> 32) > 0) {
1727 /* can not handle this big offset for old */
1733 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1737 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1738 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1740 /* tcon and ses pointer are checked in smb_init */
1741 if (tcon->ses->server == NULL)
1742 return -ECONNABORTED;
1744 pSMB->AndXCommand = 0xFF; /* none */
1746 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1748 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1750 pSMB->Remaining = 0;
1751 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1752 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1754 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1756 /* old style read */
1757 struct smb_com_readx_req *pSMBW =
1758 (struct smb_com_readx_req *)pSMB;
1759 pSMBW->ByteCount = 0;
1762 iov[0].iov_base = (char *)pSMB;
1763 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1764 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1765 CIFS_LOG_ERROR, &rsp_iov);
1766 cifs_small_buf_release(pSMB);
1767 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1768 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1770 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1772 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1773 data_length = data_length << 16;
1774 data_length += le16_to_cpu(pSMBr->DataLength);
1775 *nbytes = data_length;
1777 /*check that DataLength would not go beyond end of SMB */
1778 if ((data_length > CIFSMaxBufSize)
1779 || (data_length > count)) {
1780 cifs_dbg(FYI, "bad length %d for count %d\n",
1781 data_length, count);
1785 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1786 le16_to_cpu(pSMBr->DataOffset);
1787 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1788 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1790 }*/ /* can not use copy_to_user when using page cache*/
1792 memcpy(*buf, pReadData, data_length);
1797 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1798 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1799 /* return buffer to caller to free */
1800 *buf = rsp_iov.iov_base;
1801 if (resp_buf_type == CIFS_SMALL_BUFFER)
1802 *pbuf_type = CIFS_SMALL_BUFFER;
1803 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1804 *pbuf_type = CIFS_LARGE_BUFFER;
1805 } /* else no valid buffer on return - leave as null */
1807 /* Note: On -EAGAIN error only caller can retry on handle based calls
1808 since file handle passed in no longer valid */
1814 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1815 unsigned int *nbytes, const char *buf)
1818 WRITE_REQ *pSMB = NULL;
1819 WRITE_RSP *pSMBr = NULL;
1820 int bytes_returned, wct;
1823 __u32 pid = io_parms->pid;
1824 __u16 netfid = io_parms->netfid;
1825 __u64 offset = io_parms->offset;
1826 struct cifs_tcon *tcon = io_parms->tcon;
1827 unsigned int count = io_parms->length;
1831 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1832 if (tcon->ses == NULL)
1833 return -ECONNABORTED;
1835 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1839 if ((offset >> 32) > 0) {
1840 /* can not handle big offset for old srv */
1845 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1850 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1851 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1853 /* tcon and ses pointer are checked in smb_init */
1854 if (tcon->ses->server == NULL)
1855 return -ECONNABORTED;
1857 pSMB->AndXCommand = 0xFF; /* none */
1859 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1861 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1863 pSMB->Reserved = 0xFFFFFFFF;
1864 pSMB->WriteMode = 0;
1865 pSMB->Remaining = 0;
1867 /* Can increase buffer size if buffer is big enough in some cases ie we
1868 can send more if LARGE_WRITE_X capability returned by the server and if
1869 our buffer is big enough or if we convert to iovecs on socket writes
1870 and eliminate the copy to the CIFS buffer */
1871 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1872 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1874 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1878 if (bytes_sent > count)
1881 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1883 memcpy(pSMB->Data, buf, bytes_sent);
1884 else if (count != 0) {
1886 cifs_buf_release(pSMB);
1888 } /* else setting file size with write of zero bytes */
1890 byte_count = bytes_sent + 1; /* pad */
1891 else /* wct == 12 */
1892 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1894 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1895 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1896 inc_rfc1001_len(pSMB, byte_count);
1899 pSMB->ByteCount = cpu_to_le16(byte_count);
1900 else { /* old style write has byte count 4 bytes earlier
1902 struct smb_com_writex_req *pSMBW =
1903 (struct smb_com_writex_req *)pSMB;
1904 pSMBW->ByteCount = cpu_to_le16(byte_count);
1907 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1908 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1909 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1911 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1913 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1914 *nbytes = (*nbytes) << 16;
1915 *nbytes += le16_to_cpu(pSMBr->Count);
1918 * Mask off high 16 bits when bytes written as returned by the
1919 * server is greater than bytes requested by the client. Some
1920 * OS/2 servers are known to set incorrect CountHigh values.
1922 if (*nbytes > count)
1926 cifs_buf_release(pSMB);
1928 /* Note: On -EAGAIN error only caller can retry on handle based calls
1929 since file handle passed in no longer valid */
1935 cifs_writedata_release(struct kref *refcount)
1937 struct cifs_writedata *wdata = container_of(refcount,
1938 struct cifs_writedata, refcount);
1939 #ifdef CONFIG_CIFS_SMB_DIRECT
1941 smbd_deregister_mr(wdata->mr);
1947 cifsFileInfo_put(wdata->cfile);
1953 * Write failed with a retryable error. Resend the write request. It's also
1954 * possible that the page was redirtied so re-clean the page.
1957 cifs_writev_requeue(struct cifs_writedata *wdata)
1960 struct inode *inode = d_inode(wdata->cfile->dentry);
1961 struct TCP_Server_Info *server;
1962 unsigned int rest_len;
1964 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1966 rest_len = wdata->bytes;
1968 struct cifs_writedata *wdata2;
1969 unsigned int j, nr_pages, wsize, tailsz, cur_len;
1971 wsize = server->ops->wp_retry_size(inode);
1972 if (wsize < rest_len) {
1973 nr_pages = wsize / PAGE_SIZE;
1978 cur_len = nr_pages * PAGE_SIZE;
1981 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
1983 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
1986 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
1992 for (j = 0; j < nr_pages; j++) {
1993 wdata2->pages[j] = wdata->pages[i + j];
1994 lock_page(wdata2->pages[j]);
1995 clear_page_dirty_for_io(wdata2->pages[j]);
1998 wdata2->sync_mode = wdata->sync_mode;
1999 wdata2->nr_pages = nr_pages;
2000 wdata2->offset = page_offset(wdata2->pages[0]);
2001 wdata2->pagesz = PAGE_SIZE;
2002 wdata2->tailsz = tailsz;
2003 wdata2->bytes = cur_len;
2005 wdata2->cfile = find_writable_file(CIFS_I(inode), false);
2006 if (!wdata2->cfile) {
2007 cifs_dbg(VFS, "No writable handles for inode\n");
2011 wdata2->pid = wdata2->cfile->pid;
2012 rc = server->ops->async_writev(wdata2, cifs_writedata_release);
2014 for (j = 0; j < nr_pages; j++) {
2015 unlock_page(wdata2->pages[j]);
2016 if (rc != 0 && rc != -EAGAIN) {
2017 SetPageError(wdata2->pages[j]);
2018 end_page_writeback(wdata2->pages[j]);
2019 put_page(wdata2->pages[j]);
2024 kref_put(&wdata2->refcount, cifs_writedata_release);
2030 rest_len -= cur_len;
2032 } while (i < wdata->nr_pages);
2034 mapping_set_error(inode->i_mapping, rc);
2035 kref_put(&wdata->refcount, cifs_writedata_release);
2039 cifs_writev_complete(struct work_struct *work)
2041 struct cifs_writedata *wdata = container_of(work,
2042 struct cifs_writedata, work);
2043 struct inode *inode = d_inode(wdata->cfile->dentry);
2046 if (wdata->result == 0) {
2047 spin_lock(&inode->i_lock);
2048 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2049 spin_unlock(&inode->i_lock);
2050 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2052 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2053 return cifs_writev_requeue(wdata);
2055 for (i = 0; i < wdata->nr_pages; i++) {
2056 struct page *page = wdata->pages[i];
2057 if (wdata->result == -EAGAIN)
2058 __set_page_dirty_nobuffers(page);
2059 else if (wdata->result < 0)
2061 end_page_writeback(page);
2064 if (wdata->result != -EAGAIN)
2065 mapping_set_error(inode->i_mapping, wdata->result);
2066 kref_put(&wdata->refcount, cifs_writedata_release);
2069 struct cifs_writedata *
2070 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2072 struct cifs_writedata *wdata;
2074 /* writedata + number of page pointers */
2075 wdata = kzalloc(sizeof(*wdata) +
2076 sizeof(struct page *) * nr_pages, GFP_NOFS);
2077 if (wdata != NULL) {
2078 kref_init(&wdata->refcount);
2079 INIT_LIST_HEAD(&wdata->list);
2080 init_completion(&wdata->done);
2081 INIT_WORK(&wdata->work, complete);
2087 * Check the mid_state and signature on received buffer (if any), and queue the
2088 * workqueue completion task.
2091 cifs_writev_callback(struct mid_q_entry *mid)
2093 struct cifs_writedata *wdata = mid->callback_data;
2094 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2095 unsigned int written;
2096 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2098 switch (mid->mid_state) {
2099 case MID_RESPONSE_RECEIVED:
2100 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2101 if (wdata->result != 0)
2104 written = le16_to_cpu(smb->CountHigh);
2106 written += le16_to_cpu(smb->Count);
2108 * Mask off high 16 bits when bytes written as returned
2109 * by the server is greater than bytes requested by the
2110 * client. OS/2 servers are known to set incorrect
2113 if (written > wdata->bytes)
2116 if (written < wdata->bytes)
2117 wdata->result = -ENOSPC;
2119 wdata->bytes = written;
2121 case MID_REQUEST_SUBMITTED:
2122 case MID_RETRY_NEEDED:
2123 wdata->result = -EAGAIN;
2126 wdata->result = -EIO;
2130 queue_work(cifsiod_wq, &wdata->work);
2131 DeleteMidQEntry(mid);
2132 add_credits(tcon->ses->server, 1, 0);
2135 /* cifs_async_writev - send an async write, and set up mid to handle result */
2137 cifs_async_writev(struct cifs_writedata *wdata,
2138 void (*release)(struct kref *kref))
2141 WRITE_REQ *smb = NULL;
2143 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2145 struct smb_rqst rqst = { };
2147 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2151 if (wdata->offset >> 32 > 0) {
2152 /* can not handle big offset for old srv */
2157 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2159 goto async_writev_out;
2161 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2162 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2164 smb->AndXCommand = 0xFF; /* none */
2165 smb->Fid = wdata->cfile->fid.netfid;
2166 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2168 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2169 smb->Reserved = 0xFFFFFFFF;
2174 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2176 /* 4 for RFC1001 length + 1 for BCC */
2178 iov[0].iov_base = smb;
2179 iov[1].iov_len = get_rfc1002_length(smb) + 1;
2180 iov[1].iov_base = (char *)smb + 4;
2184 rqst.rq_pages = wdata->pages;
2185 rqst.rq_npages = wdata->nr_pages;
2186 rqst.rq_pagesz = wdata->pagesz;
2187 rqst.rq_tailsz = wdata->tailsz;
2189 cifs_dbg(FYI, "async write at %llu %u bytes\n",
2190 wdata->offset, wdata->bytes);
2192 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2193 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2196 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2197 put_bcc(wdata->bytes + 1, &smb->hdr);
2200 struct smb_com_writex_req *smbw =
2201 (struct smb_com_writex_req *)smb;
2202 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2203 put_bcc(wdata->bytes + 5, &smbw->hdr);
2204 iov[1].iov_len += 4; /* pad bigger by four bytes */
2207 kref_get(&wdata->refcount);
2208 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2209 cifs_writev_callback, NULL, wdata, 0);
2212 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2214 kref_put(&wdata->refcount, release);
2217 cifs_small_buf_release(smb);
2222 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2223 unsigned int *nbytes, struct kvec *iov, int n_vec)
2226 WRITE_REQ *pSMB = NULL;
2229 int resp_buf_type = 0;
2230 __u32 pid = io_parms->pid;
2231 __u16 netfid = io_parms->netfid;
2232 __u64 offset = io_parms->offset;
2233 struct cifs_tcon *tcon = io_parms->tcon;
2234 unsigned int count = io_parms->length;
2235 struct kvec rsp_iov;
2239 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2241 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2245 if ((offset >> 32) > 0) {
2246 /* can not handle big offset for old srv */
2250 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2254 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2255 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2257 /* tcon and ses pointer are checked in smb_init */
2258 if (tcon->ses->server == NULL)
2259 return -ECONNABORTED;
2261 pSMB->AndXCommand = 0xFF; /* none */
2263 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2265 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2266 pSMB->Reserved = 0xFFFFFFFF;
2267 pSMB->WriteMode = 0;
2268 pSMB->Remaining = 0;
2271 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2273 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2274 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2275 /* header + 1 byte pad */
2276 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2278 inc_rfc1001_len(pSMB, count + 1);
2279 else /* wct == 12 */
2280 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2282 pSMB->ByteCount = cpu_to_le16(count + 1);
2283 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2284 struct smb_com_writex_req *pSMBW =
2285 (struct smb_com_writex_req *)pSMB;
2286 pSMBW->ByteCount = cpu_to_le16(count + 5);
2288 iov[0].iov_base = pSMB;
2290 iov[0].iov_len = smb_hdr_len + 4;
2291 else /* wct == 12 pad bigger by four bytes */
2292 iov[0].iov_len = smb_hdr_len + 8;
2294 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2296 cifs_small_buf_release(pSMB);
2297 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2299 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2300 } else if (resp_buf_type == 0) {
2301 /* presumably this can not happen, but best to be safe */
2304 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2305 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2306 *nbytes = (*nbytes) << 16;
2307 *nbytes += le16_to_cpu(pSMBr->Count);
2310 * Mask off high 16 bits when bytes written as returned by the
2311 * server is greater than bytes requested by the client. OS/2
2312 * servers are known to set incorrect CountHigh values.
2314 if (*nbytes > count)
2318 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2320 /* Note: On -EAGAIN error only caller can retry on handle based calls
2321 since file handle passed in no longer valid */
2326 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2327 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2328 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2331 LOCK_REQ *pSMB = NULL;
2333 struct kvec rsp_iov;
2337 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2338 num_lock, num_unlock);
2340 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2345 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2346 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2347 pSMB->LockType = lock_type;
2348 pSMB->AndXCommand = 0xFF; /* none */
2349 pSMB->Fid = netfid; /* netfid stays le */
2351 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2352 inc_rfc1001_len(pSMB, count);
2353 pSMB->ByteCount = cpu_to_le16(count);
2355 iov[0].iov_base = (char *)pSMB;
2356 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2357 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2358 iov[1].iov_base = (char *)buf;
2359 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2361 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2362 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP,
2364 cifs_small_buf_release(pSMB);
2366 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2372 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2373 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2374 const __u64 offset, const __u32 numUnlock,
2375 const __u32 numLock, const __u8 lockType,
2376 const bool waitFlag, const __u8 oplock_level)
2379 LOCK_REQ *pSMB = NULL;
2380 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2385 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2386 (int)waitFlag, numLock);
2387 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2392 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2393 /* no response expected */
2394 flags = CIFS_ASYNC_OP | CIFS_OBREAK_OP;
2396 } else if (waitFlag) {
2397 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2398 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2403 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2404 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2405 pSMB->LockType = lockType;
2406 pSMB->OplockLevel = oplock_level;
2407 pSMB->AndXCommand = 0xFF; /* none */
2408 pSMB->Fid = smb_file_id; /* netfid stays le */
2410 if ((numLock != 0) || (numUnlock != 0)) {
2411 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2412 /* BB where to store pid high? */
2413 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2414 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2415 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2416 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2417 count = sizeof(LOCKING_ANDX_RANGE);
2422 inc_rfc1001_len(pSMB, count);
2423 pSMB->ByteCount = cpu_to_le16(count);
2426 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2427 (struct smb_hdr *) pSMB, &bytes_returned);
2429 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2430 cifs_small_buf_release(pSMB);
2431 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2433 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2435 /* Note: On -EAGAIN error only caller can retry on handle based calls
2436 since file handle passed in no longer valid */
2441 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2442 const __u16 smb_file_id, const __u32 netpid,
2443 const loff_t start_offset, const __u64 len,
2444 struct file_lock *pLockData, const __u16 lock_type,
2445 const bool waitFlag)
2447 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2448 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2449 struct cifs_posix_lock *parm_data;
2452 int bytes_returned = 0;
2453 int resp_buf_type = 0;
2454 __u16 params, param_offset, offset, byte_count, count;
2456 struct kvec rsp_iov;
2458 cifs_dbg(FYI, "Posix Lock\n");
2460 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2465 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2468 pSMB->MaxSetupCount = 0;
2471 pSMB->Reserved2 = 0;
2472 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2473 offset = param_offset + params;
2475 count = sizeof(struct cifs_posix_lock);
2476 pSMB->MaxParameterCount = cpu_to_le16(2);
2477 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2478 pSMB->SetupCount = 1;
2479 pSMB->Reserved3 = 0;
2481 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2483 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2484 byte_count = 3 /* pad */ + params + count;
2485 pSMB->DataCount = cpu_to_le16(count);
2486 pSMB->ParameterCount = cpu_to_le16(params);
2487 pSMB->TotalDataCount = pSMB->DataCount;
2488 pSMB->TotalParameterCount = pSMB->ParameterCount;
2489 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2490 parm_data = (struct cifs_posix_lock *)
2491 (((char *) &pSMB->hdr.Protocol) + offset);
2493 parm_data->lock_type = cpu_to_le16(lock_type);
2495 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2496 parm_data->lock_flags = cpu_to_le16(1);
2497 pSMB->Timeout = cpu_to_le32(-1);
2501 parm_data->pid = cpu_to_le32(netpid);
2502 parm_data->start = cpu_to_le64(start_offset);
2503 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2505 pSMB->DataOffset = cpu_to_le16(offset);
2506 pSMB->Fid = smb_file_id;
2507 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2508 pSMB->Reserved4 = 0;
2509 inc_rfc1001_len(pSMB, byte_count);
2510 pSMB->ByteCount = cpu_to_le16(byte_count);
2512 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2513 (struct smb_hdr *) pSMBr, &bytes_returned);
2515 iov[0].iov_base = (char *)pSMB;
2516 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2517 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2518 &resp_buf_type, timeout, &rsp_iov);
2519 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2521 cifs_small_buf_release(pSMB);
2524 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2525 } else if (pLockData) {
2526 /* lock structure can be returned on get */
2529 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2531 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2532 rc = -EIO; /* bad smb */
2535 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2536 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2537 if (data_count < sizeof(struct cifs_posix_lock)) {
2541 parm_data = (struct cifs_posix_lock *)
2542 ((char *)&pSMBr->hdr.Protocol + data_offset);
2543 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2544 pLockData->fl_type = F_UNLCK;
2546 if (parm_data->lock_type ==
2547 cpu_to_le16(CIFS_RDLCK))
2548 pLockData->fl_type = F_RDLCK;
2549 else if (parm_data->lock_type ==
2550 cpu_to_le16(CIFS_WRLCK))
2551 pLockData->fl_type = F_WRLCK;
2553 pLockData->fl_start = le64_to_cpu(parm_data->start);
2554 pLockData->fl_end = pLockData->fl_start +
2555 le64_to_cpu(parm_data->length) - 1;
2556 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2561 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2563 /* Note: On -EAGAIN error only caller can retry on handle based calls
2564 since file handle passed in no longer valid */
2571 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2574 CLOSE_REQ *pSMB = NULL;
2575 cifs_dbg(FYI, "In CIFSSMBClose\n");
2577 /* do not retry on dead session on close */
2578 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2584 pSMB->FileID = (__u16) smb_file_id;
2585 pSMB->LastWriteTime = 0xFFFFFFFF;
2586 pSMB->ByteCount = 0;
2587 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2588 cifs_small_buf_release(pSMB);
2589 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2592 /* EINTR is expected when user ctl-c to kill app */
2593 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2597 /* Since session is dead, file will be closed on server already */
2605 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2608 FLUSH_REQ *pSMB = NULL;
2609 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2611 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2615 pSMB->FileID = (__u16) smb_file_id;
2616 pSMB->ByteCount = 0;
2617 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2618 cifs_small_buf_release(pSMB);
2619 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2621 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2627 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2628 const char *from_name, const char *to_name,
2629 struct cifs_sb_info *cifs_sb)
2632 RENAME_REQ *pSMB = NULL;
2633 RENAME_RSP *pSMBr = NULL;
2635 int name_len, name_len2;
2637 int remap = cifs_remap(cifs_sb);
2639 cifs_dbg(FYI, "In CIFSSMBRename\n");
2641 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2646 pSMB->BufferFormat = 0x04;
2647 pSMB->SearchAttributes =
2648 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2651 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2652 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2653 from_name, PATH_MAX,
2654 cifs_sb->local_nls, remap);
2655 name_len++; /* trailing null */
2657 pSMB->OldFileName[name_len] = 0x04; /* pad */
2658 /* protocol requires ASCII signature byte on Unicode string */
2659 pSMB->OldFileName[name_len + 1] = 0x00;
2661 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2662 to_name, PATH_MAX, cifs_sb->local_nls,
2664 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2665 name_len2 *= 2; /* convert to bytes */
2666 } else { /* BB improve the check for buffer overruns BB */
2667 name_len = strnlen(from_name, PATH_MAX);
2668 name_len++; /* trailing null */
2669 strncpy(pSMB->OldFileName, from_name, name_len);
2670 name_len2 = strnlen(to_name, PATH_MAX);
2671 name_len2++; /* trailing null */
2672 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2673 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
2674 name_len2++; /* trailing null */
2675 name_len2++; /* signature byte */
2678 count = 1 /* 1st signature byte */ + name_len + name_len2;
2679 inc_rfc1001_len(pSMB, count);
2680 pSMB->ByteCount = cpu_to_le16(count);
2682 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2683 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2684 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2686 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2688 cifs_buf_release(pSMB);
2696 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2697 int netfid, const char *target_name,
2698 const struct nls_table *nls_codepage, int remap)
2700 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2701 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2702 struct set_file_rename *rename_info;
2704 char dummy_string[30];
2706 int bytes_returned = 0;
2708 __u16 params, param_offset, offset, count, byte_count;
2710 cifs_dbg(FYI, "Rename to File by handle\n");
2711 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2717 pSMB->MaxSetupCount = 0;
2721 pSMB->Reserved2 = 0;
2722 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2723 offset = param_offset + params;
2725 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2726 rename_info = (struct set_file_rename *) data_offset;
2727 pSMB->MaxParameterCount = cpu_to_le16(2);
2728 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2729 pSMB->SetupCount = 1;
2730 pSMB->Reserved3 = 0;
2731 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2732 byte_count = 3 /* pad */ + params;
2733 pSMB->ParameterCount = cpu_to_le16(params);
2734 pSMB->TotalParameterCount = pSMB->ParameterCount;
2735 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2736 pSMB->DataOffset = cpu_to_le16(offset);
2737 /* construct random name ".cifs_tmp<inodenum><mid>" */
2738 rename_info->overwrite = cpu_to_le32(1);
2739 rename_info->root_fid = 0;
2740 /* unicode only call */
2741 if (target_name == NULL) {
2742 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2744 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2745 dummy_string, 24, nls_codepage, remap);
2748 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2749 target_name, PATH_MAX, nls_codepage,
2752 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2753 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2754 byte_count += count;
2755 pSMB->DataCount = cpu_to_le16(count);
2756 pSMB->TotalDataCount = pSMB->DataCount;
2758 pSMB->InformationLevel =
2759 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2760 pSMB->Reserved4 = 0;
2761 inc_rfc1001_len(pSMB, byte_count);
2762 pSMB->ByteCount = cpu_to_le16(byte_count);
2763 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2764 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2765 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2767 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2770 cifs_buf_release(pSMB);
2772 /* Note: On -EAGAIN error only caller can retry on handle based calls
2773 since file handle passed in no longer valid */
2779 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2780 const char *fromName, const __u16 target_tid, const char *toName,
2781 const int flags, const struct nls_table *nls_codepage, int remap)
2784 COPY_REQ *pSMB = NULL;
2785 COPY_RSP *pSMBr = NULL;
2787 int name_len, name_len2;
2790 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2792 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2797 pSMB->BufferFormat = 0x04;
2798 pSMB->Tid2 = target_tid;
2800 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2802 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2803 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2804 fromName, PATH_MAX, nls_codepage,
2806 name_len++; /* trailing null */
2808 pSMB->OldFileName[name_len] = 0x04; /* pad */
2809 /* protocol requires ASCII signature byte on Unicode string */
2810 pSMB->OldFileName[name_len + 1] = 0x00;
2812 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2813 toName, PATH_MAX, nls_codepage, remap);
2814 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2815 name_len2 *= 2; /* convert to bytes */
2816 } else { /* BB improve the check for buffer overruns BB */
2817 name_len = strnlen(fromName, PATH_MAX);
2818 name_len++; /* trailing null */
2819 strncpy(pSMB->OldFileName, fromName, name_len);
2820 name_len2 = strnlen(toName, PATH_MAX);
2821 name_len2++; /* trailing null */
2822 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2823 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2824 name_len2++; /* trailing null */
2825 name_len2++; /* signature byte */
2828 count = 1 /* 1st signature byte */ + name_len + name_len2;
2829 inc_rfc1001_len(pSMB, count);
2830 pSMB->ByteCount = cpu_to_le16(count);
2832 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2833 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2835 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2836 rc, le16_to_cpu(pSMBr->CopyCount));
2838 cifs_buf_release(pSMB);
2847 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2848 const char *fromName, const char *toName,
2849 const struct nls_table *nls_codepage, int remap)
2851 TRANSACTION2_SPI_REQ *pSMB = NULL;
2852 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2855 int name_len_target;
2857 int bytes_returned = 0;
2858 __u16 params, param_offset, offset, byte_count;
2860 cifs_dbg(FYI, "In Symlink Unix style\n");
2862 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2867 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2869 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2870 /* find define for this maxpathcomponent */
2871 PATH_MAX, nls_codepage, remap);
2872 name_len++; /* trailing null */
2875 } else { /* BB improve the check for buffer overruns BB */
2876 name_len = strnlen(fromName, PATH_MAX);
2877 name_len++; /* trailing null */
2878 strncpy(pSMB->FileName, fromName, name_len);
2880 params = 6 + name_len;
2881 pSMB->MaxSetupCount = 0;
2885 pSMB->Reserved2 = 0;
2886 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2887 InformationLevel) - 4;
2888 offset = param_offset + params;
2890 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2891 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2893 cifsConvertToUTF16((__le16 *) data_offset, toName,
2894 /* find define for this maxpathcomponent */
2895 PATH_MAX, nls_codepage, remap);
2896 name_len_target++; /* trailing null */
2897 name_len_target *= 2;
2898 } else { /* BB improve the check for buffer overruns BB */
2899 name_len_target = strnlen(toName, PATH_MAX);
2900 name_len_target++; /* trailing null */
2901 strncpy(data_offset, toName, name_len_target);
2904 pSMB->MaxParameterCount = cpu_to_le16(2);
2905 /* BB find exact max on data count below from sess */
2906 pSMB->MaxDataCount = cpu_to_le16(1000);
2907 pSMB->SetupCount = 1;
2908 pSMB->Reserved3 = 0;
2909 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2910 byte_count = 3 /* pad */ + params + name_len_target;
2911 pSMB->DataCount = cpu_to_le16(name_len_target);
2912 pSMB->ParameterCount = cpu_to_le16(params);
2913 pSMB->TotalDataCount = pSMB->DataCount;
2914 pSMB->TotalParameterCount = pSMB->ParameterCount;
2915 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2916 pSMB->DataOffset = cpu_to_le16(offset);
2917 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2918 pSMB->Reserved4 = 0;
2919 inc_rfc1001_len(pSMB, byte_count);
2920 pSMB->ByteCount = cpu_to_le16(byte_count);
2921 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2922 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2923 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2925 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2928 cifs_buf_release(pSMB);
2931 goto createSymLinkRetry;
2937 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2938 const char *fromName, const char *toName,
2939 const struct nls_table *nls_codepage, int remap)
2941 TRANSACTION2_SPI_REQ *pSMB = NULL;
2942 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2945 int name_len_target;
2947 int bytes_returned = 0;
2948 __u16 params, param_offset, offset, byte_count;
2950 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2951 createHardLinkRetry:
2952 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2957 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2958 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2959 PATH_MAX, nls_codepage, remap);
2960 name_len++; /* trailing null */
2963 } else { /* BB improve the check for buffer overruns BB */
2964 name_len = strnlen(toName, PATH_MAX);
2965 name_len++; /* trailing null */
2966 strncpy(pSMB->FileName, toName, name_len);
2968 params = 6 + name_len;
2969 pSMB->MaxSetupCount = 0;
2973 pSMB->Reserved2 = 0;
2974 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2975 InformationLevel) - 4;
2976 offset = param_offset + params;
2978 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2979 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2981 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2982 PATH_MAX, nls_codepage, remap);
2983 name_len_target++; /* trailing null */
2984 name_len_target *= 2;
2985 } else { /* BB improve the check for buffer overruns BB */
2986 name_len_target = strnlen(fromName, PATH_MAX);
2987 name_len_target++; /* trailing null */
2988 strncpy(data_offset, fromName, name_len_target);
2991 pSMB->MaxParameterCount = cpu_to_le16(2);
2992 /* BB find exact max on data count below from sess*/
2993 pSMB->MaxDataCount = cpu_to_le16(1000);
2994 pSMB->SetupCount = 1;
2995 pSMB->Reserved3 = 0;
2996 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2997 byte_count = 3 /* pad */ + params + name_len_target;
2998 pSMB->ParameterCount = cpu_to_le16(params);
2999 pSMB->TotalParameterCount = pSMB->ParameterCount;
3000 pSMB->DataCount = cpu_to_le16(name_len_target);
3001 pSMB->TotalDataCount = pSMB->DataCount;
3002 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3003 pSMB->DataOffset = cpu_to_le16(offset);
3004 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
3005 pSMB->Reserved4 = 0;
3006 inc_rfc1001_len(pSMB, byte_count);
3007 pSMB->ByteCount = cpu_to_le16(byte_count);
3008 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3009 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3010 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3012 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
3015 cifs_buf_release(pSMB);
3017 goto createHardLinkRetry;
3023 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3024 const char *from_name, const char *to_name,
3025 struct cifs_sb_info *cifs_sb)
3028 NT_RENAME_REQ *pSMB = NULL;
3029 RENAME_RSP *pSMBr = NULL;
3031 int name_len, name_len2;
3033 int remap = cifs_remap(cifs_sb);
3035 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3036 winCreateHardLinkRetry:
3038 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3043 pSMB->SearchAttributes =
3044 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3046 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3047 pSMB->ClusterCount = 0;
3049 pSMB->BufferFormat = 0x04;
3051 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3053 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3054 PATH_MAX, cifs_sb->local_nls, remap);
3055 name_len++; /* trailing null */
3058 /* protocol specifies ASCII buffer format (0x04) for unicode */
3059 pSMB->OldFileName[name_len] = 0x04;
3060 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3062 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3063 to_name, PATH_MAX, cifs_sb->local_nls,
3065 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3066 name_len2 *= 2; /* convert to bytes */
3067 } else { /* BB improve the check for buffer overruns BB */
3068 name_len = strnlen(from_name, PATH_MAX);
3069 name_len++; /* trailing null */
3070 strncpy(pSMB->OldFileName, from_name, name_len);
3071 name_len2 = strnlen(to_name, PATH_MAX);
3072 name_len2++; /* trailing null */
3073 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3074 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
3075 name_len2++; /* trailing null */
3076 name_len2++; /* signature byte */
3079 count = 1 /* string type byte */ + name_len + name_len2;
3080 inc_rfc1001_len(pSMB, count);
3081 pSMB->ByteCount = cpu_to_le16(count);
3083 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3084 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3085 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3087 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3089 cifs_buf_release(pSMB);
3091 goto winCreateHardLinkRetry;
3097 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3098 const unsigned char *searchName, char **symlinkinfo,
3099 const struct nls_table *nls_codepage, int remap)
3101 /* SMB_QUERY_FILE_UNIX_LINK */
3102 TRANSACTION2_QPI_REQ *pSMB = NULL;
3103 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3107 __u16 params, byte_count;
3110 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3113 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3118 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3120 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3121 searchName, PATH_MAX, nls_codepage,
3123 name_len++; /* trailing null */
3125 } else { /* BB improve the check for buffer overruns BB */
3126 name_len = strnlen(searchName, PATH_MAX);
3127 name_len++; /* trailing null */
3128 strncpy(pSMB->FileName, searchName, name_len);
3131 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3132 pSMB->TotalDataCount = 0;
3133 pSMB->MaxParameterCount = cpu_to_le16(2);
3134 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3135 pSMB->MaxSetupCount = 0;
3139 pSMB->Reserved2 = 0;
3140 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3141 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3142 pSMB->DataCount = 0;
3143 pSMB->DataOffset = 0;
3144 pSMB->SetupCount = 1;
3145 pSMB->Reserved3 = 0;
3146 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3147 byte_count = params + 1 /* pad */ ;
3148 pSMB->TotalParameterCount = cpu_to_le16(params);
3149 pSMB->ParameterCount = pSMB->TotalParameterCount;
3150 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3151 pSMB->Reserved4 = 0;
3152 inc_rfc1001_len(pSMB, byte_count);
3153 pSMB->ByteCount = cpu_to_le16(byte_count);
3155 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3156 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3158 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3160 /* decode response */
3162 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3163 /* BB also check enough total bytes returned */
3164 if (rc || get_bcc(&pSMBr->hdr) < 2)
3168 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3170 data_start = ((char *) &pSMBr->hdr.Protocol) +
3171 le16_to_cpu(pSMBr->t2.DataOffset);
3173 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3178 /* BB FIXME investigate remapping reserved chars here */
3179 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3180 count, is_unicode, nls_codepage);
3185 cifs_buf_release(pSMB);
3187 goto querySymLinkRetry;
3192 * Recent Windows versions now create symlinks more frequently
3193 * and they use the "reparse point" mechanism below. We can of course
3194 * do symlinks nicely to Samba and other servers which support the
3195 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3196 * "MF" symlinks optionally, but for recent Windows we really need to
3197 * reenable the code below and fix the cifs_symlink callers to handle this.
3198 * In the interim this code has been moved to its own config option so
3199 * it is not compiled in by default until callers fixed up and more tested.
3202 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3203 __u16 fid, char **symlinkinfo,
3204 const struct nls_table *nls_codepage)
3208 struct smb_com_transaction_ioctl_req *pSMB;
3209 struct smb_com_transaction_ioctl_rsp *pSMBr;
3211 unsigned int sub_len;
3213 struct reparse_symlink_data *reparse_buf;
3214 struct reparse_posix_data *posix_buf;
3215 __u32 data_offset, data_count;
3218 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3219 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3224 pSMB->TotalParameterCount = 0 ;
3225 pSMB->TotalDataCount = 0;
3226 pSMB->MaxParameterCount = cpu_to_le32(2);
3227 /* BB find exact data count max from sess structure BB */
3228 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3229 pSMB->MaxSetupCount = 4;
3231 pSMB->ParameterOffset = 0;
3232 pSMB->DataCount = 0;
3233 pSMB->DataOffset = 0;
3234 pSMB->SetupCount = 4;
3235 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3236 pSMB->ParameterCount = pSMB->TotalParameterCount;
3237 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3238 pSMB->IsFsctl = 1; /* FSCTL */
3239 pSMB->IsRootFlag = 0;
3240 pSMB->Fid = fid; /* file handle always le */
3241 pSMB->ByteCount = 0;
3243 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3244 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3246 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3250 data_offset = le32_to_cpu(pSMBr->DataOffset);
3251 data_count = le32_to_cpu(pSMBr->DataCount);
3252 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3253 /* BB also check enough total bytes returned */
3254 rc = -EIO; /* bad smb */
3257 if (!data_count || (data_count > 2048)) {
3259 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3262 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3263 reparse_buf = (struct reparse_symlink_data *)
3264 ((char *)&pSMBr->hdr.Protocol + data_offset);
3265 if ((char *)reparse_buf >= end_of_smb) {
3269 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3270 cifs_dbg(FYI, "NFS style reparse tag\n");
3271 posix_buf = (struct reparse_posix_data *)reparse_buf;
3273 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3274 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3275 le64_to_cpu(posix_buf->InodeType));
3280 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3281 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3282 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3286 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3287 sub_len, is_unicode, nls_codepage);
3289 } else if (reparse_buf->ReparseTag !=
3290 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3295 /* Reparse tag is NTFS symlink */
3296 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3297 reparse_buf->PathBuffer;
3298 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3299 if (sub_start + sub_len > end_of_smb) {
3300 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3304 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3309 /* BB FIXME investigate remapping reserved chars here */
3310 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3315 cifs_buf_release(pSMB);
3318 * Note: On -EAGAIN error only caller can retry on handle based calls
3319 * since file handle passed in no longer valid.
3325 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3330 struct smb_com_transaction_compr_ioctl_req *pSMB;
3331 struct smb_com_transaction_ioctl_rsp *pSMBr;
3333 cifs_dbg(FYI, "Set compression for %u\n", fid);
3334 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3339 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3341 pSMB->TotalParameterCount = 0;
3342 pSMB->TotalDataCount = cpu_to_le32(2);
3343 pSMB->MaxParameterCount = 0;
3344 pSMB->MaxDataCount = 0;
3345 pSMB->MaxSetupCount = 4;
3347 pSMB->ParameterOffset = 0;
3348 pSMB->DataCount = cpu_to_le32(2);
3350 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3351 compression_state) - 4); /* 84 */
3352 pSMB->SetupCount = 4;
3353 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3354 pSMB->ParameterCount = 0;
3355 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3356 pSMB->IsFsctl = 1; /* FSCTL */
3357 pSMB->IsRootFlag = 0;
3358 pSMB->Fid = fid; /* file handle always le */
3359 /* 3 byte pad, followed by 2 byte compress state */
3360 pSMB->ByteCount = cpu_to_le16(5);
3361 inc_rfc1001_len(pSMB, 5);
3363 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3364 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3366 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3368 cifs_buf_release(pSMB);
3371 * Note: On -EAGAIN error only caller can retry on handle based calls
3372 * since file handle passed in no longer valid.
3378 #ifdef CONFIG_CIFS_POSIX
3380 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3381 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3382 struct cifs_posix_ace *cifs_ace)
3384 /* u8 cifs fields do not need le conversion */
3385 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3386 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3387 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3389 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3390 ace->e_perm, ace->e_tag, ace->e_id);
3396 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3397 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3398 const int acl_type, const int size_of_data_area)
3403 struct cifs_posix_ace *pACE;
3404 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3405 struct posix_acl_xattr_header *local_acl = (void *)trgt;
3407 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3410 if (acl_type == ACL_TYPE_ACCESS) {
3411 count = le16_to_cpu(cifs_acl->access_entry_count);
3412 pACE = &cifs_acl->ace_array[0];
3413 size = sizeof(struct cifs_posix_acl);
3414 size += sizeof(struct cifs_posix_ace) * count;
3415 /* check if we would go beyond end of SMB */
3416 if (size_of_data_area < size) {
3417 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3418 size_of_data_area, size);
3421 } else if (acl_type == ACL_TYPE_DEFAULT) {
3422 count = le16_to_cpu(cifs_acl->access_entry_count);
3423 size = sizeof(struct cifs_posix_acl);
3424 size += sizeof(struct cifs_posix_ace) * count;
3425 /* skip past access ACEs to get to default ACEs */
3426 pACE = &cifs_acl->ace_array[count];
3427 count = le16_to_cpu(cifs_acl->default_entry_count);
3428 size += sizeof(struct cifs_posix_ace) * count;
3429 /* check if we would go beyond end of SMB */
3430 if (size_of_data_area < size)
3437 size = posix_acl_xattr_size(count);
3438 if ((buflen == 0) || (local_acl == NULL)) {
3439 /* used to query ACL EA size */
3440 } else if (size > buflen) {
3442 } else /* buffer big enough */ {
3443 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3445 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3446 for (i = 0; i < count ; i++) {
3447 cifs_convert_ace(&ace[i], pACE);
3454 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3455 const struct posix_acl_xattr_entry *local_ace)
3457 __u16 rc = 0; /* 0 = ACL converted ok */
3459 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3460 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3461 /* BB is there a better way to handle the large uid? */
3462 if (local_ace->e_id == cpu_to_le32(-1)) {
3463 /* Probably no need to le convert -1 on any arch but can not hurt */
3464 cifs_ace->cifs_uid = cpu_to_le64(-1);
3466 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3468 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3469 ace->e_perm, ace->e_tag, ace->e_id);
3474 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3475 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3476 const int buflen, const int acl_type)
3479 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3480 struct posix_acl_xattr_header *local_acl = (void *)pACL;
3481 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3485 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3488 count = posix_acl_xattr_count((size_t)buflen);
3489 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3490 count, buflen, le32_to_cpu(local_acl->a_version));
3491 if (le32_to_cpu(local_acl->a_version) != 2) {
3492 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3493 le32_to_cpu(local_acl->a_version));
3496 cifs_acl->version = cpu_to_le16(1);
3497 if (acl_type == ACL_TYPE_ACCESS) {
3498 cifs_acl->access_entry_count = cpu_to_le16(count);
3499 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3500 } else if (acl_type == ACL_TYPE_DEFAULT) {
3501 cifs_acl->default_entry_count = cpu_to_le16(count);
3502 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3504 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3507 for (i = 0; i < count; i++) {
3508 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3510 /* ACE not converted */
3515 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3516 rc += sizeof(struct cifs_posix_acl);
3517 /* BB add check to make sure ACL does not overflow SMB */
3523 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3524 const unsigned char *searchName,
3525 char *acl_inf, const int buflen, const int acl_type,
3526 const struct nls_table *nls_codepage, int remap)
3528 /* SMB_QUERY_POSIX_ACL */
3529 TRANSACTION2_QPI_REQ *pSMB = NULL;
3530 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3534 __u16 params, byte_count;
3536 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3539 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3544 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3546 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3547 searchName, PATH_MAX, nls_codepage,
3549 name_len++; /* trailing null */
3551 pSMB->FileName[name_len] = 0;
3552 pSMB->FileName[name_len+1] = 0;
3553 } else { /* BB improve the check for buffer overruns BB */
3554 name_len = strnlen(searchName, PATH_MAX);
3555 name_len++; /* trailing null */
3556 strncpy(pSMB->FileName, searchName, name_len);
3559 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3560 pSMB->TotalDataCount = 0;
3561 pSMB->MaxParameterCount = cpu_to_le16(2);
3562 /* BB find exact max data count below from sess structure BB */
3563 pSMB->MaxDataCount = cpu_to_le16(4000);
3564 pSMB->MaxSetupCount = 0;
3568 pSMB->Reserved2 = 0;
3569 pSMB->ParameterOffset = cpu_to_le16(
3570 offsetof(struct smb_com_transaction2_qpi_req,
3571 InformationLevel) - 4);
3572 pSMB->DataCount = 0;
3573 pSMB->DataOffset = 0;
3574 pSMB->SetupCount = 1;
3575 pSMB->Reserved3 = 0;
3576 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3577 byte_count = params + 1 /* pad */ ;
3578 pSMB->TotalParameterCount = cpu_to_le16(params);
3579 pSMB->ParameterCount = pSMB->TotalParameterCount;
3580 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3581 pSMB->Reserved4 = 0;
3582 inc_rfc1001_len(pSMB, byte_count);
3583 pSMB->ByteCount = cpu_to_le16(byte_count);
3585 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3586 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3587 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3589 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3591 /* decode response */
3593 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3594 /* BB also check enough total bytes returned */
3595 if (rc || get_bcc(&pSMBr->hdr) < 2)
3596 rc = -EIO; /* bad smb */
3598 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3599 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3600 rc = cifs_copy_posix_acl(acl_inf,
3601 (char *)&pSMBr->hdr.Protocol+data_offset,
3602 buflen, acl_type, count);
3605 cifs_buf_release(pSMB);
3612 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3613 const unsigned char *fileName,
3614 const char *local_acl, const int buflen,
3616 const struct nls_table *nls_codepage, int remap)
3618 struct smb_com_transaction2_spi_req *pSMB = NULL;
3619 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3623 int bytes_returned = 0;
3624 __u16 params, byte_count, data_count, param_offset, offset;
3626 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3628 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3632 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3634 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3635 PATH_MAX, nls_codepage, remap);
3636 name_len++; /* trailing null */
3638 } else { /* BB improve the check for buffer overruns BB */
3639 name_len = strnlen(fileName, PATH_MAX);
3640 name_len++; /* trailing null */
3641 strncpy(pSMB->FileName, fileName, name_len);
3643 params = 6 + name_len;
3644 pSMB->MaxParameterCount = cpu_to_le16(2);
3645 /* BB find max SMB size from sess */
3646 pSMB->MaxDataCount = cpu_to_le16(1000);
3647 pSMB->MaxSetupCount = 0;
3651 pSMB->Reserved2 = 0;
3652 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3653 InformationLevel) - 4;
3654 offset = param_offset + params;
3655 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3656 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3658 /* convert to on the wire format for POSIX ACL */
3659 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3661 if (data_count == 0) {
3663 goto setACLerrorExit;
3665 pSMB->DataOffset = cpu_to_le16(offset);
3666 pSMB->SetupCount = 1;
3667 pSMB->Reserved3 = 0;
3668 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3669 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3670 byte_count = 3 /* pad */ + params + data_count;
3671 pSMB->DataCount = cpu_to_le16(data_count);
3672 pSMB->TotalDataCount = pSMB->DataCount;
3673 pSMB->ParameterCount = cpu_to_le16(params);
3674 pSMB->TotalParameterCount = pSMB->ParameterCount;
3675 pSMB->Reserved4 = 0;
3676 inc_rfc1001_len(pSMB, byte_count);
3677 pSMB->ByteCount = cpu_to_le16(byte_count);
3678 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3679 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3681 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3684 cifs_buf_release(pSMB);
3690 /* BB fix tabs in this function FIXME BB */
3692 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3693 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3696 struct smb_t2_qfi_req *pSMB = NULL;
3697 struct smb_t2_qfi_rsp *pSMBr = NULL;
3699 __u16 params, byte_count;
3701 cifs_dbg(FYI, "In GetExtAttr\n");
3706 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3711 params = 2 /* level */ + 2 /* fid */;
3712 pSMB->t2.TotalDataCount = 0;
3713 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3714 /* BB find exact max data count below from sess structure BB */
3715 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3716 pSMB->t2.MaxSetupCount = 0;
3717 pSMB->t2.Reserved = 0;
3719 pSMB->t2.Timeout = 0;
3720 pSMB->t2.Reserved2 = 0;
3721 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3723 pSMB->t2.DataCount = 0;
3724 pSMB->t2.DataOffset = 0;
3725 pSMB->t2.SetupCount = 1;
3726 pSMB->t2.Reserved3 = 0;
3727 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3728 byte_count = params + 1 /* pad */ ;
3729 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3730 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3731 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3734 inc_rfc1001_len(pSMB, byte_count);
3735 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3737 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3738 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3740 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3742 /* decode response */
3743 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3744 /* BB also check enough total bytes returned */
3745 if (rc || get_bcc(&pSMBr->hdr) < 2)
3746 /* If rc should we check for EOPNOSUPP and
3747 disable the srvino flag? or in caller? */
3748 rc = -EIO; /* bad smb */
3750 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3751 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3752 struct file_chattr_info *pfinfo;
3753 /* BB Do we need a cast or hash here ? */
3755 cifs_dbg(FYI, "Illegal size ret in GetExtAttr\n");
3759 pfinfo = (struct file_chattr_info *)
3760 (data_offset + (char *) &pSMBr->hdr.Protocol);
3761 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3762 *pMask = le64_to_cpu(pfinfo->mask);
3766 cifs_buf_release(pSMB);
3768 goto GetExtAttrRetry;
3772 #endif /* CONFIG_POSIX */
3774 #ifdef CONFIG_CIFS_ACL
3776 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3777 * all NT TRANSACTS that we init here have total parm and data under about 400
3778 * bytes (to fit in small cifs buffer size), which is the case so far, it
3779 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3780 * returned setup area) and MaxParameterCount (returned parms size) must be set
3784 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3785 const int parm_len, struct cifs_tcon *tcon,
3790 struct smb_com_ntransact_req *pSMB;
3792 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3796 *ret_buf = (void *)pSMB;
3798 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3799 pSMB->TotalDataCount = 0;
3800 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3801 pSMB->ParameterCount = pSMB->TotalParameterCount;
3802 pSMB->DataCount = pSMB->TotalDataCount;
3803 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3804 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3805 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3806 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3807 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3808 pSMB->SubCommand = cpu_to_le16(sub_command);
3813 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3814 __u32 *pparmlen, __u32 *pdatalen)
3817 __u32 data_count, data_offset, parm_count, parm_offset;
3818 struct smb_com_ntransact_rsp *pSMBr;
3827 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3829 bcc = get_bcc(&pSMBr->hdr);
3830 end_of_smb = 2 /* sizeof byte count */ + bcc +
3831 (char *)&pSMBr->ByteCount;
3833 data_offset = le32_to_cpu(pSMBr->DataOffset);
3834 data_count = le32_to_cpu(pSMBr->DataCount);
3835 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3836 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3838 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3839 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3841 /* should we also check that parm and data areas do not overlap? */
3842 if (*ppparm > end_of_smb) {
3843 cifs_dbg(FYI, "parms start after end of smb\n");
3845 } else if (parm_count + *ppparm > end_of_smb) {
3846 cifs_dbg(FYI, "parm end after end of smb\n");
3848 } else if (*ppdata > end_of_smb) {
3849 cifs_dbg(FYI, "data starts after end of smb\n");
3851 } else if (data_count + *ppdata > end_of_smb) {
3852 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3853 *ppdata, data_count, (data_count + *ppdata),
3856 } else if (parm_count + data_count > bcc) {
3857 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3860 *pdatalen = data_count;
3861 *pparmlen = parm_count;
3865 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3867 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3868 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3872 QUERY_SEC_DESC_REQ *pSMB;
3874 struct kvec rsp_iov;
3876 cifs_dbg(FYI, "GetCifsACL\n");
3881 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3882 8 /* parm len */, tcon, (void **) &pSMB);
3886 pSMB->MaxParameterCount = cpu_to_le32(4);
3887 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3888 pSMB->MaxSetupCount = 0;
3889 pSMB->Fid = fid; /* file handle always le */
3890 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3892 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3893 inc_rfc1001_len(pSMB, 11);
3894 iov[0].iov_base = (char *)pSMB;
3895 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3897 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3899 cifs_small_buf_release(pSMB);
3900 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3902 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3903 } else { /* decode response */
3907 struct smb_com_ntransact_rsp *pSMBr;
3910 /* validate_nttransact */
3911 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3912 &pdata, &parm_len, pbuflen);
3915 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3917 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3918 pSMBr, parm, *acl_inf);
3920 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3921 rc = -EIO; /* bad smb */
3926 /* BB check that data area is minimum length and as big as acl_len */
3928 acl_len = le32_to_cpu(*parm);
3929 if (acl_len != *pbuflen) {
3930 cifs_dbg(VFS, "acl length %d does not match %d\n",
3932 if (*pbuflen > acl_len)
3936 /* check if buffer is big enough for the acl
3937 header followed by the smallest SID */
3938 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3939 (*pbuflen >= 64 * 1024)) {
3940 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3944 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3945 if (*acl_inf == NULL) {
3952 free_rsp_buf(buf_type, rsp_iov.iov_base);
3957 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3958 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3960 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3962 int bytes_returned = 0;
3963 SET_SEC_DESC_REQ *pSMB = NULL;
3967 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3971 pSMB->MaxSetupCount = 0;
3975 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3976 data_count = acllen;
3977 data_offset = param_offset + param_count;
3978 byte_count = 3 /* pad */ + param_count;
3980 pSMB->DataCount = cpu_to_le32(data_count);
3981 pSMB->TotalDataCount = pSMB->DataCount;
3982 pSMB->MaxParameterCount = cpu_to_le32(4);
3983 pSMB->MaxDataCount = cpu_to_le32(16384);
3984 pSMB->ParameterCount = cpu_to_le32(param_count);
3985 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3986 pSMB->TotalParameterCount = pSMB->ParameterCount;
3987 pSMB->DataOffset = cpu_to_le32(data_offset);
3988 pSMB->SetupCount = 0;
3989 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3990 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3992 pSMB->Fid = fid; /* file handle always le */
3993 pSMB->Reserved2 = 0;
3994 pSMB->AclFlags = cpu_to_le32(aclflag);
3996 if (pntsd && acllen) {
3997 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3998 data_offset, pntsd, acllen);
3999 inc_rfc1001_len(pSMB, byte_count + data_count);
4001 inc_rfc1001_len(pSMB, byte_count);
4003 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4004 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4006 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4007 bytes_returned, rc);
4009 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
4010 cifs_buf_release(pSMB);
4013 goto setCifsAclRetry;
4018 #endif /* CONFIG_CIFS_ACL */
4020 /* Legacy Query Path Information call for lookup to old servers such
4023 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
4024 const char *search_name, FILE_ALL_INFO *data,
4025 const struct nls_table *nls_codepage, int remap)
4027 QUERY_INFORMATION_REQ *pSMB;
4028 QUERY_INFORMATION_RSP *pSMBr;
4033 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
4035 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
4040 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4042 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4043 search_name, PATH_MAX, nls_codepage,
4045 name_len++; /* trailing null */
4048 name_len = strnlen(search_name, PATH_MAX);
4049 name_len++; /* trailing null */
4050 strncpy(pSMB->FileName, search_name, name_len);
4052 pSMB->BufferFormat = 0x04;
4053 name_len++; /* account for buffer type byte */
4054 inc_rfc1001_len(pSMB, (__u16)name_len);
4055 pSMB->ByteCount = cpu_to_le16(name_len);
4057 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4058 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4060 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4063 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4065 /* decode response */
4066 /* BB FIXME - add time zone adjustment BB */
4067 memset(data, 0, sizeof(FILE_ALL_INFO));
4070 /* decode time fields */
4071 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4072 data->LastWriteTime = data->ChangeTime;
4073 data->LastAccessTime = 0;
4074 data->AllocationSize =
4075 cpu_to_le64(le32_to_cpu(pSMBr->size));
4076 data->EndOfFile = data->AllocationSize;
4078 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4080 rc = -EIO; /* bad buffer passed in */
4082 cifs_buf_release(pSMB);
4091 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4092 u16 netfid, FILE_ALL_INFO *pFindData)
4094 struct smb_t2_qfi_req *pSMB = NULL;
4095 struct smb_t2_qfi_rsp *pSMBr = NULL;
4098 __u16 params, byte_count;
4101 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4106 params = 2 /* level */ + 2 /* fid */;
4107 pSMB->t2.TotalDataCount = 0;
4108 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4109 /* BB find exact max data count below from sess structure BB */
4110 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4111 pSMB->t2.MaxSetupCount = 0;
4112 pSMB->t2.Reserved = 0;
4114 pSMB->t2.Timeout = 0;
4115 pSMB->t2.Reserved2 = 0;
4116 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4118 pSMB->t2.DataCount = 0;
4119 pSMB->t2.DataOffset = 0;
4120 pSMB->t2.SetupCount = 1;
4121 pSMB->t2.Reserved3 = 0;
4122 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4123 byte_count = params + 1 /* pad */ ;
4124 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4125 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4126 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4129 inc_rfc1001_len(pSMB, byte_count);
4130 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4132 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4133 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4135 cifs_dbg(FYI, "Send error in QFileInfo = %d", rc);
4136 } else { /* decode response */
4137 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4139 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4141 else if (get_bcc(&pSMBr->hdr) < 40)
4142 rc = -EIO; /* bad smb */
4143 else if (pFindData) {
4144 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4145 memcpy((char *) pFindData,
4146 (char *) &pSMBr->hdr.Protocol +
4147 data_offset, sizeof(FILE_ALL_INFO));
4151 cifs_buf_release(pSMB);
4153 goto QFileInfoRetry;
4159 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4160 const char *search_name, FILE_ALL_INFO *data,
4161 int legacy /* old style infolevel */,
4162 const struct nls_table *nls_codepage, int remap)
4164 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4165 TRANSACTION2_QPI_REQ *pSMB = NULL;
4166 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4170 __u16 params, byte_count;
4172 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4174 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4179 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4181 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4182 PATH_MAX, nls_codepage, remap);
4183 name_len++; /* trailing null */
4185 } else { /* BB improve the check for buffer overruns BB */
4186 name_len = strnlen(search_name, PATH_MAX);
4187 name_len++; /* trailing null */
4188 strncpy(pSMB->FileName, search_name, name_len);
4191 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4192 pSMB->TotalDataCount = 0;
4193 pSMB->MaxParameterCount = cpu_to_le16(2);
4194 /* BB find exact max SMB PDU from sess structure BB */
4195 pSMB->MaxDataCount = cpu_to_le16(4000);
4196 pSMB->MaxSetupCount = 0;
4200 pSMB->Reserved2 = 0;
4201 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4202 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4203 pSMB->DataCount = 0;
4204 pSMB->DataOffset = 0;
4205 pSMB->SetupCount = 1;
4206 pSMB->Reserved3 = 0;
4207 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4208 byte_count = params + 1 /* pad */ ;
4209 pSMB->TotalParameterCount = cpu_to_le16(params);
4210 pSMB->ParameterCount = pSMB->TotalParameterCount;
4212 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4214 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4215 pSMB->Reserved4 = 0;
4216 inc_rfc1001_len(pSMB, byte_count);
4217 pSMB->ByteCount = cpu_to_le16(byte_count);
4219 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4220 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4222 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4223 } else { /* decode response */
4224 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4226 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4228 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4229 rc = -EIO; /* bad smb */
4230 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4231 rc = -EIO; /* 24 or 26 expected but we do not read
4235 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4238 * On legacy responses we do not read the last field,
4239 * EAsize, fortunately since it varies by subdialect and
4240 * also note it differs on Set vs Get, ie two bytes or 4
4241 * bytes depending but we don't care here.
4244 size = sizeof(FILE_INFO_STANDARD);
4246 size = sizeof(FILE_ALL_INFO);
4247 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4252 cifs_buf_release(pSMB);
4254 goto QPathInfoRetry;
4260 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4261 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4263 struct smb_t2_qfi_req *pSMB = NULL;
4264 struct smb_t2_qfi_rsp *pSMBr = NULL;
4267 __u16 params, byte_count;
4270 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4275 params = 2 /* level */ + 2 /* fid */;
4276 pSMB->t2.TotalDataCount = 0;
4277 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4278 /* BB find exact max data count below from sess structure BB */
4279 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4280 pSMB->t2.MaxSetupCount = 0;
4281 pSMB->t2.Reserved = 0;
4283 pSMB->t2.Timeout = 0;
4284 pSMB->t2.Reserved2 = 0;
4285 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4287 pSMB->t2.DataCount = 0;
4288 pSMB->t2.DataOffset = 0;
4289 pSMB->t2.SetupCount = 1;
4290 pSMB->t2.Reserved3 = 0;
4291 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4292 byte_count = params + 1 /* pad */ ;
4293 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4294 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4295 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4298 inc_rfc1001_len(pSMB, byte_count);
4299 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4301 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4302 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4304 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d", rc);
4305 } else { /* decode response */
4306 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4308 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4309 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4310 rc = -EIO; /* bad smb */
4312 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4313 memcpy((char *) pFindData,
4314 (char *) &pSMBr->hdr.Protocol +
4316 sizeof(FILE_UNIX_BASIC_INFO));
4320 cifs_buf_release(pSMB);
4322 goto UnixQFileInfoRetry;
4328 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4329 const unsigned char *searchName,
4330 FILE_UNIX_BASIC_INFO *pFindData,
4331 const struct nls_table *nls_codepage, int remap)
4333 /* SMB_QUERY_FILE_UNIX_BASIC */
4334 TRANSACTION2_QPI_REQ *pSMB = NULL;
4335 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4337 int bytes_returned = 0;
4339 __u16 params, byte_count;
4341 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4343 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4348 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4350 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4351 PATH_MAX, nls_codepage, remap);
4352 name_len++; /* trailing null */
4354 } else { /* BB improve the check for buffer overruns BB */
4355 name_len = strnlen(searchName, PATH_MAX);
4356 name_len++; /* trailing null */
4357 strncpy(pSMB->FileName, searchName, name_len);
4360 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4361 pSMB->TotalDataCount = 0;
4362 pSMB->MaxParameterCount = cpu_to_le16(2);
4363 /* BB find exact max SMB PDU from sess structure BB */
4364 pSMB->MaxDataCount = cpu_to_le16(4000);
4365 pSMB->MaxSetupCount = 0;
4369 pSMB->Reserved2 = 0;
4370 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4371 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4372 pSMB->DataCount = 0;
4373 pSMB->DataOffset = 0;
4374 pSMB->SetupCount = 1;
4375 pSMB->Reserved3 = 0;
4376 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4377 byte_count = params + 1 /* pad */ ;
4378 pSMB->TotalParameterCount = cpu_to_le16(params);
4379 pSMB->ParameterCount = pSMB->TotalParameterCount;
4380 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4381 pSMB->Reserved4 = 0;
4382 inc_rfc1001_len(pSMB, byte_count);
4383 pSMB->ByteCount = cpu_to_le16(byte_count);
4385 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4386 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4388 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d", rc);
4389 } else { /* decode response */
4390 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4392 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4393 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4394 rc = -EIO; /* bad smb */
4396 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4397 memcpy((char *) pFindData,
4398 (char *) &pSMBr->hdr.Protocol +
4400 sizeof(FILE_UNIX_BASIC_INFO));
4403 cifs_buf_release(pSMB);
4405 goto UnixQPathInfoRetry;
4410 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4412 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4413 const char *searchName, struct cifs_sb_info *cifs_sb,
4414 __u16 *pnetfid, __u16 search_flags,
4415 struct cifs_search_info *psrch_inf, bool msearch)
4417 /* level 257 SMB_ */
4418 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4419 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4420 T2_FFIRST_RSP_PARMS *parms;
4422 int bytes_returned = 0;
4423 int name_len, remap;
4424 __u16 params, byte_count;
4425 struct nls_table *nls_codepage;
4427 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4430 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4435 nls_codepage = cifs_sb->local_nls;
4436 remap = cifs_remap(cifs_sb);
4438 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4440 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4441 PATH_MAX, nls_codepage, remap);
4442 /* We can not add the asterik earlier in case
4443 it got remapped to 0xF03A as if it were part of the
4444 directory name instead of a wildcard */
4447 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4448 pSMB->FileName[name_len+1] = 0;
4449 pSMB->FileName[name_len+2] = '*';
4450 pSMB->FileName[name_len+3] = 0;
4451 name_len += 4; /* now the trailing null */
4452 /* null terminate just in case */
4453 pSMB->FileName[name_len] = 0;
4454 pSMB->FileName[name_len+1] = 0;
4457 } else { /* BB add check for overrun of SMB buf BB */
4458 name_len = strnlen(searchName, PATH_MAX);
4459 /* BB fix here and in unicode clause above ie
4460 if (name_len > buffersize-header)
4461 free buffer exit; BB */
4462 strncpy(pSMB->FileName, searchName, name_len);
4464 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4465 pSMB->FileName[name_len+1] = '*';
4466 pSMB->FileName[name_len+2] = 0;
4471 params = 12 + name_len /* includes null */ ;
4472 pSMB->TotalDataCount = 0; /* no EAs */
4473 pSMB->MaxParameterCount = cpu_to_le16(10);
4474 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4475 pSMB->MaxSetupCount = 0;
4479 pSMB->Reserved2 = 0;
4480 byte_count = params + 1 /* pad */ ;
4481 pSMB->TotalParameterCount = cpu_to_le16(params);
4482 pSMB->ParameterCount = pSMB->TotalParameterCount;
4483 pSMB->ParameterOffset = cpu_to_le16(
4484 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4486 pSMB->DataCount = 0;
4487 pSMB->DataOffset = 0;
4488 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4489 pSMB->Reserved3 = 0;
4490 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4491 pSMB->SearchAttributes =
4492 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4494 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4495 pSMB->SearchFlags = cpu_to_le16(search_flags);
4496 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4498 /* BB what should we set StorageType to? Does it matter? BB */
4499 pSMB->SearchStorageType = 0;
4500 inc_rfc1001_len(pSMB, byte_count);
4501 pSMB->ByteCount = cpu_to_le16(byte_count);
4503 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4504 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4505 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4507 if (rc) {/* BB add logic to retry regular search if Unix search
4508 rejected unexpectedly by server */
4509 /* BB Add code to handle unsupported level rc */
4510 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4512 cifs_buf_release(pSMB);
4514 /* BB eventually could optimize out free and realloc of buf */
4517 goto findFirstRetry;
4518 } else { /* decode response */
4519 /* BB remember to free buffer if error BB */
4520 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4524 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4525 psrch_inf->unicode = true;
4527 psrch_inf->unicode = false;
4529 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4530 psrch_inf->smallBuf = 0;
4531 psrch_inf->srch_entries_start =
4532 (char *) &pSMBr->hdr.Protocol +
4533 le16_to_cpu(pSMBr->t2.DataOffset);
4534 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4535 le16_to_cpu(pSMBr->t2.ParameterOffset));
4537 if (parms->EndofSearch)
4538 psrch_inf->endOfSearch = true;
4540 psrch_inf->endOfSearch = false;
4542 psrch_inf->entries_in_buffer =
4543 le16_to_cpu(parms->SearchCount);
4544 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4545 psrch_inf->entries_in_buffer;
4546 lnoff = le16_to_cpu(parms->LastNameOffset);
4547 if (CIFSMaxBufSize < lnoff) {
4548 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4549 psrch_inf->last_entry = NULL;
4553 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4557 *pnetfid = parms->SearchHandle;
4559 cifs_buf_release(pSMB);
4566 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4567 __u16 searchHandle, __u16 search_flags,
4568 struct cifs_search_info *psrch_inf)
4570 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4571 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4572 T2_FNEXT_RSP_PARMS *parms;
4573 char *response_data;
4576 unsigned int name_len;
4577 __u16 params, byte_count;
4579 cifs_dbg(FYI, "In FindNext\n");
4581 if (psrch_inf->endOfSearch)
4584 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4589 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4591 pSMB->TotalDataCount = 0; /* no EAs */
4592 pSMB->MaxParameterCount = cpu_to_le16(8);
4593 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4594 pSMB->MaxSetupCount = 0;
4598 pSMB->Reserved2 = 0;
4599 pSMB->ParameterOffset = cpu_to_le16(
4600 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4601 pSMB->DataCount = 0;
4602 pSMB->DataOffset = 0;
4603 pSMB->SetupCount = 1;
4604 pSMB->Reserved3 = 0;
4605 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4606 pSMB->SearchHandle = searchHandle; /* always kept as le */
4608 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4609 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4610 pSMB->ResumeKey = psrch_inf->resume_key;
4611 pSMB->SearchFlags = cpu_to_le16(search_flags);
4613 name_len = psrch_inf->resume_name_len;
4615 if (name_len < PATH_MAX) {
4616 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4617 byte_count += name_len;
4618 /* 14 byte parm len above enough for 2 byte null terminator */
4619 pSMB->ResumeFileName[name_len] = 0;
4620 pSMB->ResumeFileName[name_len+1] = 0;
4623 goto FNext2_err_exit;
4625 byte_count = params + 1 /* pad */ ;
4626 pSMB->TotalParameterCount = cpu_to_le16(params);
4627 pSMB->ParameterCount = pSMB->TotalParameterCount;
4628 inc_rfc1001_len(pSMB, byte_count);
4629 pSMB->ByteCount = cpu_to_le16(byte_count);
4631 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4632 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4633 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4636 psrch_inf->endOfSearch = true;
4637 cifs_buf_release(pSMB);
4638 rc = 0; /* search probably was closed at end of search*/
4640 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4641 } else { /* decode response */
4642 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4647 /* BB fixme add lock for file (srch_info) struct here */
4648 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4649 psrch_inf->unicode = true;
4651 psrch_inf->unicode = false;
4652 response_data = (char *) &pSMBr->hdr.Protocol +
4653 le16_to_cpu(pSMBr->t2.ParameterOffset);
4654 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4655 response_data = (char *)&pSMBr->hdr.Protocol +
4656 le16_to_cpu(pSMBr->t2.DataOffset);
4657 if (psrch_inf->smallBuf)
4658 cifs_small_buf_release(
4659 psrch_inf->ntwrk_buf_start);
4661 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4662 psrch_inf->srch_entries_start = response_data;
4663 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4664 psrch_inf->smallBuf = 0;
4665 if (parms->EndofSearch)
4666 psrch_inf->endOfSearch = true;
4668 psrch_inf->endOfSearch = false;
4669 psrch_inf->entries_in_buffer =
4670 le16_to_cpu(parms->SearchCount);
4671 psrch_inf->index_of_last_entry +=
4672 psrch_inf->entries_in_buffer;
4673 lnoff = le16_to_cpu(parms->LastNameOffset);
4674 if (CIFSMaxBufSize < lnoff) {
4675 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4676 psrch_inf->last_entry = NULL;
4679 psrch_inf->last_entry =
4680 psrch_inf->srch_entries_start + lnoff;
4682 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4683 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4685 /* BB fixme add unlock here */
4690 /* BB On error, should we leave previous search buf (and count and
4691 last entry fields) intact or free the previous one? */
4693 /* Note: On -EAGAIN error only caller can retry on handle based calls
4694 since file handle passed in no longer valid */
4697 cifs_buf_release(pSMB);
4702 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4703 const __u16 searchHandle)
4706 FINDCLOSE_REQ *pSMB = NULL;
4708 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4709 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4711 /* no sense returning error if session restarted
4712 as file handle has been closed */
4718 pSMB->FileID = searchHandle;
4719 pSMB->ByteCount = 0;
4720 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4721 cifs_small_buf_release(pSMB);
4723 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4725 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4727 /* Since session is dead, search handle closed on server already */
4735 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4736 const char *search_name, __u64 *inode_number,
4737 const struct nls_table *nls_codepage, int remap)
4740 TRANSACTION2_QPI_REQ *pSMB = NULL;
4741 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4742 int name_len, bytes_returned;
4743 __u16 params, byte_count;
4745 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4749 GetInodeNumberRetry:
4750 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4755 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4757 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4758 search_name, PATH_MAX, nls_codepage,
4760 name_len++; /* trailing null */
4762 } else { /* BB improve the check for buffer overruns BB */
4763 name_len = strnlen(search_name, PATH_MAX);
4764 name_len++; /* trailing null */
4765 strncpy(pSMB->FileName, search_name, name_len);
4768 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4769 pSMB->TotalDataCount = 0;
4770 pSMB->MaxParameterCount = cpu_to_le16(2);
4771 /* BB find exact max data count below from sess structure BB */
4772 pSMB->MaxDataCount = cpu_to_le16(4000);
4773 pSMB->MaxSetupCount = 0;
4777 pSMB->Reserved2 = 0;
4778 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4779 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4780 pSMB->DataCount = 0;
4781 pSMB->DataOffset = 0;
4782 pSMB->SetupCount = 1;
4783 pSMB->Reserved3 = 0;
4784 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4785 byte_count = params + 1 /* pad */ ;
4786 pSMB->TotalParameterCount = cpu_to_le16(params);
4787 pSMB->ParameterCount = pSMB->TotalParameterCount;
4788 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4789 pSMB->Reserved4 = 0;
4790 inc_rfc1001_len(pSMB, byte_count);
4791 pSMB->ByteCount = cpu_to_le16(byte_count);
4793 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4794 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4796 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4798 /* decode response */
4799 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4800 /* BB also check enough total bytes returned */
4801 if (rc || get_bcc(&pSMBr->hdr) < 2)
4802 /* If rc should we check for EOPNOSUPP and
4803 disable the srvino flag? or in caller? */
4804 rc = -EIO; /* bad smb */
4806 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4807 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4808 struct file_internal_info *pfinfo;
4809 /* BB Do we need a cast or hash here ? */
4811 cifs_dbg(FYI, "Illegal size ret in QryIntrnlInf\n");
4813 goto GetInodeNumOut;
4815 pfinfo = (struct file_internal_info *)
4816 (data_offset + (char *) &pSMBr->hdr.Protocol);
4817 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4821 cifs_buf_release(pSMB);
4823 goto GetInodeNumberRetry;
4828 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4829 const char *search_name, struct dfs_info3_param **target_nodes,
4830 unsigned int *num_of_nodes,
4831 const struct nls_table *nls_codepage, int remap)
4833 /* TRANS2_GET_DFS_REFERRAL */
4834 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4835 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4839 __u16 params, byte_count;
4841 *target_nodes = NULL;
4843 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4844 if (ses == NULL || ses->tcon_ipc == NULL)
4848 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4853 /* server pointer checked in called function,
4854 but should never be null here anyway */
4855 pSMB->hdr.Mid = get_next_mid(ses->server);
4856 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4857 pSMB->hdr.Uid = ses->Suid;
4858 if (ses->capabilities & CAP_STATUS32)
4859 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4860 if (ses->capabilities & CAP_DFS)
4861 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4863 if (ses->capabilities & CAP_UNICODE) {
4864 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4866 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4867 search_name, PATH_MAX, nls_codepage,
4869 name_len++; /* trailing null */
4871 } else { /* BB improve the check for buffer overruns BB */
4872 name_len = strnlen(search_name, PATH_MAX);
4873 name_len++; /* trailing null */
4874 strncpy(pSMB->RequestFileName, search_name, name_len);
4877 if (ses->server->sign)
4878 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4880 pSMB->hdr.Uid = ses->Suid;
4882 params = 2 /* level */ + name_len /*includes null */ ;
4883 pSMB->TotalDataCount = 0;
4884 pSMB->DataCount = 0;
4885 pSMB->DataOffset = 0;
4886 pSMB->MaxParameterCount = 0;
4887 /* BB find exact max SMB PDU from sess structure BB */
4888 pSMB->MaxDataCount = cpu_to_le16(4000);
4889 pSMB->MaxSetupCount = 0;
4893 pSMB->Reserved2 = 0;
4894 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4895 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4896 pSMB->SetupCount = 1;
4897 pSMB->Reserved3 = 0;
4898 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4899 byte_count = params + 3 /* pad */ ;
4900 pSMB->ParameterCount = cpu_to_le16(params);
4901 pSMB->TotalParameterCount = pSMB->ParameterCount;
4902 pSMB->MaxReferralLevel = cpu_to_le16(3);
4903 inc_rfc1001_len(pSMB, byte_count);
4904 pSMB->ByteCount = cpu_to_le16(byte_count);
4906 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4907 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4909 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4912 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4914 /* BB Also check if enough total bytes returned? */
4915 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4916 rc = -EIO; /* bad smb */
4920 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4921 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4923 /* parse returned result into more usable form */
4924 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4925 le16_to_cpu(pSMBr->t2.DataCount),
4926 num_of_nodes, target_nodes, nls_codepage,
4928 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4931 cifs_buf_release(pSMB);
4939 /* Query File System Info such as free space to old servers such as Win 9x */
4941 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4942 struct kstatfs *FSData)
4944 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4945 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4946 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4947 FILE_SYSTEM_ALLOC_INFO *response_data;
4949 int bytes_returned = 0;
4950 __u16 params, byte_count;
4952 cifs_dbg(FYI, "OldQFSInfo\n");
4954 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4959 params = 2; /* level */
4960 pSMB->TotalDataCount = 0;
4961 pSMB->MaxParameterCount = cpu_to_le16(2);
4962 pSMB->MaxDataCount = cpu_to_le16(1000);
4963 pSMB->MaxSetupCount = 0;
4967 pSMB->Reserved2 = 0;
4968 byte_count = params + 1 /* pad */ ;
4969 pSMB->TotalParameterCount = cpu_to_le16(params);
4970 pSMB->ParameterCount = pSMB->TotalParameterCount;
4971 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4972 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4973 pSMB->DataCount = 0;
4974 pSMB->DataOffset = 0;
4975 pSMB->SetupCount = 1;
4976 pSMB->Reserved3 = 0;
4977 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4978 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4979 inc_rfc1001_len(pSMB, byte_count);
4980 pSMB->ByteCount = cpu_to_le16(byte_count);
4982 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4983 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4985 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4986 } else { /* decode response */
4987 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4989 if (rc || get_bcc(&pSMBr->hdr) < 18)
4990 rc = -EIO; /* bad smb */
4992 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4993 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4994 get_bcc(&pSMBr->hdr), data_offset);
4996 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4997 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4999 le16_to_cpu(response_data->BytesPerSector) *
5000 le32_to_cpu(response_data->
5001 SectorsPerAllocationUnit);
5003 le32_to_cpu(response_data->TotalAllocationUnits);
5004 FSData->f_bfree = FSData->f_bavail =
5005 le32_to_cpu(response_data->FreeAllocationUnits);
5006 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5007 (unsigned long long)FSData->f_blocks,
5008 (unsigned long long)FSData->f_bfree,
5012 cifs_buf_release(pSMB);
5015 goto oldQFSInfoRetry;
5021 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
5022 struct kstatfs *FSData)
5024 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5025 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5026 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5027 FILE_SYSTEM_INFO *response_data;
5029 int bytes_returned = 0;
5030 __u16 params, byte_count;
5032 cifs_dbg(FYI, "In QFSInfo\n");
5034 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5039 params = 2; /* level */
5040 pSMB->TotalDataCount = 0;
5041 pSMB->MaxParameterCount = cpu_to_le16(2);
5042 pSMB->MaxDataCount = cpu_to_le16(1000);
5043 pSMB->MaxSetupCount = 0;
5047 pSMB->Reserved2 = 0;
5048 byte_count = params + 1 /* pad */ ;
5049 pSMB->TotalParameterCount = cpu_to_le16(params);
5050 pSMB->ParameterCount = pSMB->TotalParameterCount;
5051 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5052 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5053 pSMB->DataCount = 0;
5054 pSMB->DataOffset = 0;
5055 pSMB->SetupCount = 1;
5056 pSMB->Reserved3 = 0;
5057 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5058 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5059 inc_rfc1001_len(pSMB, byte_count);
5060 pSMB->ByteCount = cpu_to_le16(byte_count);
5062 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5063 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5065 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5066 } else { /* decode response */
5067 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5069 if (rc || get_bcc(&pSMBr->hdr) < 24)
5070 rc = -EIO; /* bad smb */
5072 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5076 *) (((char *) &pSMBr->hdr.Protocol) +
5079 le32_to_cpu(response_data->BytesPerSector) *
5080 le32_to_cpu(response_data->
5081 SectorsPerAllocationUnit);
5083 le64_to_cpu(response_data->TotalAllocationUnits);
5084 FSData->f_bfree = FSData->f_bavail =
5085 le64_to_cpu(response_data->FreeAllocationUnits);
5086 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5087 (unsigned long long)FSData->f_blocks,
5088 (unsigned long long)FSData->f_bfree,
5092 cifs_buf_release(pSMB);
5101 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5103 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5104 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5105 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5106 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5108 int bytes_returned = 0;
5109 __u16 params, byte_count;
5111 cifs_dbg(FYI, "In QFSAttributeInfo\n");
5113 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5118 params = 2; /* level */
5119 pSMB->TotalDataCount = 0;
5120 pSMB->MaxParameterCount = cpu_to_le16(2);
5121 /* BB find exact max SMB PDU from sess structure BB */
5122 pSMB->MaxDataCount = cpu_to_le16(1000);
5123 pSMB->MaxSetupCount = 0;
5127 pSMB->Reserved2 = 0;
5128 byte_count = params + 1 /* pad */ ;
5129 pSMB->TotalParameterCount = cpu_to_le16(params);
5130 pSMB->ParameterCount = pSMB->TotalParameterCount;
5131 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5132 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5133 pSMB->DataCount = 0;
5134 pSMB->DataOffset = 0;
5135 pSMB->SetupCount = 1;
5136 pSMB->Reserved3 = 0;
5137 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5138 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5139 inc_rfc1001_len(pSMB, byte_count);
5140 pSMB->ByteCount = cpu_to_le16(byte_count);
5142 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5143 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5145 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5146 } else { /* decode response */
5147 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5149 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5150 /* BB also check if enough bytes returned */
5151 rc = -EIO; /* bad smb */
5153 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5155 (FILE_SYSTEM_ATTRIBUTE_INFO
5156 *) (((char *) &pSMBr->hdr.Protocol) +
5158 memcpy(&tcon->fsAttrInfo, response_data,
5159 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5162 cifs_buf_release(pSMB);
5165 goto QFSAttributeRetry;
5171 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5173 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5174 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5175 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5176 FILE_SYSTEM_DEVICE_INFO *response_data;
5178 int bytes_returned = 0;
5179 __u16 params, byte_count;
5181 cifs_dbg(FYI, "In QFSDeviceInfo\n");
5183 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5188 params = 2; /* level */
5189 pSMB->TotalDataCount = 0;
5190 pSMB->MaxParameterCount = cpu_to_le16(2);
5191 /* BB find exact max SMB PDU from sess structure BB */
5192 pSMB->MaxDataCount = cpu_to_le16(1000);
5193 pSMB->MaxSetupCount = 0;
5197 pSMB->Reserved2 = 0;
5198 byte_count = params + 1 /* pad */ ;
5199 pSMB->TotalParameterCount = cpu_to_le16(params);
5200 pSMB->ParameterCount = pSMB->TotalParameterCount;
5201 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5202 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5204 pSMB->DataCount = 0;
5205 pSMB->DataOffset = 0;
5206 pSMB->SetupCount = 1;
5207 pSMB->Reserved3 = 0;
5208 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5209 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5210 inc_rfc1001_len(pSMB, byte_count);
5211 pSMB->ByteCount = cpu_to_le16(byte_count);
5213 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5214 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5216 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5217 } else { /* decode response */
5218 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5220 if (rc || get_bcc(&pSMBr->hdr) <
5221 sizeof(FILE_SYSTEM_DEVICE_INFO))
5222 rc = -EIO; /* bad smb */
5224 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5226 (FILE_SYSTEM_DEVICE_INFO *)
5227 (((char *) &pSMBr->hdr.Protocol) +
5229 memcpy(&tcon->fsDevInfo, response_data,
5230 sizeof(FILE_SYSTEM_DEVICE_INFO));
5233 cifs_buf_release(pSMB);
5236 goto QFSDeviceRetry;
5242 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5244 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5245 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5246 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5247 FILE_SYSTEM_UNIX_INFO *response_data;
5249 int bytes_returned = 0;
5250 __u16 params, byte_count;
5252 cifs_dbg(FYI, "In QFSUnixInfo\n");
5254 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5255 (void **) &pSMB, (void **) &pSMBr);
5259 params = 2; /* level */
5260 pSMB->TotalDataCount = 0;
5261 pSMB->DataCount = 0;
5262 pSMB->DataOffset = 0;
5263 pSMB->MaxParameterCount = cpu_to_le16(2);
5264 /* BB find exact max SMB PDU from sess structure BB */
5265 pSMB->MaxDataCount = cpu_to_le16(100);
5266 pSMB->MaxSetupCount = 0;
5270 pSMB->Reserved2 = 0;
5271 byte_count = params + 1 /* pad */ ;
5272 pSMB->ParameterCount = cpu_to_le16(params);
5273 pSMB->TotalParameterCount = pSMB->ParameterCount;
5274 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5275 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5276 pSMB->SetupCount = 1;
5277 pSMB->Reserved3 = 0;
5278 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5279 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5280 inc_rfc1001_len(pSMB, byte_count);
5281 pSMB->ByteCount = cpu_to_le16(byte_count);
5283 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5284 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5286 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5287 } else { /* decode response */
5288 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5290 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5291 rc = -EIO; /* bad smb */
5293 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5295 (FILE_SYSTEM_UNIX_INFO
5296 *) (((char *) &pSMBr->hdr.Protocol) +
5298 memcpy(&tcon->fsUnixInfo, response_data,
5299 sizeof(FILE_SYSTEM_UNIX_INFO));
5302 cifs_buf_release(pSMB);
5312 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5314 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5315 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5316 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5318 int bytes_returned = 0;
5319 __u16 params, param_offset, offset, byte_count;
5321 cifs_dbg(FYI, "In SETFSUnixInfo\n");
5323 /* BB switch to small buf init to save memory */
5324 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5325 (void **) &pSMB, (void **) &pSMBr);
5329 params = 4; /* 2 bytes zero followed by info level. */
5330 pSMB->MaxSetupCount = 0;
5334 pSMB->Reserved2 = 0;
5335 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5337 offset = param_offset + params;
5339 pSMB->MaxParameterCount = cpu_to_le16(4);
5340 /* BB find exact max SMB PDU from sess structure BB */
5341 pSMB->MaxDataCount = cpu_to_le16(100);
5342 pSMB->SetupCount = 1;
5343 pSMB->Reserved3 = 0;
5344 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5345 byte_count = 1 /* pad */ + params + 12;
5347 pSMB->DataCount = cpu_to_le16(12);
5348 pSMB->ParameterCount = cpu_to_le16(params);
5349 pSMB->TotalDataCount = pSMB->DataCount;
5350 pSMB->TotalParameterCount = pSMB->ParameterCount;
5351 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5352 pSMB->DataOffset = cpu_to_le16(offset);
5356 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5359 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5360 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5361 pSMB->ClientUnixCap = cpu_to_le64(cap);
5363 inc_rfc1001_len(pSMB, byte_count);
5364 pSMB->ByteCount = cpu_to_le16(byte_count);
5366 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5367 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5369 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5370 } else { /* decode response */
5371 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5373 rc = -EIO; /* bad smb */
5375 cifs_buf_release(pSMB);
5378 goto SETFSUnixRetry;
5386 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5387 struct kstatfs *FSData)
5389 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5390 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5391 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5392 FILE_SYSTEM_POSIX_INFO *response_data;
5394 int bytes_returned = 0;
5395 __u16 params, byte_count;
5397 cifs_dbg(FYI, "In QFSPosixInfo\n");
5399 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5404 params = 2; /* level */
5405 pSMB->TotalDataCount = 0;
5406 pSMB->DataCount = 0;
5407 pSMB->DataOffset = 0;
5408 pSMB->MaxParameterCount = cpu_to_le16(2);
5409 /* BB find exact max SMB PDU from sess structure BB */
5410 pSMB->MaxDataCount = cpu_to_le16(100);
5411 pSMB->MaxSetupCount = 0;
5415 pSMB->Reserved2 = 0;
5416 byte_count = params + 1 /* pad */ ;
5417 pSMB->ParameterCount = cpu_to_le16(params);
5418 pSMB->TotalParameterCount = pSMB->ParameterCount;
5419 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5420 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5421 pSMB->SetupCount = 1;
5422 pSMB->Reserved3 = 0;
5423 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5424 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5425 inc_rfc1001_len(pSMB, byte_count);
5426 pSMB->ByteCount = cpu_to_le16(byte_count);
5428 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5429 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5431 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5432 } else { /* decode response */
5433 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5435 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5436 rc = -EIO; /* bad smb */
5438 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5440 (FILE_SYSTEM_POSIX_INFO
5441 *) (((char *) &pSMBr->hdr.Protocol) +
5444 le32_to_cpu(response_data->BlockSize);
5446 le64_to_cpu(response_data->TotalBlocks);
5448 le64_to_cpu(response_data->BlocksAvail);
5449 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5450 FSData->f_bavail = FSData->f_bfree;
5453 le64_to_cpu(response_data->UserBlocksAvail);
5455 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5457 le64_to_cpu(response_data->TotalFileNodes);
5458 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5460 le64_to_cpu(response_data->FreeFileNodes);
5463 cifs_buf_release(pSMB);
5473 * We can not use write of zero bytes trick to set file size due to need for
5474 * large file support. Also note that this SetPathInfo is preferred to
5475 * SetFileInfo based method in next routine which is only needed to work around
5476 * a sharing violation bugin Samba which this routine can run into.
5479 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5480 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5481 bool set_allocation)
5483 struct smb_com_transaction2_spi_req *pSMB = NULL;
5484 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5485 struct file_end_of_file_info *parm_data;
5488 int bytes_returned = 0;
5489 int remap = cifs_remap(cifs_sb);
5491 __u16 params, byte_count, data_count, param_offset, offset;
5493 cifs_dbg(FYI, "In SetEOF\n");
5495 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5500 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5502 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5503 PATH_MAX, cifs_sb->local_nls, remap);
5504 name_len++; /* trailing null */
5506 } else { /* BB improve the check for buffer overruns BB */
5507 name_len = strnlen(file_name, PATH_MAX);
5508 name_len++; /* trailing null */
5509 strncpy(pSMB->FileName, file_name, name_len);
5511 params = 6 + name_len;
5512 data_count = sizeof(struct file_end_of_file_info);
5513 pSMB->MaxParameterCount = cpu_to_le16(2);
5514 pSMB->MaxDataCount = cpu_to_le16(4100);
5515 pSMB->MaxSetupCount = 0;
5519 pSMB->Reserved2 = 0;
5520 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5521 InformationLevel) - 4;
5522 offset = param_offset + params;
5523 if (set_allocation) {
5524 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5525 pSMB->InformationLevel =
5526 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5528 pSMB->InformationLevel =
5529 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5530 } else /* Set File Size */ {
5531 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5532 pSMB->InformationLevel =
5533 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5535 pSMB->InformationLevel =
5536 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5540 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5542 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5543 pSMB->DataOffset = cpu_to_le16(offset);
5544 pSMB->SetupCount = 1;
5545 pSMB->Reserved3 = 0;
5546 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5547 byte_count = 3 /* pad */ + params + data_count;
5548 pSMB->DataCount = cpu_to_le16(data_count);
5549 pSMB->TotalDataCount = pSMB->DataCount;
5550 pSMB->ParameterCount = cpu_to_le16(params);
5551 pSMB->TotalParameterCount = pSMB->ParameterCount;
5552 pSMB->Reserved4 = 0;
5553 inc_rfc1001_len(pSMB, byte_count);
5554 parm_data->FileSize = cpu_to_le64(size);
5555 pSMB->ByteCount = cpu_to_le16(byte_count);
5556 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5557 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5559 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5561 cifs_buf_release(pSMB);
5570 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5571 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5573 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5574 struct file_end_of_file_info *parm_data;
5576 __u16 params, param_offset, offset, byte_count, count;
5578 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5580 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5585 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5586 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5589 pSMB->MaxSetupCount = 0;
5593 pSMB->Reserved2 = 0;
5594 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5595 offset = param_offset + params;
5597 count = sizeof(struct file_end_of_file_info);
5598 pSMB->MaxParameterCount = cpu_to_le16(2);
5599 /* BB find exact max SMB PDU from sess structure BB */
5600 pSMB->MaxDataCount = cpu_to_le16(1000);
5601 pSMB->SetupCount = 1;
5602 pSMB->Reserved3 = 0;
5603 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5604 byte_count = 3 /* pad */ + params + count;
5605 pSMB->DataCount = cpu_to_le16(count);
5606 pSMB->ParameterCount = cpu_to_le16(params);
5607 pSMB->TotalDataCount = pSMB->DataCount;
5608 pSMB->TotalParameterCount = pSMB->ParameterCount;
5609 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5611 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5613 pSMB->DataOffset = cpu_to_le16(offset);
5614 parm_data->FileSize = cpu_to_le64(size);
5615 pSMB->Fid = cfile->fid.netfid;
5616 if (set_allocation) {
5617 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5618 pSMB->InformationLevel =
5619 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5621 pSMB->InformationLevel =
5622 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5623 } else /* Set File Size */ {
5624 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5625 pSMB->InformationLevel =
5626 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5628 pSMB->InformationLevel =
5629 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5631 pSMB->Reserved4 = 0;
5632 inc_rfc1001_len(pSMB, byte_count);
5633 pSMB->ByteCount = cpu_to_le16(byte_count);
5634 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5635 cifs_small_buf_release(pSMB);
5637 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5641 /* Note: On -EAGAIN error only caller can retry on handle based calls
5642 since file handle passed in no longer valid */
5647 /* Some legacy servers such as NT4 require that the file times be set on
5648 an open handle, rather than by pathname - this is awkward due to
5649 potential access conflicts on the open, but it is unavoidable for these
5650 old servers since the only other choice is to go from 100 nanosecond DCE
5651 time and resort to the original setpathinfo level which takes the ancient
5652 DOS time format with 2 second granularity */
5654 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5655 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5657 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5660 __u16 params, param_offset, offset, byte_count, count;
5662 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5663 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5668 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5669 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5672 pSMB->MaxSetupCount = 0;
5676 pSMB->Reserved2 = 0;
5677 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5678 offset = param_offset + params;
5680 data_offset = (char *)pSMB +
5681 offsetof(struct smb_hdr, Protocol) + offset;
5683 count = sizeof(FILE_BASIC_INFO);
5684 pSMB->MaxParameterCount = cpu_to_le16(2);
5685 /* BB find max SMB PDU from sess */
5686 pSMB->MaxDataCount = cpu_to_le16(1000);
5687 pSMB->SetupCount = 1;
5688 pSMB->Reserved3 = 0;
5689 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5690 byte_count = 3 /* pad */ + params + count;
5691 pSMB->DataCount = cpu_to_le16(count);
5692 pSMB->ParameterCount = cpu_to_le16(params);
5693 pSMB->TotalDataCount = pSMB->DataCount;
5694 pSMB->TotalParameterCount = pSMB->ParameterCount;
5695 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5696 pSMB->DataOffset = cpu_to_le16(offset);
5698 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5699 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5701 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5702 pSMB->Reserved4 = 0;
5703 inc_rfc1001_len(pSMB, byte_count);
5704 pSMB->ByteCount = cpu_to_le16(byte_count);
5705 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5706 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5707 cifs_small_buf_release(pSMB);
5709 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5712 /* Note: On -EAGAIN error only caller can retry on handle based calls
5713 since file handle passed in no longer valid */
5719 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5720 bool delete_file, __u16 fid, __u32 pid_of_opener)
5722 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5725 __u16 params, param_offset, offset, byte_count, count;
5727 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5728 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5733 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5734 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5737 pSMB->MaxSetupCount = 0;
5741 pSMB->Reserved2 = 0;
5742 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5743 offset = param_offset + params;
5745 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5748 pSMB->MaxParameterCount = cpu_to_le16(2);
5749 /* BB find max SMB PDU from sess */
5750 pSMB->MaxDataCount = cpu_to_le16(1000);
5751 pSMB->SetupCount = 1;
5752 pSMB->Reserved3 = 0;
5753 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5754 byte_count = 3 /* pad */ + params + count;
5755 pSMB->DataCount = cpu_to_le16(count);
5756 pSMB->ParameterCount = cpu_to_le16(params);
5757 pSMB->TotalDataCount = pSMB->DataCount;
5758 pSMB->TotalParameterCount = pSMB->ParameterCount;
5759 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5760 pSMB->DataOffset = cpu_to_le16(offset);
5762 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5763 pSMB->Reserved4 = 0;
5764 inc_rfc1001_len(pSMB, byte_count);
5765 pSMB->ByteCount = cpu_to_le16(byte_count);
5766 *data_offset = delete_file ? 1 : 0;
5767 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5768 cifs_small_buf_release(pSMB);
5770 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5776 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5777 const char *fileName, const FILE_BASIC_INFO *data,
5778 const struct nls_table *nls_codepage, int remap)
5780 TRANSACTION2_SPI_REQ *pSMB = NULL;
5781 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5784 int bytes_returned = 0;
5786 __u16 params, param_offset, offset, byte_count, count;
5788 cifs_dbg(FYI, "In SetTimes\n");
5791 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5796 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5798 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5799 PATH_MAX, nls_codepage, remap);
5800 name_len++; /* trailing null */
5802 } else { /* BB improve the check for buffer overruns BB */
5803 name_len = strnlen(fileName, PATH_MAX);
5804 name_len++; /* trailing null */
5805 strncpy(pSMB->FileName, fileName, name_len);
5808 params = 6 + name_len;
5809 count = sizeof(FILE_BASIC_INFO);
5810 pSMB->MaxParameterCount = cpu_to_le16(2);
5811 /* BB find max SMB PDU from sess structure BB */
5812 pSMB->MaxDataCount = cpu_to_le16(1000);
5813 pSMB->MaxSetupCount = 0;
5817 pSMB->Reserved2 = 0;
5818 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5819 InformationLevel) - 4;
5820 offset = param_offset + params;
5821 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5822 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5823 pSMB->DataOffset = cpu_to_le16(offset);
5824 pSMB->SetupCount = 1;
5825 pSMB->Reserved3 = 0;
5826 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5827 byte_count = 3 /* pad */ + params + count;
5829 pSMB->DataCount = cpu_to_le16(count);
5830 pSMB->ParameterCount = cpu_to_le16(params);
5831 pSMB->TotalDataCount = pSMB->DataCount;
5832 pSMB->TotalParameterCount = pSMB->ParameterCount;
5833 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5834 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5836 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5837 pSMB->Reserved4 = 0;
5838 inc_rfc1001_len(pSMB, byte_count);
5839 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5840 pSMB->ByteCount = cpu_to_le16(byte_count);
5841 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5842 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5844 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5846 cifs_buf_release(pSMB);
5854 /* Can not be used to set time stamps yet (due to old DOS time format) */
5855 /* Can be used to set attributes */
5856 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5857 handling it anyway and NT4 was what we thought it would be needed for
5858 Do not delete it until we prove whether needed for Win9x though */
5860 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
5861 __u16 dos_attrs, const struct nls_table *nls_codepage)
5863 SETATTR_REQ *pSMB = NULL;
5864 SETATTR_RSP *pSMBr = NULL;
5869 cifs_dbg(FYI, "In SetAttrLegacy\n");
5872 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5877 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5879 ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
5880 PATH_MAX, nls_codepage);
5881 name_len++; /* trailing null */
5883 } else { /* BB improve the check for buffer overruns BB */
5884 name_len = strnlen(fileName, PATH_MAX);
5885 name_len++; /* trailing null */
5886 strncpy(pSMB->fileName, fileName, name_len);
5888 pSMB->attr = cpu_to_le16(dos_attrs);
5889 pSMB->BufferFormat = 0x04;
5890 inc_rfc1001_len(pSMB, name_len + 1);
5891 pSMB->ByteCount = cpu_to_le16(name_len + 1);
5892 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5893 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5895 cifs_dbg(FYI, "Error in LegacySetAttr = %d\n", rc);
5897 cifs_buf_release(pSMB);
5900 goto SetAttrLgcyRetry;
5904 #endif /* temporarily unneeded SetAttr legacy function */
5907 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5908 const struct cifs_unix_set_info_args *args)
5910 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5911 u64 mode = args->mode;
5913 if (uid_valid(args->uid))
5914 uid = from_kuid(&init_user_ns, args->uid);
5915 if (gid_valid(args->gid))
5916 gid = from_kgid(&init_user_ns, args->gid);
5919 * Samba server ignores set of file size to zero due to bugs in some
5920 * older clients, but we should be precise - we use SetFileSize to
5921 * set file size and do not want to truncate file size to zero
5922 * accidentally as happened on one Samba server beta by putting
5923 * zero instead of -1 here
5925 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5926 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5927 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5928 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5929 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5930 data_offset->Uid = cpu_to_le64(uid);
5931 data_offset->Gid = cpu_to_le64(gid);
5932 /* better to leave device as zero when it is */
5933 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5934 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5935 data_offset->Permissions = cpu_to_le64(mode);
5938 data_offset->Type = cpu_to_le32(UNIX_FILE);
5939 else if (S_ISDIR(mode))
5940 data_offset->Type = cpu_to_le32(UNIX_DIR);
5941 else if (S_ISLNK(mode))
5942 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5943 else if (S_ISCHR(mode))
5944 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5945 else if (S_ISBLK(mode))
5946 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5947 else if (S_ISFIFO(mode))
5948 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5949 else if (S_ISSOCK(mode))
5950 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5954 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5955 const struct cifs_unix_set_info_args *args,
5956 u16 fid, u32 pid_of_opener)
5958 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5961 u16 params, param_offset, offset, byte_count, count;
5963 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5964 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5969 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5970 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5973 pSMB->MaxSetupCount = 0;
5977 pSMB->Reserved2 = 0;
5978 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5979 offset = param_offset + params;
5981 data_offset = (char *)pSMB +
5982 offsetof(struct smb_hdr, Protocol) + offset;
5984 count = sizeof(FILE_UNIX_BASIC_INFO);
5986 pSMB->MaxParameterCount = cpu_to_le16(2);
5987 /* BB find max SMB PDU from sess */
5988 pSMB->MaxDataCount = cpu_to_le16(1000);
5989 pSMB->SetupCount = 1;
5990 pSMB->Reserved3 = 0;
5991 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5992 byte_count = 3 /* pad */ + params + count;
5993 pSMB->DataCount = cpu_to_le16(count);
5994 pSMB->ParameterCount = cpu_to_le16(params);
5995 pSMB->TotalDataCount = pSMB->DataCount;
5996 pSMB->TotalParameterCount = pSMB->ParameterCount;
5997 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5998 pSMB->DataOffset = cpu_to_le16(offset);
6000 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6001 pSMB->Reserved4 = 0;
6002 inc_rfc1001_len(pSMB, byte_count);
6003 pSMB->ByteCount = cpu_to_le16(byte_count);
6005 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
6007 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
6008 cifs_small_buf_release(pSMB);
6010 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
6013 /* Note: On -EAGAIN error only caller can retry on handle based calls
6014 since file handle passed in no longer valid */
6020 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
6021 const char *file_name,
6022 const struct cifs_unix_set_info_args *args,
6023 const struct nls_table *nls_codepage, int remap)
6025 TRANSACTION2_SPI_REQ *pSMB = NULL;
6026 TRANSACTION2_SPI_RSP *pSMBr = NULL;
6029 int bytes_returned = 0;
6030 FILE_UNIX_BASIC_INFO *data_offset;
6031 __u16 params, param_offset, offset, count, byte_count;
6033 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
6035 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6040 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6042 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6043 PATH_MAX, nls_codepage, remap);
6044 name_len++; /* trailing null */
6046 } else { /* BB improve the check for buffer overruns BB */
6047 name_len = strnlen(file_name, PATH_MAX);
6048 name_len++; /* trailing null */
6049 strncpy(pSMB->FileName, file_name, name_len);
6052 params = 6 + name_len;
6053 count = sizeof(FILE_UNIX_BASIC_INFO);
6054 pSMB->MaxParameterCount = cpu_to_le16(2);
6055 /* BB find max SMB PDU from sess structure BB */
6056 pSMB->MaxDataCount = cpu_to_le16(1000);
6057 pSMB->MaxSetupCount = 0;
6061 pSMB->Reserved2 = 0;
6062 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6063 InformationLevel) - 4;
6064 offset = param_offset + params;
6066 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
6068 memset(data_offset, 0, count);
6069 pSMB->DataOffset = cpu_to_le16(offset);
6070 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6071 pSMB->SetupCount = 1;
6072 pSMB->Reserved3 = 0;
6073 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6074 byte_count = 3 /* pad */ + params + count;
6075 pSMB->ParameterCount = cpu_to_le16(params);
6076 pSMB->DataCount = cpu_to_le16(count);
6077 pSMB->TotalParameterCount = pSMB->ParameterCount;
6078 pSMB->TotalDataCount = pSMB->DataCount;
6079 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6080 pSMB->Reserved4 = 0;
6081 inc_rfc1001_len(pSMB, byte_count);
6083 cifs_fill_unix_set_info(data_offset, args);
6085 pSMB->ByteCount = cpu_to_le16(byte_count);
6086 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6087 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6089 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6091 cifs_buf_release(pSMB);
6097 #ifdef CONFIG_CIFS_XATTR
6099 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6100 * function used by listxattr and getxattr type calls. When ea_name is set,
6101 * it looks for that attribute name and stuffs that value into the EAData
6102 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6103 * buffer. In both cases, the return value is either the length of the
6104 * resulting data or a negative error code. If EAData is a NULL pointer then
6105 * the data isn't copied to it, but the length is returned.
6108 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6109 const unsigned char *searchName, const unsigned char *ea_name,
6110 char *EAData, size_t buf_size,
6111 struct cifs_sb_info *cifs_sb)
6113 /* BB assumes one setup word */
6114 TRANSACTION2_QPI_REQ *pSMB = NULL;
6115 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6116 int remap = cifs_remap(cifs_sb);
6117 struct nls_table *nls_codepage = cifs_sb->local_nls;
6121 struct fealist *ea_response_data;
6122 struct fea *temp_fea;
6125 __u16 params, byte_count, data_offset;
6126 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6128 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6130 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6135 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6137 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6138 PATH_MAX, nls_codepage, remap);
6139 list_len++; /* trailing null */
6141 } else { /* BB improve the check for buffer overruns BB */
6142 list_len = strnlen(searchName, PATH_MAX);
6143 list_len++; /* trailing null */
6144 strncpy(pSMB->FileName, searchName, list_len);
6147 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6148 pSMB->TotalDataCount = 0;
6149 pSMB->MaxParameterCount = cpu_to_le16(2);
6150 /* BB find exact max SMB PDU from sess structure BB */
6151 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6152 pSMB->MaxSetupCount = 0;
6156 pSMB->Reserved2 = 0;
6157 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6158 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6159 pSMB->DataCount = 0;
6160 pSMB->DataOffset = 0;
6161 pSMB->SetupCount = 1;
6162 pSMB->Reserved3 = 0;
6163 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6164 byte_count = params + 1 /* pad */ ;
6165 pSMB->TotalParameterCount = cpu_to_le16(params);
6166 pSMB->ParameterCount = pSMB->TotalParameterCount;
6167 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6168 pSMB->Reserved4 = 0;
6169 inc_rfc1001_len(pSMB, byte_count);
6170 pSMB->ByteCount = cpu_to_le16(byte_count);
6172 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6173 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6175 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6180 /* BB also check enough total bytes returned */
6181 /* BB we need to improve the validity checking
6182 of these trans2 responses */
6184 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6185 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6186 rc = -EIO; /* bad smb */
6190 /* check that length of list is not more than bcc */
6191 /* check that each entry does not go beyond length
6193 /* check that each element of each entry does not
6194 go beyond end of list */
6195 /* validate_trans2_offsets() */
6196 /* BB check if start of smb + data_offset > &bcc+ bcc */
6198 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6199 ea_response_data = (struct fealist *)
6200 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6202 list_len = le32_to_cpu(ea_response_data->list_len);
6203 cifs_dbg(FYI, "ea length %d\n", list_len);
6204 if (list_len <= 8) {
6205 cifs_dbg(FYI, "empty EA list returned from server\n");
6206 /* didn't find the named attribute */
6212 /* make sure list_len doesn't go past end of SMB */
6213 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6214 if ((char *)ea_response_data + list_len > end_of_smb) {
6215 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6220 /* account for ea list len */
6222 temp_fea = ea_response_data->list;
6223 temp_ptr = (char *)temp_fea;
6224 while (list_len > 0) {
6225 unsigned int name_len;
6230 /* make sure we can read name_len and value_len */
6232 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6237 name_len = temp_fea->name_len;
6238 value_len = le16_to_cpu(temp_fea->value_len);
6239 list_len -= name_len + 1 + value_len;
6241 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6247 if (ea_name_len == name_len &&
6248 memcmp(ea_name, temp_ptr, name_len) == 0) {
6249 temp_ptr += name_len + 1;
6253 if ((size_t)value_len > buf_size) {
6257 memcpy(EAData, temp_ptr, value_len);
6261 /* account for prefix user. and trailing null */
6262 rc += (5 + 1 + name_len);
6263 if (rc < (int) buf_size) {
6264 memcpy(EAData, "user.", 5);
6266 memcpy(EAData, temp_ptr, name_len);
6268 /* null terminate name */
6271 } else if (buf_size == 0) {
6272 /* skip copy - calc size only */
6274 /* stop before overrun buffer */
6279 temp_ptr += name_len + 1 + value_len;
6280 temp_fea = (struct fea *)temp_ptr;
6283 /* didn't find the named attribute */
6288 cifs_buf_release(pSMB);
6296 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6297 const char *fileName, const char *ea_name, const void *ea_value,
6298 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6299 struct cifs_sb_info *cifs_sb)
6301 struct smb_com_transaction2_spi_req *pSMB = NULL;
6302 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6303 struct fealist *parm_data;
6306 int bytes_returned = 0;
6307 __u16 params, param_offset, byte_count, offset, count;
6308 int remap = cifs_remap(cifs_sb);
6310 cifs_dbg(FYI, "In SetEA\n");
6312 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6317 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6319 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6320 PATH_MAX, nls_codepage, remap);
6321 name_len++; /* trailing null */
6323 } else { /* BB improve the check for buffer overruns BB */
6324 name_len = strnlen(fileName, PATH_MAX);
6325 name_len++; /* trailing null */
6326 strncpy(pSMB->FileName, fileName, name_len);
6329 params = 6 + name_len;
6331 /* done calculating parms using name_len of file name,
6332 now use name_len to calculate length of ea name
6333 we are going to create in the inode xattrs */
6334 if (ea_name == NULL)
6337 name_len = strnlen(ea_name, 255);
6339 count = sizeof(*parm_data) + ea_value_len + name_len;
6340 pSMB->MaxParameterCount = cpu_to_le16(2);
6341 /* BB find max SMB PDU from sess */
6342 pSMB->MaxDataCount = cpu_to_le16(1000);
6343 pSMB->MaxSetupCount = 0;
6347 pSMB->Reserved2 = 0;
6348 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6349 InformationLevel) - 4;
6350 offset = param_offset + params;
6351 pSMB->InformationLevel =
6352 cpu_to_le16(SMB_SET_FILE_EA);
6354 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6355 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6356 pSMB->DataOffset = cpu_to_le16(offset);
6357 pSMB->SetupCount = 1;
6358 pSMB->Reserved3 = 0;
6359 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6360 byte_count = 3 /* pad */ + params + count;
6361 pSMB->DataCount = cpu_to_le16(count);
6362 parm_data->list_len = cpu_to_le32(count);
6363 parm_data->list[0].EA_flags = 0;
6364 /* we checked above that name len is less than 255 */
6365 parm_data->list[0].name_len = (__u8)name_len;
6366 /* EA names are always ASCII */
6368 strncpy(parm_data->list[0].name, ea_name, name_len);
6369 parm_data->list[0].name[name_len] = 0;
6370 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6371 /* caller ensures that ea_value_len is less than 64K but
6372 we need to ensure that it fits within the smb */
6374 /*BB add length check to see if it would fit in
6375 negotiated SMB buffer size BB */
6376 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6378 memcpy(parm_data->list[0].name+name_len+1,
6379 ea_value, ea_value_len);
6381 pSMB->TotalDataCount = pSMB->DataCount;
6382 pSMB->ParameterCount = cpu_to_le16(params);
6383 pSMB->TotalParameterCount = pSMB->ParameterCount;
6384 pSMB->Reserved4 = 0;
6385 inc_rfc1001_len(pSMB, byte_count);
6386 pSMB->ByteCount = cpu_to_le16(byte_count);
6387 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6388 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6390 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6392 cifs_buf_release(pSMB);
6401 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6403 * Years ago the kernel added a "dnotify" function for Samba server,
6404 * to allow network clients (such as Windows) to display updated
6405 * lists of files in directory listings automatically when
6406 * files are added by one user when another user has the
6407 * same directory open on their desktop. The Linux cifs kernel
6408 * client hooked into the kernel side of this interface for
6409 * the same reason, but ironically when the VFS moved from
6410 * "dnotify" to "inotify" it became harder to plug in Linux
6411 * network file system clients (the most obvious use case
6412 * for notify interfaces is when multiple users can update
6413 * the contents of the same directory - exactly what network
6414 * file systems can do) although the server (Samba) could
6415 * still use it. For the short term we leave the worker
6416 * function ifdeffed out (below) until inotify is fixed
6417 * in the VFS to make it easier to plug in network file
6418 * system clients. If inotify turns out to be permanently
6419 * incompatible for network fs clients, we could instead simply
6420 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6422 int CIFSSMBNotify(const unsigned int xid, struct cifs_tcon *tcon,
6423 const int notify_subdirs, const __u16 netfid,
6424 __u32 filter, struct file *pfile, int multishot,
6425 const struct nls_table *nls_codepage)
6428 struct smb_com_transaction_change_notify_req *pSMB = NULL;
6429 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6430 struct dir_notify_req *dnotify_req;
6433 cifs_dbg(FYI, "In CIFSSMBNotify for file handle %d\n", (int)netfid);
6434 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6439 pSMB->TotalParameterCount = 0 ;
6440 pSMB->TotalDataCount = 0;
6441 pSMB->MaxParameterCount = cpu_to_le32(2);
6442 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6443 pSMB->MaxSetupCount = 4;
6445 pSMB->ParameterOffset = 0;
6446 pSMB->DataCount = 0;
6447 pSMB->DataOffset = 0;
6448 pSMB->SetupCount = 4; /* single byte does not need le conversion */
6449 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6450 pSMB->ParameterCount = pSMB->TotalParameterCount;
6452 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6453 pSMB->Reserved2 = 0;
6454 pSMB->CompletionFilter = cpu_to_le32(filter);
6455 pSMB->Fid = netfid; /* file handle always le */
6456 pSMB->ByteCount = 0;
6458 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6459 (struct smb_hdr *)pSMBr, &bytes_returned,
6462 cifs_dbg(FYI, "Error in Notify = %d\n", rc);
6464 /* Add file to outstanding requests */
6465 /* BB change to kmem cache alloc */
6466 dnotify_req = kmalloc(
6467 sizeof(struct dir_notify_req),
6470 dnotify_req->Pid = pSMB->hdr.Pid;
6471 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6472 dnotify_req->Mid = pSMB->hdr.Mid;
6473 dnotify_req->Tid = pSMB->hdr.Tid;
6474 dnotify_req->Uid = pSMB->hdr.Uid;
6475 dnotify_req->netfid = netfid;
6476 dnotify_req->pfile = pfile;
6477 dnotify_req->filter = filter;
6478 dnotify_req->multishot = multishot;
6479 spin_lock(&GlobalMid_Lock);
6480 list_add_tail(&dnotify_req->lhead,
6481 &GlobalDnotifyReqList);
6482 spin_unlock(&GlobalMid_Lock);
6486 cifs_buf_release(pSMB);
6489 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */