1 // SPDX-License-Identifier: LGPL-2.1
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
11 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
12 /* These are mostly routines that operate on a pathname, or on a tree id */
13 /* (mounted volume), but there are eight handle based routines which must be */
14 /* treated slightly differently for reconnection purposes since we never */
15 /* want to reuse a stale file handle and only the caller knows the file info */
18 #include <linux/kernel.h>
19 #include <linux/vfs.h>
20 #include <linux/slab.h>
21 #include <linux/posix_acl_xattr.h>
22 #include <linux/pagemap.h>
23 #include <linux/swap.h>
24 #include <linux/task_io_accounting_ops.h>
25 #include <linux/uaccess.h>
29 #include "cifsproto.h"
30 #include "cifs_unicode.h"
31 #include "cifs_debug.h"
32 #include "smb2proto.h"
34 #include "smbdirect.h"
35 #ifdef CONFIG_CIFS_DFS_UPCALL
36 #include "dfs_cache.h"
39 #ifdef CONFIG_CIFS_POSIX
44 {CIFS_PROT, "\2NT LM 0.12"},
45 {POSIX_PROT, "\2POSIX 2"},
53 {CIFS_PROT, "\2NT LM 0.12"},
58 /* define the number of elements in the cifs dialect array */
59 #ifdef CONFIG_CIFS_POSIX
60 #define CIFS_NUM_PROT 2
62 #define CIFS_NUM_PROT 1
63 #endif /* CIFS_POSIX */
66 * Mark as invalid, all open files on tree connections since they
67 * were closed when session to server was lost.
70 cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
72 struct cifsFileInfo *open_file = NULL;
73 struct list_head *tmp;
74 struct list_head *tmp1;
76 /* only send once per connect */
77 spin_lock(&cifs_tcp_ses_lock);
78 if ((tcon->ses->ses_status != SES_GOOD) || (tcon->status != TID_NEED_RECON)) {
79 spin_unlock(&cifs_tcp_ses_lock);
82 tcon->status = TID_IN_FILES_INVALIDATE;
83 spin_unlock(&cifs_tcp_ses_lock);
85 /* list all files open on tree connection and mark them invalid */
86 spin_lock(&tcon->open_file_lock);
87 list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
88 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
89 open_file->invalidHandle = true;
90 open_file->oplock_break_cancelled = true;
92 spin_unlock(&tcon->open_file_lock);
94 mutex_lock(&tcon->crfid.fid_mutex);
95 tcon->crfid.is_valid = false;
96 /* cached handle is not valid, so SMB2_CLOSE won't be sent below */
97 close_cached_dir_lease_locked(&tcon->crfid);
98 memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
99 mutex_unlock(&tcon->crfid.fid_mutex);
101 spin_lock(&cifs_tcp_ses_lock);
102 if (tcon->status == TID_IN_FILES_INVALIDATE)
103 tcon->status = TID_NEED_TCON;
104 spin_unlock(&cifs_tcp_ses_lock);
107 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
112 /* reconnect the socket, tcon, and smb session if needed */
114 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
117 struct cifs_ses *ses;
118 struct TCP_Server_Info *server;
119 struct nls_table *nls_codepage;
123 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
124 * tcp and smb session status done differently for those three - in the
131 server = ses->server;
134 * only tree disconnect, open, and write, (and ulogoff which does not
135 * have tcon) are allowed as we start force umount
137 spin_lock(&cifs_tcp_ses_lock);
138 if (tcon->status == TID_EXITING) {
139 if (smb_command != SMB_COM_WRITE_ANDX &&
140 smb_command != SMB_COM_OPEN_ANDX &&
141 smb_command != SMB_COM_TREE_DISCONNECT) {
142 spin_unlock(&cifs_tcp_ses_lock);
143 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
148 spin_unlock(&cifs_tcp_ses_lock);
150 retries = server->nr_targets;
153 * Give demultiplex thread up to 10 seconds to each target available for
154 * reconnect -- should be greater than cifs socket timeout which is 7
157 while (server->tcpStatus == CifsNeedReconnect) {
158 rc = wait_event_interruptible_timeout(server->response_q,
159 (server->tcpStatus != CifsNeedReconnect),
162 cifs_dbg(FYI, "%s: aborting reconnect due to a received signal by the process\n",
167 /* are we still trying to reconnect? */
168 spin_lock(&cifs_tcp_ses_lock);
169 if (server->tcpStatus != CifsNeedReconnect) {
170 spin_unlock(&cifs_tcp_ses_lock);
173 spin_unlock(&cifs_tcp_ses_lock);
175 if (retries && --retries)
179 * on "soft" mounts we wait once. Hard mounts keep
180 * retrying until process is killed or server comes
184 cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
187 retries = server->nr_targets;
190 spin_lock(&ses->chan_lock);
191 if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) {
192 spin_unlock(&ses->chan_lock);
195 spin_unlock(&ses->chan_lock);
197 nls_codepage = load_nls_default();
200 * Recheck after acquire mutex. If another thread is negotiating
201 * and the server never sends an answer the socket will be closed
202 * and tcpStatus set to reconnect.
204 spin_lock(&cifs_tcp_ses_lock);
205 if (server->tcpStatus == CifsNeedReconnect) {
206 spin_unlock(&cifs_tcp_ses_lock);
210 spin_unlock(&cifs_tcp_ses_lock);
213 * need to prevent multiple threads trying to simultaneously
214 * reconnect the same SMB session
216 spin_lock(&ses->chan_lock);
217 if (!cifs_chan_needs_reconnect(ses, server)) {
218 spin_unlock(&ses->chan_lock);
220 /* this means that we only need to tree connect */
221 if (tcon->need_reconnect)
222 goto skip_sess_setup;
227 spin_unlock(&ses->chan_lock);
229 mutex_lock(&ses->session_mutex);
230 rc = cifs_negotiate_protocol(0, ses, server);
232 rc = cifs_setup_session(0, ses, server, nls_codepage);
234 /* do we need to reconnect tcon? */
235 if (rc || !tcon->need_reconnect) {
236 mutex_unlock(&ses->session_mutex);
241 cifs_mark_open_files_invalid(tcon);
242 rc = cifs_tree_connect(0, tcon, nls_codepage);
243 mutex_unlock(&ses->session_mutex);
244 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
247 pr_warn_once("reconnect tcon failed rc = %d\n", rc);
251 atomic_inc(&tconInfoReconnectCount);
253 /* tell server Unix caps we support */
255 reset_cifs_unix_caps(0, tcon, NULL, NULL);
258 * Removed call to reopen open files here. It is safer (and faster) to
259 * reopen files one at a time as needed in read and write.
261 * FIXME: what about file locks? don't we need to reclaim them ASAP?
266 * Check if handle based operation so we know whether we can continue
267 * or not without returning to caller to reset file handle
269 switch (smb_command) {
270 case SMB_COM_READ_ANDX:
271 case SMB_COM_WRITE_ANDX:
273 case SMB_COM_FIND_CLOSE2:
274 case SMB_COM_LOCKING_ANDX:
278 unload_nls(nls_codepage);
282 /* Allocate and return pointer to an SMB request buffer, and set basic
283 SMB information in the SMB header. If the return code is zero, this
284 function must have filled in request_buf pointer */
286 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
291 rc = cifs_reconnect_tcon(tcon, smb_command);
295 *request_buf = cifs_small_buf_get();
296 if (*request_buf == NULL) {
297 /* BB should we add a retry in here if not a writepage? */
301 header_assemble((struct smb_hdr *) *request_buf, smb_command,
305 cifs_stats_inc(&tcon->num_smbs_sent);
311 small_smb_init_no_tc(const int smb_command, const int wct,
312 struct cifs_ses *ses, void **request_buf)
315 struct smb_hdr *buffer;
317 rc = small_smb_init(smb_command, wct, NULL, request_buf);
321 buffer = (struct smb_hdr *)*request_buf;
322 buffer->Mid = get_next_mid(ses->server);
323 if (ses->capabilities & CAP_UNICODE)
324 buffer->Flags2 |= SMBFLG2_UNICODE;
325 if (ses->capabilities & CAP_STATUS32)
326 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
328 /* uid, tid can stay at zero as set in header assemble */
330 /* BB add support for turning on the signing when
331 this function is used after 1st of session setup requests */
336 /* If the return code is zero, this function must fill in request_buf pointer */
338 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
339 void **request_buf, void **response_buf)
341 *request_buf = cifs_buf_get();
342 if (*request_buf == NULL) {
343 /* BB should we add a retry in here if not a writepage? */
346 /* Although the original thought was we needed the response buf for */
347 /* potential retries of smb operations it turns out we can determine */
348 /* from the mid flags when the request buffer can be resent without */
349 /* having to use a second distinct buffer for the response */
351 *response_buf = *request_buf;
353 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
357 cifs_stats_inc(&tcon->num_smbs_sent);
362 /* If the return code is zero, this function must fill in request_buf pointer */
364 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
365 void **request_buf, void **response_buf)
369 rc = cifs_reconnect_tcon(tcon, smb_command);
373 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
377 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
378 void **request_buf, void **response_buf)
380 spin_lock(&tcon->ses->chan_lock);
381 if (cifs_chan_needs_reconnect(tcon->ses, tcon->ses->server) ||
382 tcon->need_reconnect) {
383 spin_unlock(&tcon->ses->chan_lock);
386 spin_unlock(&tcon->ses->chan_lock);
388 return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
391 static int validate_t2(struct smb_t2_rsp *pSMB)
393 unsigned int total_size;
395 /* check for plausible wct */
396 if (pSMB->hdr.WordCount < 10)
399 /* check for parm and data offset going beyond end of smb */
400 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
401 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
404 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
405 if (total_size >= 512)
408 /* check that bcc is at least as big as parms + data, and that it is
409 * less than negotiated smb buffer
411 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
412 if (total_size > get_bcc(&pSMB->hdr) ||
413 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
418 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
419 sizeof(struct smb_t2_rsp) + 16);
424 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
428 char *guid = pSMBr->u.extended_response.GUID;
429 struct TCP_Server_Info *server = ses->server;
431 count = get_bcc(&pSMBr->hdr);
432 if (count < SMB1_CLIENT_GUID_SIZE)
435 spin_lock(&cifs_tcp_ses_lock);
436 if (server->srv_count > 1) {
437 spin_unlock(&cifs_tcp_ses_lock);
438 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
439 cifs_dbg(FYI, "server UID changed\n");
440 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
443 spin_unlock(&cifs_tcp_ses_lock);
444 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
447 if (count == SMB1_CLIENT_GUID_SIZE) {
448 server->sec_ntlmssp = true;
450 count -= SMB1_CLIENT_GUID_SIZE;
451 rc = decode_negTokenInit(
452 pSMBr->u.extended_response.SecurityBlob, count, server);
461 cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
463 bool srv_sign_required = server->sec_mode & server->vals->signing_required;
464 bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
465 bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
468 * Is signing required by mnt options? If not then check
469 * global_secflags to see if it is there.
471 if (!mnt_sign_required)
472 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
476 * If signing is required then it's automatically enabled too,
477 * otherwise, check to see if the secflags allow it.
479 mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
480 (global_secflags & CIFSSEC_MAY_SIGN);
482 /* If server requires signing, does client allow it? */
483 if (srv_sign_required) {
484 if (!mnt_sign_enabled) {
485 cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!\n");
491 /* If client requires signing, does server allow it? */
492 if (mnt_sign_required) {
493 if (!srv_sign_enabled) {
494 cifs_dbg(VFS, "Server does not support signing!\n");
500 if (cifs_rdma_enabled(server) && server->sign)
501 cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled\n");
507 should_set_ext_sec_flag(enum securityEnum sectype)
514 if (global_secflags &
515 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
524 CIFSSMBNegotiate(const unsigned int xid,
525 struct cifs_ses *ses,
526 struct TCP_Server_Info *server)
529 NEGOTIATE_RSP *pSMBr;
536 WARN(1, "%s: server is NULL!\n", __func__);
540 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
541 (void **) &pSMB, (void **) &pSMBr);
545 pSMB->hdr.Mid = get_next_mid(server);
546 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
548 if (should_set_ext_sec_flag(ses->sectype)) {
549 cifs_dbg(FYI, "Requesting extended security\n");
550 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
555 * We know that all the name entries in the protocols array
556 * are short (< 16 bytes anyway) and are NUL terminated.
558 for (i = 0; i < CIFS_NUM_PROT; i++) {
559 size_t len = strlen(protocols[i].name) + 1;
561 memcpy(pSMB->DialectsArray+count, protocols[i].name, len);
564 inc_rfc1001_len(pSMB, count);
565 pSMB->ByteCount = cpu_to_le16(count);
567 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
568 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
572 server->dialect = le16_to_cpu(pSMBr->DialectIndex);
573 cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
574 /* Check wct = 1 error case */
575 if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) {
576 /* core returns wct = 1, but we do not ask for core - otherwise
577 small wct just comes when dialect index is -1 indicating we
578 could not negotiate a common dialect */
581 } else if (pSMBr->hdr.WordCount != 17) {
586 /* else wct == 17, NTLM or better */
588 server->sec_mode = pSMBr->SecurityMode;
589 if ((server->sec_mode & SECMODE_USER) == 0)
590 cifs_dbg(FYI, "share mode security\n");
592 /* one byte, so no need to convert this or EncryptionKeyLen from
594 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
596 set_credits(server, server->maxReq);
597 /* probably no need to store and check maxvcs */
598 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
599 /* set up max_read for readahead check */
600 server->max_read = server->maxBuf;
601 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
602 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
603 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
604 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
605 server->timeAdj *= 60;
607 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
608 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
609 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
610 CIFS_CRYPTO_KEY_SIZE);
611 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
612 server->capabilities & CAP_EXTENDED_SECURITY) {
613 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
614 rc = decode_ext_sec_blob(ses, pSMBr);
615 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
616 rc = -EIO; /* no crypt key only if plain text pwd */
618 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
619 server->capabilities &= ~CAP_EXTENDED_SECURITY;
623 rc = cifs_enable_signing(server, ses->sign);
625 cifs_buf_release(pSMB);
627 cifs_dbg(FYI, "negprot rc %d\n", rc);
632 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
634 struct smb_hdr *smb_buffer;
637 cifs_dbg(FYI, "In tree disconnect\n");
639 /* BB: do we need to check this? These should never be NULL. */
640 if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
644 * No need to return error on this operation if tid invalidated and
645 * closed on server already e.g. due to tcp session crashing. Also,
646 * the tcon is no longer on the list, so no need to take lock before
649 spin_lock(&tcon->ses->chan_lock);
650 if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {
651 spin_unlock(&tcon->ses->chan_lock);
654 spin_unlock(&tcon->ses->chan_lock);
656 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
657 (void **)&smb_buffer);
661 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
662 cifs_small_buf_release(smb_buffer);
664 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
666 /* No need to return error on this operation if tid invalidated and
667 closed on server already e.g. due to tcp session crashing */
675 * This is a no-op for now. We're not really interested in the reply, but
676 * rather in the fact that the server sent one and that server->lstrp
679 * FIXME: maybe we should consider checking that the reply matches request?
682 cifs_echo_callback(struct mid_q_entry *mid)
684 struct TCP_Server_Info *server = mid->callback_data;
685 struct cifs_credits credits = { .value = 1, .instance = 0 };
687 DeleteMidQEntry(mid);
688 add_credits(server, &credits, CIFS_ECHO_OP);
692 CIFSSMBEcho(struct TCP_Server_Info *server)
697 struct smb_rqst rqst = { .rq_iov = iov,
700 cifs_dbg(FYI, "In echo request\n");
702 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
706 if (server->capabilities & CAP_UNICODE)
707 smb->hdr.Flags2 |= SMBFLG2_UNICODE;
709 /* set up echo request */
710 smb->hdr.Tid = 0xffff;
711 smb->hdr.WordCount = 1;
712 put_unaligned_le16(1, &smb->EchoCount);
713 put_bcc(1, &smb->hdr);
715 inc_rfc1001_len(smb, 3);
718 iov[0].iov_base = smb;
719 iov[1].iov_len = get_rfc1002_length(smb);
720 iov[1].iov_base = (char *)smb + 4;
722 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
723 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
725 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
727 cifs_small_buf_release(smb);
733 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
735 LOGOFF_ANDX_REQ *pSMB;
738 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
741 * BB: do we need to check validity of ses and server? They should
742 * always be valid since we have an active reference. If not, that
743 * should probably be a BUG()
745 if (!ses || !ses->server)
748 mutex_lock(&ses->session_mutex);
749 spin_lock(&ses->chan_lock);
750 if (CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
751 spin_unlock(&ses->chan_lock);
752 goto session_already_dead; /* no need to send SMBlogoff if uid
753 already closed due to reconnect */
755 spin_unlock(&ses->chan_lock);
757 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
759 mutex_unlock(&ses->session_mutex);
763 pSMB->hdr.Mid = get_next_mid(ses->server);
765 if (ses->server->sign)
766 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
768 pSMB->hdr.Uid = ses->Suid;
770 pSMB->AndXCommand = 0xFF;
771 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
772 cifs_small_buf_release(pSMB);
773 session_already_dead:
774 mutex_unlock(&ses->session_mutex);
776 /* if session dead then we do not need to do ulogoff,
777 since server closed smb session, no sense reporting
785 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
786 const char *fileName, __u16 type,
787 const struct nls_table *nls_codepage, int remap)
789 TRANSACTION2_SPI_REQ *pSMB = NULL;
790 TRANSACTION2_SPI_RSP *pSMBr = NULL;
791 struct unlink_psx_rq *pRqD;
794 int bytes_returned = 0;
795 __u16 params, param_offset, offset, byte_count;
797 cifs_dbg(FYI, "In POSIX delete\n");
799 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
804 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
806 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
807 PATH_MAX, nls_codepage, remap);
808 name_len++; /* trailing null */
811 name_len = copy_path_name(pSMB->FileName, fileName);
814 params = 6 + name_len;
815 pSMB->MaxParameterCount = cpu_to_le16(2);
816 pSMB->MaxDataCount = 0; /* BB double check this with jra */
817 pSMB->MaxSetupCount = 0;
822 param_offset = offsetof(struct smb_com_transaction2_spi_req,
823 InformationLevel) - 4;
824 offset = param_offset + params;
826 /* Setup pointer to Request Data (inode type).
827 * Note that SMB offsets are from the beginning of SMB which is 4 bytes
828 * in, after RFC1001 field
830 pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4);
831 pRqD->type = cpu_to_le16(type);
832 pSMB->ParameterOffset = cpu_to_le16(param_offset);
833 pSMB->DataOffset = cpu_to_le16(offset);
834 pSMB->SetupCount = 1;
836 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
837 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
839 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
840 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
841 pSMB->ParameterCount = cpu_to_le16(params);
842 pSMB->TotalParameterCount = pSMB->ParameterCount;
843 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
845 inc_rfc1001_len(pSMB, byte_count);
846 pSMB->ByteCount = cpu_to_le16(byte_count);
847 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
848 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
850 cifs_dbg(FYI, "Posix delete returned %d\n", rc);
851 cifs_buf_release(pSMB);
853 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
862 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
863 struct cifs_sb_info *cifs_sb)
865 DELETE_FILE_REQ *pSMB = NULL;
866 DELETE_FILE_RSP *pSMBr = NULL;
870 int remap = cifs_remap(cifs_sb);
873 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
878 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
879 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
880 PATH_MAX, cifs_sb->local_nls,
882 name_len++; /* trailing null */
885 name_len = copy_path_name(pSMB->fileName, name);
887 pSMB->SearchAttributes =
888 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
889 pSMB->BufferFormat = 0x04;
890 inc_rfc1001_len(pSMB, name_len + 1);
891 pSMB->ByteCount = cpu_to_le16(name_len + 1);
892 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
893 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
894 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
896 cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
898 cifs_buf_release(pSMB);
906 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
907 struct cifs_sb_info *cifs_sb)
909 DELETE_DIRECTORY_REQ *pSMB = NULL;
910 DELETE_DIRECTORY_RSP *pSMBr = NULL;
914 int remap = cifs_remap(cifs_sb);
916 cifs_dbg(FYI, "In CIFSSMBRmDir\n");
918 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
923 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
924 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
925 PATH_MAX, cifs_sb->local_nls,
927 name_len++; /* trailing null */
930 name_len = copy_path_name(pSMB->DirName, name);
933 pSMB->BufferFormat = 0x04;
934 inc_rfc1001_len(pSMB, name_len + 1);
935 pSMB->ByteCount = cpu_to_le16(name_len + 1);
936 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
937 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
938 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
940 cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
942 cifs_buf_release(pSMB);
949 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
950 struct cifs_tcon *tcon, const char *name,
951 struct cifs_sb_info *cifs_sb)
954 CREATE_DIRECTORY_REQ *pSMB = NULL;
955 CREATE_DIRECTORY_RSP *pSMBr = NULL;
958 int remap = cifs_remap(cifs_sb);
960 cifs_dbg(FYI, "In CIFSSMBMkDir\n");
962 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
967 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
968 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
969 PATH_MAX, cifs_sb->local_nls,
971 name_len++; /* trailing null */
974 name_len = copy_path_name(pSMB->DirName, name);
977 pSMB->BufferFormat = 0x04;
978 inc_rfc1001_len(pSMB, name_len + 1);
979 pSMB->ByteCount = cpu_to_le16(name_len + 1);
980 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
981 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
982 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
984 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
986 cifs_buf_release(pSMB);
993 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
994 __u32 posix_flags, __u64 mode, __u16 *netfid,
995 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
996 const char *name, const struct nls_table *nls_codepage,
999 TRANSACTION2_SPI_REQ *pSMB = NULL;
1000 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1003 int bytes_returned = 0;
1004 __u16 params, param_offset, offset, byte_count, count;
1005 OPEN_PSX_REQ *pdata;
1006 OPEN_PSX_RSP *psx_rsp;
1008 cifs_dbg(FYI, "In POSIX Create\n");
1010 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1015 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1017 cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1018 PATH_MAX, nls_codepage, remap);
1019 name_len++; /* trailing null */
1022 name_len = copy_path_name(pSMB->FileName, name);
1025 params = 6 + name_len;
1026 count = sizeof(OPEN_PSX_REQ);
1027 pSMB->MaxParameterCount = cpu_to_le16(2);
1028 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1029 pSMB->MaxSetupCount = 0;
1033 pSMB->Reserved2 = 0;
1034 param_offset = offsetof(struct smb_com_transaction2_spi_req,
1035 InformationLevel) - 4;
1036 offset = param_offset + params;
1037 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
1038 pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4);
1039 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1040 pdata->Permissions = cpu_to_le64(mode);
1041 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1042 pdata->OpenFlags = cpu_to_le32(*pOplock);
1043 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1044 pSMB->DataOffset = cpu_to_le16(offset);
1045 pSMB->SetupCount = 1;
1046 pSMB->Reserved3 = 0;
1047 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1048 byte_count = 3 /* pad */ + params + count;
1050 pSMB->DataCount = cpu_to_le16(count);
1051 pSMB->ParameterCount = cpu_to_le16(params);
1052 pSMB->TotalDataCount = pSMB->DataCount;
1053 pSMB->TotalParameterCount = pSMB->ParameterCount;
1054 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1055 pSMB->Reserved4 = 0;
1056 inc_rfc1001_len(pSMB, byte_count);
1057 pSMB->ByteCount = cpu_to_le16(byte_count);
1058 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1059 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1061 cifs_dbg(FYI, "Posix create returned %d\n", rc);
1062 goto psx_create_err;
1065 cifs_dbg(FYI, "copying inode info\n");
1066 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1068 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1069 rc = -EIO; /* bad smb */
1070 goto psx_create_err;
1073 /* copy return information to pRetData */
1074 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1075 + le16_to_cpu(pSMBr->t2.DataOffset));
1077 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1079 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1080 /* Let caller know file was created so we can set the mode. */
1081 /* Do we care about the CreateAction in any other cases? */
1082 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1083 *pOplock |= CIFS_CREATE_ACTION;
1084 /* check to make sure response data is there */
1085 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1086 pRetData->Type = cpu_to_le32(-1); /* unknown */
1087 cifs_dbg(NOISY, "unknown type\n");
1089 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1090 + sizeof(FILE_UNIX_BASIC_INFO)) {
1091 cifs_dbg(VFS, "Open response data too small\n");
1092 pRetData->Type = cpu_to_le32(-1);
1093 goto psx_create_err;
1095 memcpy((char *) pRetData,
1096 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1097 sizeof(FILE_UNIX_BASIC_INFO));
1101 cifs_buf_release(pSMB);
1103 if (posix_flags & SMB_O_DIRECTORY)
1104 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1106 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1114 static __u16 convert_disposition(int disposition)
1118 switch (disposition) {
1119 case FILE_SUPERSEDE:
1120 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1123 ofun = SMBOPEN_OAPPEND;
1126 ofun = SMBOPEN_OCREATE;
1129 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1131 case FILE_OVERWRITE:
1132 ofun = SMBOPEN_OTRUNC;
1134 case FILE_OVERWRITE_IF:
1135 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1138 cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1139 ofun = SMBOPEN_OAPPEND; /* regular open */
1145 access_flags_to_smbopen_mode(const int access_flags)
1147 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1149 if (masked_flags == GENERIC_READ)
1150 return SMBOPEN_READ;
1151 else if (masked_flags == GENERIC_WRITE)
1152 return SMBOPEN_WRITE;
1154 /* just go for read/write */
1155 return SMBOPEN_READWRITE;
1159 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1160 const char *fileName, const int openDisposition,
1161 const int access_flags, const int create_options, __u16 *netfid,
1162 int *pOplock, FILE_ALL_INFO *pfile_info,
1163 const struct nls_table *nls_codepage, int remap)
1166 OPENX_REQ *pSMB = NULL;
1167 OPENX_RSP *pSMBr = NULL;
1173 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1178 pSMB->AndXCommand = 0xFF; /* none */
1180 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1181 count = 1; /* account for one byte pad to word boundary */
1183 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1184 fileName, PATH_MAX, nls_codepage, remap);
1185 name_len++; /* trailing null */
1188 count = 0; /* no pad */
1189 name_len = copy_path_name(pSMB->fileName, fileName);
1191 if (*pOplock & REQ_OPLOCK)
1192 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1193 else if (*pOplock & REQ_BATCHOPLOCK)
1194 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1196 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1197 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1198 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1199 /* set file as system file if special file such
1200 as fifo and server expecting SFU style and
1201 no Unix extensions */
1203 if (create_options & CREATE_OPTION_SPECIAL)
1204 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1205 else /* BB FIXME BB */
1206 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1208 if (create_options & CREATE_OPTION_READONLY)
1209 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1212 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1213 CREATE_OPTIONS_MASK); */
1214 /* BB FIXME END BB */
1216 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1217 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1219 inc_rfc1001_len(pSMB, count);
1221 pSMB->ByteCount = cpu_to_le16(count);
1222 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1223 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1224 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1226 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1228 /* BB verify if wct == 15 */
1230 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1232 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1233 /* Let caller know file was created so we can set the mode. */
1234 /* Do we care about the CreateAction in any other cases? */
1236 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1237 *pOplock |= CIFS_CREATE_ACTION; */
1241 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1242 pfile_info->LastAccessTime = 0; /* BB fixme */
1243 pfile_info->LastWriteTime = 0; /* BB fixme */
1244 pfile_info->ChangeTime = 0; /* BB fixme */
1245 pfile_info->Attributes =
1246 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1247 /* the file_info buf is endian converted by caller */
1248 pfile_info->AllocationSize =
1249 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1250 pfile_info->EndOfFile = pfile_info->AllocationSize;
1251 pfile_info->NumberOfLinks = cpu_to_le32(1);
1252 pfile_info->DeletePending = 0;
1256 cifs_buf_release(pSMB);
1263 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1267 OPEN_REQ *req = NULL;
1268 OPEN_RSP *rsp = NULL;
1272 struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1273 struct cifs_tcon *tcon = oparms->tcon;
1274 int remap = cifs_remap(cifs_sb);
1275 const struct nls_table *nls = cifs_sb->local_nls;
1276 int create_options = oparms->create_options;
1277 int desired_access = oparms->desired_access;
1278 int disposition = oparms->disposition;
1279 const char *path = oparms->path;
1282 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1287 /* no commands go after this */
1288 req->AndXCommand = 0xFF;
1290 if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1291 /* account for one byte pad to word boundary */
1293 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1294 path, PATH_MAX, nls, remap);
1298 req->NameLength = cpu_to_le16(name_len);
1300 /* BB improve check for buffer overruns BB */
1303 name_len = copy_path_name(req->fileName, path);
1304 req->NameLength = cpu_to_le16(name_len);
1307 if (*oplock & REQ_OPLOCK)
1308 req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1309 else if (*oplock & REQ_BATCHOPLOCK)
1310 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1312 req->DesiredAccess = cpu_to_le32(desired_access);
1313 req->AllocationSize = 0;
1316 * Set file as system file if special file such as fifo and server
1317 * expecting SFU style and no Unix extensions.
1319 if (create_options & CREATE_OPTION_SPECIAL)
1320 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1322 req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1325 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1326 * sensitive checks for other servers such as Samba.
1328 if (tcon->ses->capabilities & CAP_UNIX)
1329 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1331 if (create_options & CREATE_OPTION_READONLY)
1332 req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1334 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1335 req->CreateDisposition = cpu_to_le32(disposition);
1336 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1338 /* BB Expirement with various impersonation levels and verify */
1339 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1340 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1343 inc_rfc1001_len(req, count);
1345 req->ByteCount = cpu_to_le16(count);
1346 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1347 (struct smb_hdr *)rsp, &bytes_returned, 0);
1348 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1350 cifs_dbg(FYI, "Error in Open = %d\n", rc);
1351 cifs_buf_release(req);
1357 /* 1 byte no need to le_to_cpu */
1358 *oplock = rsp->OplockLevel;
1359 /* cifs fid stays in le */
1360 oparms->fid->netfid = rsp->Fid;
1361 oparms->fid->access = desired_access;
1363 /* Let caller know file was created so we can set the mode. */
1364 /* Do we care about the CreateAction in any other cases? */
1365 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1366 *oplock |= CIFS_CREATE_ACTION;
1369 /* copy from CreationTime to Attributes */
1370 memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1371 /* the file_info buf is endian converted by caller */
1372 buf->AllocationSize = rsp->AllocationSize;
1373 buf->EndOfFile = rsp->EndOfFile;
1374 buf->NumberOfLinks = cpu_to_le32(1);
1375 buf->DeletePending = 0;
1378 cifs_buf_release(req);
1383 * Discard any remaining data in the current SMB. To do this, we borrow the
1387 cifs_discard_remaining_data(struct TCP_Server_Info *server)
1389 unsigned int rfclen = server->pdu_size;
1390 int remaining = rfclen + server->vals->header_preamble_size -
1393 while (remaining > 0) {
1396 length = cifs_discard_from_socket(server,
1397 min_t(size_t, remaining,
1398 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1401 server->total_read += length;
1402 remaining -= length;
1409 __cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
1414 length = cifs_discard_remaining_data(server);
1415 dequeue_mid(mid, malformed);
1416 mid->resp_buf = server->smallbuf;
1417 server->smallbuf = NULL;
1422 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1424 struct cifs_readdata *rdata = mid->callback_data;
1426 return __cifs_readv_discard(server, mid, rdata->result);
1430 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1433 unsigned int data_offset, data_len;
1434 struct cifs_readdata *rdata = mid->callback_data;
1435 char *buf = server->smallbuf;
1436 unsigned int buflen = server->pdu_size +
1437 server->vals->header_preamble_size;
1438 bool use_rdma_mr = false;
1440 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1441 __func__, mid->mid, rdata->offset, rdata->bytes);
1444 * read the rest of READ_RSP header (sans Data array), or whatever we
1445 * can if there's not enough data. At this point, we've read down to
1448 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1449 HEADER_SIZE(server) + 1;
1451 length = cifs_read_from_socket(server,
1452 buf + HEADER_SIZE(server) - 1, len);
1455 server->total_read += length;
1457 if (server->ops->is_session_expired &&
1458 server->ops->is_session_expired(buf)) {
1459 cifs_reconnect(server, true);
1463 if (server->ops->is_status_pending &&
1464 server->ops->is_status_pending(buf, server)) {
1465 cifs_discard_remaining_data(server);
1469 /* set up first two iov for signature check and to get credits */
1470 rdata->iov[0].iov_base = buf;
1471 rdata->iov[0].iov_len = server->vals->header_preamble_size;
1472 rdata->iov[1].iov_base = buf + server->vals->header_preamble_size;
1473 rdata->iov[1].iov_len =
1474 server->total_read - server->vals->header_preamble_size;
1475 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
1476 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1477 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
1478 rdata->iov[1].iov_base, rdata->iov[1].iov_len);
1480 /* Was the SMB read successful? */
1481 rdata->result = server->ops->map_error(buf, false);
1482 if (rdata->result != 0) {
1483 cifs_dbg(FYI, "%s: server returned error %d\n",
1484 __func__, rdata->result);
1485 /* normal error on read response */
1486 return __cifs_readv_discard(server, mid, false);
1489 /* Is there enough to get to the rest of the READ_RSP header? */
1490 if (server->total_read < server->vals->read_rsp_size) {
1491 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1492 __func__, server->total_read,
1493 server->vals->read_rsp_size);
1494 rdata->result = -EIO;
1495 return cifs_readv_discard(server, mid);
1498 data_offset = server->ops->read_data_offset(buf) +
1499 server->vals->header_preamble_size;
1500 if (data_offset < server->total_read) {
1502 * win2k8 sometimes sends an offset of 0 when the read
1503 * is beyond the EOF. Treat it as if the data starts just after
1506 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1507 __func__, data_offset);
1508 data_offset = server->total_read;
1509 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1510 /* data_offset is beyond the end of smallbuf */
1511 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1512 __func__, data_offset);
1513 rdata->result = -EIO;
1514 return cifs_readv_discard(server, mid);
1517 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1518 __func__, server->total_read, data_offset);
1520 len = data_offset - server->total_read;
1522 /* read any junk before data into the rest of smallbuf */
1523 length = cifs_read_from_socket(server,
1524 buf + server->total_read, len);
1527 server->total_read += length;
1530 /* how much data is in the response? */
1531 #ifdef CONFIG_CIFS_SMB_DIRECT
1532 use_rdma_mr = rdata->mr;
1534 data_len = server->ops->read_data_length(buf, use_rdma_mr);
1535 if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1536 /* data_len is corrupt -- discard frame */
1537 rdata->result = -EIO;
1538 return cifs_readv_discard(server, mid);
1541 length = rdata->read_into_pages(server, rdata, data_len);
1545 server->total_read += length;
1547 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1548 server->total_read, buflen, data_len);
1550 /* discard anything left over */
1551 if (server->total_read < buflen)
1552 return cifs_readv_discard(server, mid);
1554 dequeue_mid(mid, false);
1555 mid->resp_buf = server->smallbuf;
1556 server->smallbuf = NULL;
1561 cifs_readv_callback(struct mid_q_entry *mid)
1563 struct cifs_readdata *rdata = mid->callback_data;
1564 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1565 struct TCP_Server_Info *server = tcon->ses->server;
1566 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1568 .rq_pages = rdata->pages,
1569 .rq_offset = rdata->page_offset,
1570 .rq_npages = rdata->nr_pages,
1571 .rq_pagesz = rdata->pagesz,
1572 .rq_tailsz = rdata->tailsz };
1573 struct cifs_credits credits = { .value = 1, .instance = 0 };
1575 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1576 __func__, mid->mid, mid->mid_state, rdata->result,
1579 switch (mid->mid_state) {
1580 case MID_RESPONSE_RECEIVED:
1581 /* result already set, check signature */
1585 rc = cifs_verify_signature(&rqst, server,
1586 mid->sequence_number);
1588 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1591 /* FIXME: should this be counted toward the initiating task? */
1592 task_io_account_read(rdata->got_bytes);
1593 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1595 case MID_REQUEST_SUBMITTED:
1596 case MID_RETRY_NEEDED:
1597 rdata->result = -EAGAIN;
1598 if (server->sign && rdata->got_bytes)
1599 /* reset bytes number since we can not check a sign */
1600 rdata->got_bytes = 0;
1601 /* FIXME: should this be counted toward the initiating task? */
1602 task_io_account_read(rdata->got_bytes);
1603 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1606 rdata->result = -EIO;
1609 queue_work(cifsiod_wq, &rdata->work);
1610 DeleteMidQEntry(mid);
1611 add_credits(server, &credits, 0);
1614 /* cifs_async_readv - send an async write, and set up mid to handle result */
1616 cifs_async_readv(struct cifs_readdata *rdata)
1619 READ_REQ *smb = NULL;
1621 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1622 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1625 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1626 __func__, rdata->offset, rdata->bytes);
1628 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1631 wct = 10; /* old style read */
1632 if ((rdata->offset >> 32) > 0) {
1633 /* can not handle this big offset for old */
1638 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1642 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1643 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1645 smb->AndXCommand = 0xFF; /* none */
1646 smb->Fid = rdata->cfile->fid.netfid;
1647 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1649 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1651 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1652 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1656 /* old style read */
1657 struct smb_com_readx_req *smbr =
1658 (struct smb_com_readx_req *)smb;
1659 smbr->ByteCount = 0;
1662 /* 4 for RFC1001 length + 1 for BCC */
1663 rdata->iov[0].iov_base = smb;
1664 rdata->iov[0].iov_len = 4;
1665 rdata->iov[1].iov_base = (char *)smb + 4;
1666 rdata->iov[1].iov_len = get_rfc1002_length(smb);
1668 kref_get(&rdata->refcount);
1669 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1670 cifs_readv_callback, NULL, rdata, 0, NULL);
1673 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1675 kref_put(&rdata->refcount, cifs_readdata_release);
1677 cifs_small_buf_release(smb);
1682 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1683 unsigned int *nbytes, char **buf, int *pbuf_type)
1686 READ_REQ *pSMB = NULL;
1687 READ_RSP *pSMBr = NULL;
1688 char *pReadData = NULL;
1690 int resp_buf_type = 0;
1692 struct kvec rsp_iov;
1693 __u32 pid = io_parms->pid;
1694 __u16 netfid = io_parms->netfid;
1695 __u64 offset = io_parms->offset;
1696 struct cifs_tcon *tcon = io_parms->tcon;
1697 unsigned int count = io_parms->length;
1699 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1700 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1703 wct = 10; /* old style read */
1704 if ((offset >> 32) > 0) {
1705 /* can not handle this big offset for old */
1711 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1715 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1716 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1718 /* tcon and ses pointer are checked in smb_init */
1719 if (tcon->ses->server == NULL)
1720 return -ECONNABORTED;
1722 pSMB->AndXCommand = 0xFF; /* none */
1724 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1726 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1728 pSMB->Remaining = 0;
1729 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1730 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1732 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1734 /* old style read */
1735 struct smb_com_readx_req *pSMBW =
1736 (struct smb_com_readx_req *)pSMB;
1737 pSMBW->ByteCount = 0;
1740 iov[0].iov_base = (char *)pSMB;
1741 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1742 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1743 CIFS_LOG_ERROR, &rsp_iov);
1744 cifs_small_buf_release(pSMB);
1745 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1746 pSMBr = (READ_RSP *)rsp_iov.iov_base;
1748 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1750 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1751 data_length = data_length << 16;
1752 data_length += le16_to_cpu(pSMBr->DataLength);
1753 *nbytes = data_length;
1755 /*check that DataLength would not go beyond end of SMB */
1756 if ((data_length > CIFSMaxBufSize)
1757 || (data_length > count)) {
1758 cifs_dbg(FYI, "bad length %d for count %d\n",
1759 data_length, count);
1763 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1764 le16_to_cpu(pSMBr->DataOffset);
1765 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1766 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1768 }*/ /* can not use copy_to_user when using page cache*/
1770 memcpy(*buf, pReadData, data_length);
1775 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1776 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1777 /* return buffer to caller to free */
1778 *buf = rsp_iov.iov_base;
1779 if (resp_buf_type == CIFS_SMALL_BUFFER)
1780 *pbuf_type = CIFS_SMALL_BUFFER;
1781 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1782 *pbuf_type = CIFS_LARGE_BUFFER;
1783 } /* else no valid buffer on return - leave as null */
1785 /* Note: On -EAGAIN error only caller can retry on handle based calls
1786 since file handle passed in no longer valid */
1792 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1793 unsigned int *nbytes, const char *buf)
1796 WRITE_REQ *pSMB = NULL;
1797 WRITE_RSP *pSMBr = NULL;
1798 int bytes_returned, wct;
1801 __u32 pid = io_parms->pid;
1802 __u16 netfid = io_parms->netfid;
1803 __u64 offset = io_parms->offset;
1804 struct cifs_tcon *tcon = io_parms->tcon;
1805 unsigned int count = io_parms->length;
1809 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1810 if (tcon->ses == NULL)
1811 return -ECONNABORTED;
1813 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1817 if ((offset >> 32) > 0) {
1818 /* can not handle big offset for old srv */
1823 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1828 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1829 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1831 /* tcon and ses pointer are checked in smb_init */
1832 if (tcon->ses->server == NULL)
1833 return -ECONNABORTED;
1835 pSMB->AndXCommand = 0xFF; /* none */
1837 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1839 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1841 pSMB->Reserved = 0xFFFFFFFF;
1842 pSMB->WriteMode = 0;
1843 pSMB->Remaining = 0;
1845 /* Can increase buffer size if buffer is big enough in some cases ie we
1846 can send more if LARGE_WRITE_X capability returned by the server and if
1847 our buffer is big enough or if we convert to iovecs on socket writes
1848 and eliminate the copy to the CIFS buffer */
1849 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1850 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1852 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1856 if (bytes_sent > count)
1859 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1861 memcpy(pSMB->Data, buf, bytes_sent);
1862 else if (count != 0) {
1864 cifs_buf_release(pSMB);
1866 } /* else setting file size with write of zero bytes */
1868 byte_count = bytes_sent + 1; /* pad */
1869 else /* wct == 12 */
1870 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1872 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1873 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1874 inc_rfc1001_len(pSMB, byte_count);
1877 pSMB->ByteCount = cpu_to_le16(byte_count);
1878 else { /* old style write has byte count 4 bytes earlier
1880 struct smb_com_writex_req *pSMBW =
1881 (struct smb_com_writex_req *)pSMB;
1882 pSMBW->ByteCount = cpu_to_le16(byte_count);
1885 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1886 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1887 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1889 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1891 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1892 *nbytes = (*nbytes) << 16;
1893 *nbytes += le16_to_cpu(pSMBr->Count);
1896 * Mask off high 16 bits when bytes written as returned by the
1897 * server is greater than bytes requested by the client. Some
1898 * OS/2 servers are known to set incorrect CountHigh values.
1900 if (*nbytes > count)
1904 cifs_buf_release(pSMB);
1906 /* Note: On -EAGAIN error only caller can retry on handle based calls
1907 since file handle passed in no longer valid */
1913 cifs_writedata_release(struct kref *refcount)
1915 struct cifs_writedata *wdata = container_of(refcount,
1916 struct cifs_writedata, refcount);
1917 #ifdef CONFIG_CIFS_SMB_DIRECT
1919 smbd_deregister_mr(wdata->mr);
1925 cifsFileInfo_put(wdata->cfile);
1927 kvfree(wdata->pages);
1932 * Write failed with a retryable error. Resend the write request. It's also
1933 * possible that the page was redirtied so re-clean the page.
1936 cifs_writev_requeue(struct cifs_writedata *wdata)
1939 struct inode *inode = d_inode(wdata->cfile->dentry);
1940 struct TCP_Server_Info *server;
1941 unsigned int rest_len;
1943 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1945 rest_len = wdata->bytes;
1947 struct cifs_writedata *wdata2;
1948 unsigned int j, nr_pages, wsize, tailsz, cur_len;
1950 wsize = server->ops->wp_retry_size(inode);
1951 if (wsize < rest_len) {
1952 nr_pages = wsize / PAGE_SIZE;
1957 cur_len = nr_pages * PAGE_SIZE;
1960 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
1962 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
1965 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
1971 for (j = 0; j < nr_pages; j++) {
1972 wdata2->pages[j] = wdata->pages[i + j];
1973 lock_page(wdata2->pages[j]);
1974 clear_page_dirty_for_io(wdata2->pages[j]);
1977 wdata2->sync_mode = wdata->sync_mode;
1978 wdata2->nr_pages = nr_pages;
1979 wdata2->offset = page_offset(wdata2->pages[0]);
1980 wdata2->pagesz = PAGE_SIZE;
1981 wdata2->tailsz = tailsz;
1982 wdata2->bytes = cur_len;
1984 rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY,
1986 if (!wdata2->cfile) {
1987 cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
1989 if (!is_retryable_error(rc))
1992 wdata2->pid = wdata2->cfile->pid;
1993 rc = server->ops->async_writev(wdata2,
1994 cifs_writedata_release);
1997 for (j = 0; j < nr_pages; j++) {
1998 unlock_page(wdata2->pages[j]);
1999 if (rc != 0 && !is_retryable_error(rc)) {
2000 SetPageError(wdata2->pages[j]);
2001 end_page_writeback(wdata2->pages[j]);
2002 put_page(wdata2->pages[j]);
2006 kref_put(&wdata2->refcount, cifs_writedata_release);
2008 if (is_retryable_error(rc))
2014 rest_len -= cur_len;
2016 } while (i < wdata->nr_pages);
2018 /* cleanup remaining pages from the original wdata */
2019 for (; i < wdata->nr_pages; i++) {
2020 SetPageError(wdata->pages[i]);
2021 end_page_writeback(wdata->pages[i]);
2022 put_page(wdata->pages[i]);
2025 if (rc != 0 && !is_retryable_error(rc))
2026 mapping_set_error(inode->i_mapping, rc);
2027 kref_put(&wdata->refcount, cifs_writedata_release);
2031 cifs_writev_complete(struct work_struct *work)
2033 struct cifs_writedata *wdata = container_of(work,
2034 struct cifs_writedata, work);
2035 struct inode *inode = d_inode(wdata->cfile->dentry);
2038 if (wdata->result == 0) {
2039 spin_lock(&inode->i_lock);
2040 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2041 spin_unlock(&inode->i_lock);
2042 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2044 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2045 return cifs_writev_requeue(wdata);
2047 for (i = 0; i < wdata->nr_pages; i++) {
2048 struct page *page = wdata->pages[i];
2049 if (wdata->result == -EAGAIN)
2050 __set_page_dirty_nobuffers(page);
2051 else if (wdata->result < 0)
2053 end_page_writeback(page);
2054 cifs_readpage_to_fscache(inode, page);
2057 if (wdata->result != -EAGAIN)
2058 mapping_set_error(inode->i_mapping, wdata->result);
2059 kref_put(&wdata->refcount, cifs_writedata_release);
2062 struct cifs_writedata *
2063 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2065 struct page **pages =
2066 kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
2068 return cifs_writedata_direct_alloc(pages, complete);
2073 struct cifs_writedata *
2074 cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
2076 struct cifs_writedata *wdata;
2078 wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
2079 if (wdata != NULL) {
2080 wdata->pages = pages;
2081 kref_init(&wdata->refcount);
2082 INIT_LIST_HEAD(&wdata->list);
2083 init_completion(&wdata->done);
2084 INIT_WORK(&wdata->work, complete);
2090 * Check the mid_state and signature on received buffer (if any), and queue the
2091 * workqueue completion task.
2094 cifs_writev_callback(struct mid_q_entry *mid)
2096 struct cifs_writedata *wdata = mid->callback_data;
2097 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2098 unsigned int written;
2099 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2100 struct cifs_credits credits = { .value = 1, .instance = 0 };
2102 switch (mid->mid_state) {
2103 case MID_RESPONSE_RECEIVED:
2104 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2105 if (wdata->result != 0)
2108 written = le16_to_cpu(smb->CountHigh);
2110 written += le16_to_cpu(smb->Count);
2112 * Mask off high 16 bits when bytes written as returned
2113 * by the server is greater than bytes requested by the
2114 * client. OS/2 servers are known to set incorrect
2117 if (written > wdata->bytes)
2120 if (written < wdata->bytes)
2121 wdata->result = -ENOSPC;
2123 wdata->bytes = written;
2125 case MID_REQUEST_SUBMITTED:
2126 case MID_RETRY_NEEDED:
2127 wdata->result = -EAGAIN;
2130 wdata->result = -EIO;
2134 queue_work(cifsiod_wq, &wdata->work);
2135 DeleteMidQEntry(mid);
2136 add_credits(tcon->ses->server, &credits, 0);
2139 /* cifs_async_writev - send an async write, and set up mid to handle result */
2141 cifs_async_writev(struct cifs_writedata *wdata,
2142 void (*release)(struct kref *kref))
2145 WRITE_REQ *smb = NULL;
2147 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2149 struct smb_rqst rqst = { };
2151 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2155 if (wdata->offset >> 32 > 0) {
2156 /* can not handle big offset for old srv */
2161 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2163 goto async_writev_out;
2165 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2166 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2168 smb->AndXCommand = 0xFF; /* none */
2169 smb->Fid = wdata->cfile->fid.netfid;
2170 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2172 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2173 smb->Reserved = 0xFFFFFFFF;
2178 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2180 /* 4 for RFC1001 length + 1 for BCC */
2182 iov[0].iov_base = smb;
2183 iov[1].iov_len = get_rfc1002_length(smb) + 1;
2184 iov[1].iov_base = (char *)smb + 4;
2188 rqst.rq_pages = wdata->pages;
2189 rqst.rq_offset = wdata->page_offset;
2190 rqst.rq_npages = wdata->nr_pages;
2191 rqst.rq_pagesz = wdata->pagesz;
2192 rqst.rq_tailsz = wdata->tailsz;
2194 cifs_dbg(FYI, "async write at %llu %u bytes\n",
2195 wdata->offset, wdata->bytes);
2197 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2198 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2201 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2202 put_bcc(wdata->bytes + 1, &smb->hdr);
2205 struct smb_com_writex_req *smbw =
2206 (struct smb_com_writex_req *)smb;
2207 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2208 put_bcc(wdata->bytes + 5, &smbw->hdr);
2209 iov[1].iov_len += 4; /* pad bigger by four bytes */
2212 kref_get(&wdata->refcount);
2213 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2214 cifs_writev_callback, NULL, wdata, 0, NULL);
2217 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2219 kref_put(&wdata->refcount, release);
2222 cifs_small_buf_release(smb);
2227 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2228 unsigned int *nbytes, struct kvec *iov, int n_vec)
2231 WRITE_REQ *pSMB = NULL;
2234 int resp_buf_type = 0;
2235 __u32 pid = io_parms->pid;
2236 __u16 netfid = io_parms->netfid;
2237 __u64 offset = io_parms->offset;
2238 struct cifs_tcon *tcon = io_parms->tcon;
2239 unsigned int count = io_parms->length;
2240 struct kvec rsp_iov;
2244 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2246 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2250 if ((offset >> 32) > 0) {
2251 /* can not handle big offset for old srv */
2255 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2259 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2260 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2262 /* tcon and ses pointer are checked in smb_init */
2263 if (tcon->ses->server == NULL)
2264 return -ECONNABORTED;
2266 pSMB->AndXCommand = 0xFF; /* none */
2268 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2270 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2271 pSMB->Reserved = 0xFFFFFFFF;
2272 pSMB->WriteMode = 0;
2273 pSMB->Remaining = 0;
2276 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2278 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2279 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2280 /* header + 1 byte pad */
2281 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2283 inc_rfc1001_len(pSMB, count + 1);
2284 else /* wct == 12 */
2285 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2287 pSMB->ByteCount = cpu_to_le16(count + 1);
2288 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2289 struct smb_com_writex_req *pSMBW =
2290 (struct smb_com_writex_req *)pSMB;
2291 pSMBW->ByteCount = cpu_to_le16(count + 5);
2293 iov[0].iov_base = pSMB;
2295 iov[0].iov_len = smb_hdr_len + 4;
2296 else /* wct == 12 pad bigger by four bytes */
2297 iov[0].iov_len = smb_hdr_len + 8;
2299 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2301 cifs_small_buf_release(pSMB);
2302 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2304 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2305 } else if (resp_buf_type == 0) {
2306 /* presumably this can not happen, but best to be safe */
2309 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2310 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2311 *nbytes = (*nbytes) << 16;
2312 *nbytes += le16_to_cpu(pSMBr->Count);
2315 * Mask off high 16 bits when bytes written as returned by the
2316 * server is greater than bytes requested by the client. OS/2
2317 * servers are known to set incorrect CountHigh values.
2319 if (*nbytes > count)
2323 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2325 /* Note: On -EAGAIN error only caller can retry on handle based calls
2326 since file handle passed in no longer valid */
2331 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2332 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2333 const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2336 LOCK_REQ *pSMB = NULL;
2338 struct kvec rsp_iov;
2342 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2343 num_lock, num_unlock);
2345 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2350 pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2351 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2352 pSMB->LockType = lock_type;
2353 pSMB->AndXCommand = 0xFF; /* none */
2354 pSMB->Fid = netfid; /* netfid stays le */
2356 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2357 inc_rfc1001_len(pSMB, count);
2358 pSMB->ByteCount = cpu_to_le16(count);
2360 iov[0].iov_base = (char *)pSMB;
2361 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2362 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2363 iov[1].iov_base = (char *)buf;
2364 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2366 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2367 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
2368 CIFS_NO_RSP_BUF, &rsp_iov);
2369 cifs_small_buf_release(pSMB);
2371 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2377 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2378 const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2379 const __u64 offset, const __u32 numUnlock,
2380 const __u32 numLock, const __u8 lockType,
2381 const bool waitFlag, const __u8 oplock_level)
2384 LOCK_REQ *pSMB = NULL;
2385 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2390 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2391 (int)waitFlag, numLock);
2392 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2397 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2398 /* no response expected */
2399 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
2401 } else if (waitFlag) {
2402 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2403 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2408 pSMB->NumberOfLocks = cpu_to_le16(numLock);
2409 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2410 pSMB->LockType = lockType;
2411 pSMB->OplockLevel = oplock_level;
2412 pSMB->AndXCommand = 0xFF; /* none */
2413 pSMB->Fid = smb_file_id; /* netfid stays le */
2415 if ((numLock != 0) || (numUnlock != 0)) {
2416 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2417 /* BB where to store pid high? */
2418 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2419 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2420 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2421 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2422 count = sizeof(LOCKING_ANDX_RANGE);
2427 inc_rfc1001_len(pSMB, count);
2428 pSMB->ByteCount = cpu_to_le16(count);
2431 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2432 (struct smb_hdr *) pSMB, &bytes_returned);
2434 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2435 cifs_small_buf_release(pSMB);
2436 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2438 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2440 /* Note: On -EAGAIN error only caller can retry on handle based calls
2441 since file handle passed in no longer valid */
2446 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2447 const __u16 smb_file_id, const __u32 netpid,
2448 const loff_t start_offset, const __u64 len,
2449 struct file_lock *pLockData, const __u16 lock_type,
2450 const bool waitFlag)
2452 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2453 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2454 struct cifs_posix_lock *parm_data;
2457 int bytes_returned = 0;
2458 int resp_buf_type = 0;
2459 __u16 params, param_offset, offset, byte_count, count;
2461 struct kvec rsp_iov;
2463 cifs_dbg(FYI, "Posix Lock\n");
2465 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2470 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2473 pSMB->MaxSetupCount = 0;
2476 pSMB->Reserved2 = 0;
2477 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2478 offset = param_offset + params;
2480 count = sizeof(struct cifs_posix_lock);
2481 pSMB->MaxParameterCount = cpu_to_le16(2);
2482 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2483 pSMB->SetupCount = 1;
2484 pSMB->Reserved3 = 0;
2486 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2488 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2489 byte_count = 3 /* pad */ + params + count;
2490 pSMB->DataCount = cpu_to_le16(count);
2491 pSMB->ParameterCount = cpu_to_le16(params);
2492 pSMB->TotalDataCount = pSMB->DataCount;
2493 pSMB->TotalParameterCount = pSMB->ParameterCount;
2494 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2495 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2496 parm_data = (struct cifs_posix_lock *)
2497 (((char *)pSMB) + offset + 4);
2499 parm_data->lock_type = cpu_to_le16(lock_type);
2501 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2502 parm_data->lock_flags = cpu_to_le16(1);
2503 pSMB->Timeout = cpu_to_le32(-1);
2507 parm_data->pid = cpu_to_le32(netpid);
2508 parm_data->start = cpu_to_le64(start_offset);
2509 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
2511 pSMB->DataOffset = cpu_to_le16(offset);
2512 pSMB->Fid = smb_file_id;
2513 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2514 pSMB->Reserved4 = 0;
2515 inc_rfc1001_len(pSMB, byte_count);
2516 pSMB->ByteCount = cpu_to_le16(byte_count);
2518 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2519 (struct smb_hdr *) pSMBr, &bytes_returned);
2521 iov[0].iov_base = (char *)pSMB;
2522 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2523 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2524 &resp_buf_type, timeout, &rsp_iov);
2525 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2527 cifs_small_buf_release(pSMB);
2530 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2531 } else if (pLockData) {
2532 /* lock structure can be returned on get */
2535 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2537 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2538 rc = -EIO; /* bad smb */
2541 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2542 data_count = le16_to_cpu(pSMBr->t2.DataCount);
2543 if (data_count < sizeof(struct cifs_posix_lock)) {
2547 parm_data = (struct cifs_posix_lock *)
2548 ((char *)&pSMBr->hdr.Protocol + data_offset);
2549 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2550 pLockData->fl_type = F_UNLCK;
2552 if (parm_data->lock_type ==
2553 cpu_to_le16(CIFS_RDLCK))
2554 pLockData->fl_type = F_RDLCK;
2555 else if (parm_data->lock_type ==
2556 cpu_to_le16(CIFS_WRLCK))
2557 pLockData->fl_type = F_WRLCK;
2559 pLockData->fl_start = le64_to_cpu(parm_data->start);
2560 pLockData->fl_end = pLockData->fl_start +
2561 (le64_to_cpu(parm_data->length) ?
2562 le64_to_cpu(parm_data->length) - 1 : 0);
2563 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2568 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2570 /* Note: On -EAGAIN error only caller can retry on handle based calls
2571 since file handle passed in no longer valid */
2578 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2581 CLOSE_REQ *pSMB = NULL;
2582 cifs_dbg(FYI, "In CIFSSMBClose\n");
2584 /* do not retry on dead session on close */
2585 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2591 pSMB->FileID = (__u16) smb_file_id;
2592 pSMB->LastWriteTime = 0xFFFFFFFF;
2593 pSMB->ByteCount = 0;
2594 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2595 cifs_small_buf_release(pSMB);
2596 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2599 /* EINTR is expected when user ctl-c to kill app */
2600 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2604 /* Since session is dead, file will be closed on server already */
2612 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2615 FLUSH_REQ *pSMB = NULL;
2616 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2618 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2622 pSMB->FileID = (__u16) smb_file_id;
2623 pSMB->ByteCount = 0;
2624 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2625 cifs_small_buf_release(pSMB);
2626 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2628 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2634 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2635 const char *from_name, const char *to_name,
2636 struct cifs_sb_info *cifs_sb)
2639 RENAME_REQ *pSMB = NULL;
2640 RENAME_RSP *pSMBr = NULL;
2642 int name_len, name_len2;
2644 int remap = cifs_remap(cifs_sb);
2646 cifs_dbg(FYI, "In CIFSSMBRename\n");
2648 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2653 pSMB->BufferFormat = 0x04;
2654 pSMB->SearchAttributes =
2655 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2658 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2659 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2660 from_name, PATH_MAX,
2661 cifs_sb->local_nls, remap);
2662 name_len++; /* trailing null */
2664 pSMB->OldFileName[name_len] = 0x04; /* pad */
2665 /* protocol requires ASCII signature byte on Unicode string */
2666 pSMB->OldFileName[name_len + 1] = 0x00;
2668 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2669 to_name, PATH_MAX, cifs_sb->local_nls,
2671 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2672 name_len2 *= 2; /* convert to bytes */
2674 name_len = copy_path_name(pSMB->OldFileName, from_name);
2675 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2676 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2677 name_len2++; /* signature byte */
2680 count = 1 /* 1st signature byte */ + name_len + name_len2;
2681 inc_rfc1001_len(pSMB, count);
2682 pSMB->ByteCount = cpu_to_le16(count);
2684 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2685 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2686 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2688 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2690 cifs_buf_release(pSMB);
2698 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2699 int netfid, const char *target_name,
2700 const struct nls_table *nls_codepage, int remap)
2702 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2703 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2704 struct set_file_rename *rename_info;
2706 char dummy_string[30];
2708 int bytes_returned = 0;
2710 __u16 params, param_offset, offset, count, byte_count;
2712 cifs_dbg(FYI, "Rename to File by handle\n");
2713 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2719 pSMB->MaxSetupCount = 0;
2723 pSMB->Reserved2 = 0;
2724 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2725 offset = param_offset + params;
2727 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2728 data_offset = (char *)(pSMB) + offset + 4;
2729 rename_info = (struct set_file_rename *) data_offset;
2730 pSMB->MaxParameterCount = cpu_to_le16(2);
2731 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2732 pSMB->SetupCount = 1;
2733 pSMB->Reserved3 = 0;
2734 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2735 byte_count = 3 /* pad */ + params;
2736 pSMB->ParameterCount = cpu_to_le16(params);
2737 pSMB->TotalParameterCount = pSMB->ParameterCount;
2738 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2739 pSMB->DataOffset = cpu_to_le16(offset);
2740 /* construct random name ".cifs_tmp<inodenum><mid>" */
2741 rename_info->overwrite = cpu_to_le32(1);
2742 rename_info->root_fid = 0;
2743 /* unicode only call */
2744 if (target_name == NULL) {
2745 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2747 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2748 dummy_string, 24, nls_codepage, remap);
2751 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2752 target_name, PATH_MAX, nls_codepage,
2755 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2756 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2757 byte_count += count;
2758 pSMB->DataCount = cpu_to_le16(count);
2759 pSMB->TotalDataCount = pSMB->DataCount;
2761 pSMB->InformationLevel =
2762 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2763 pSMB->Reserved4 = 0;
2764 inc_rfc1001_len(pSMB, byte_count);
2765 pSMB->ByteCount = cpu_to_le16(byte_count);
2766 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2767 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2768 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2770 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2773 cifs_buf_release(pSMB);
2775 /* Note: On -EAGAIN error only caller can retry on handle based calls
2776 since file handle passed in no longer valid */
2782 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2783 const char *fromName, const __u16 target_tid, const char *toName,
2784 const int flags, const struct nls_table *nls_codepage, int remap)
2787 COPY_REQ *pSMB = NULL;
2788 COPY_RSP *pSMBr = NULL;
2790 int name_len, name_len2;
2793 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2795 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2800 pSMB->BufferFormat = 0x04;
2801 pSMB->Tid2 = target_tid;
2803 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2805 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2806 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2807 fromName, PATH_MAX, nls_codepage,
2809 name_len++; /* trailing null */
2811 pSMB->OldFileName[name_len] = 0x04; /* pad */
2812 /* protocol requires ASCII signature byte on Unicode string */
2813 pSMB->OldFileName[name_len + 1] = 0x00;
2815 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2816 toName, PATH_MAX, nls_codepage, remap);
2817 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2818 name_len2 *= 2; /* convert to bytes */
2820 name_len = copy_path_name(pSMB->OldFileName, fromName);
2821 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2822 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2823 name_len2++; /* signature byte */
2826 count = 1 /* 1st signature byte */ + name_len + name_len2;
2827 inc_rfc1001_len(pSMB, count);
2828 pSMB->ByteCount = cpu_to_le16(count);
2830 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2831 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2833 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2834 rc, le16_to_cpu(pSMBr->CopyCount));
2836 cifs_buf_release(pSMB);
2845 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2846 const char *fromName, const char *toName,
2847 const struct nls_table *nls_codepage, int remap)
2849 TRANSACTION2_SPI_REQ *pSMB = NULL;
2850 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2853 int name_len_target;
2855 int bytes_returned = 0;
2856 __u16 params, param_offset, offset, byte_count;
2858 cifs_dbg(FYI, "In Symlink Unix style\n");
2860 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2865 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2867 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2868 /* find define for this maxpathcomponent */
2869 PATH_MAX, nls_codepage, remap);
2870 name_len++; /* trailing null */
2874 name_len = copy_path_name(pSMB->FileName, fromName);
2876 params = 6 + name_len;
2877 pSMB->MaxSetupCount = 0;
2881 pSMB->Reserved2 = 0;
2882 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2883 InformationLevel) - 4;
2884 offset = param_offset + params;
2886 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2887 data_offset = (char *)pSMB + offset + 4;
2888 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2890 cifsConvertToUTF16((__le16 *) data_offset, toName,
2891 /* find define for this maxpathcomponent */
2892 PATH_MAX, nls_codepage, remap);
2893 name_len_target++; /* trailing null */
2894 name_len_target *= 2;
2896 name_len_target = copy_path_name(data_offset, toName);
2899 pSMB->MaxParameterCount = cpu_to_le16(2);
2900 /* BB find exact max on data count below from sess */
2901 pSMB->MaxDataCount = cpu_to_le16(1000);
2902 pSMB->SetupCount = 1;
2903 pSMB->Reserved3 = 0;
2904 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2905 byte_count = 3 /* pad */ + params + name_len_target;
2906 pSMB->DataCount = cpu_to_le16(name_len_target);
2907 pSMB->ParameterCount = cpu_to_le16(params);
2908 pSMB->TotalDataCount = pSMB->DataCount;
2909 pSMB->TotalParameterCount = pSMB->ParameterCount;
2910 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2911 pSMB->DataOffset = cpu_to_le16(offset);
2912 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2913 pSMB->Reserved4 = 0;
2914 inc_rfc1001_len(pSMB, byte_count);
2915 pSMB->ByteCount = cpu_to_le16(byte_count);
2916 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2917 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2918 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2920 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2923 cifs_buf_release(pSMB);
2926 goto createSymLinkRetry;
2932 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2933 const char *fromName, const char *toName,
2934 const struct nls_table *nls_codepage, int remap)
2936 TRANSACTION2_SPI_REQ *pSMB = NULL;
2937 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2940 int name_len_target;
2942 int bytes_returned = 0;
2943 __u16 params, param_offset, offset, byte_count;
2945 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2946 createHardLinkRetry:
2947 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2952 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2953 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2954 PATH_MAX, nls_codepage, remap);
2955 name_len++; /* trailing null */
2959 name_len = copy_path_name(pSMB->FileName, toName);
2961 params = 6 + name_len;
2962 pSMB->MaxSetupCount = 0;
2966 pSMB->Reserved2 = 0;
2967 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2968 InformationLevel) - 4;
2969 offset = param_offset + params;
2971 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2972 data_offset = (char *)pSMB + offset + 4;
2973 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2975 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2976 PATH_MAX, nls_codepage, remap);
2977 name_len_target++; /* trailing null */
2978 name_len_target *= 2;
2980 name_len_target = copy_path_name(data_offset, fromName);
2983 pSMB->MaxParameterCount = cpu_to_le16(2);
2984 /* BB find exact max on data count below from sess*/
2985 pSMB->MaxDataCount = cpu_to_le16(1000);
2986 pSMB->SetupCount = 1;
2987 pSMB->Reserved3 = 0;
2988 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2989 byte_count = 3 /* pad */ + params + name_len_target;
2990 pSMB->ParameterCount = cpu_to_le16(params);
2991 pSMB->TotalParameterCount = pSMB->ParameterCount;
2992 pSMB->DataCount = cpu_to_le16(name_len_target);
2993 pSMB->TotalDataCount = pSMB->DataCount;
2994 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2995 pSMB->DataOffset = cpu_to_le16(offset);
2996 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2997 pSMB->Reserved4 = 0;
2998 inc_rfc1001_len(pSMB, byte_count);
2999 pSMB->ByteCount = cpu_to_le16(byte_count);
3000 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3001 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3002 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3004 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
3007 cifs_buf_release(pSMB);
3009 goto createHardLinkRetry;
3015 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3016 const char *from_name, const char *to_name,
3017 struct cifs_sb_info *cifs_sb)
3020 NT_RENAME_REQ *pSMB = NULL;
3021 RENAME_RSP *pSMBr = NULL;
3023 int name_len, name_len2;
3025 int remap = cifs_remap(cifs_sb);
3027 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3028 winCreateHardLinkRetry:
3030 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3035 pSMB->SearchAttributes =
3036 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3038 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3039 pSMB->ClusterCount = 0;
3041 pSMB->BufferFormat = 0x04;
3043 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3045 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3046 PATH_MAX, cifs_sb->local_nls, remap);
3047 name_len++; /* trailing null */
3050 /* protocol specifies ASCII buffer format (0x04) for unicode */
3051 pSMB->OldFileName[name_len] = 0x04;
3052 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3054 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3055 to_name, PATH_MAX, cifs_sb->local_nls,
3057 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3058 name_len2 *= 2; /* convert to bytes */
3060 name_len = copy_path_name(pSMB->OldFileName, from_name);
3061 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3062 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
3063 name_len2++; /* signature byte */
3066 count = 1 /* string type byte */ + name_len + name_len2;
3067 inc_rfc1001_len(pSMB, count);
3068 pSMB->ByteCount = cpu_to_le16(count);
3070 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3071 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3072 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3074 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3076 cifs_buf_release(pSMB);
3078 goto winCreateHardLinkRetry;
3084 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3085 const unsigned char *searchName, char **symlinkinfo,
3086 const struct nls_table *nls_codepage, int remap)
3088 /* SMB_QUERY_FILE_UNIX_LINK */
3089 TRANSACTION2_QPI_REQ *pSMB = NULL;
3090 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3094 __u16 params, byte_count;
3097 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3100 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3105 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3107 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3108 searchName, PATH_MAX, nls_codepage,
3110 name_len++; /* trailing null */
3113 name_len = copy_path_name(pSMB->FileName, searchName);
3116 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3117 pSMB->TotalDataCount = 0;
3118 pSMB->MaxParameterCount = cpu_to_le16(2);
3119 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3120 pSMB->MaxSetupCount = 0;
3124 pSMB->Reserved2 = 0;
3125 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3126 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3127 pSMB->DataCount = 0;
3128 pSMB->DataOffset = 0;
3129 pSMB->SetupCount = 1;
3130 pSMB->Reserved3 = 0;
3131 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3132 byte_count = params + 1 /* pad */ ;
3133 pSMB->TotalParameterCount = cpu_to_le16(params);
3134 pSMB->ParameterCount = pSMB->TotalParameterCount;
3135 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3136 pSMB->Reserved4 = 0;
3137 inc_rfc1001_len(pSMB, byte_count);
3138 pSMB->ByteCount = cpu_to_le16(byte_count);
3140 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3141 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3143 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3145 /* decode response */
3147 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3148 /* BB also check enough total bytes returned */
3149 if (rc || get_bcc(&pSMBr->hdr) < 2)
3153 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3155 data_start = ((char *) &pSMBr->hdr.Protocol) +
3156 le16_to_cpu(pSMBr->t2.DataOffset);
3158 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3163 /* BB FIXME investigate remapping reserved chars here */
3164 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3165 count, is_unicode, nls_codepage);
3170 cifs_buf_release(pSMB);
3172 goto querySymLinkRetry;
3177 * Recent Windows versions now create symlinks more frequently
3178 * and they use the "reparse point" mechanism below. We can of course
3179 * do symlinks nicely to Samba and other servers which support the
3180 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3181 * "MF" symlinks optionally, but for recent Windows we really need to
3182 * reenable the code below and fix the cifs_symlink callers to handle this.
3183 * In the interim this code has been moved to its own config option so
3184 * it is not compiled in by default until callers fixed up and more tested.
3187 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3188 __u16 fid, char **symlinkinfo,
3189 const struct nls_table *nls_codepage)
3193 struct smb_com_transaction_ioctl_req *pSMB;
3194 struct smb_com_transaction_ioctl_rsp *pSMBr;
3196 unsigned int sub_len;
3198 struct reparse_symlink_data *reparse_buf;
3199 struct reparse_posix_data *posix_buf;
3200 __u32 data_offset, data_count;
3203 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3204 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3209 pSMB->TotalParameterCount = 0 ;
3210 pSMB->TotalDataCount = 0;
3211 pSMB->MaxParameterCount = cpu_to_le32(2);
3212 /* BB find exact data count max from sess structure BB */
3213 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3214 pSMB->MaxSetupCount = 4;
3216 pSMB->ParameterOffset = 0;
3217 pSMB->DataCount = 0;
3218 pSMB->DataOffset = 0;
3219 pSMB->SetupCount = 4;
3220 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3221 pSMB->ParameterCount = pSMB->TotalParameterCount;
3222 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3223 pSMB->IsFsctl = 1; /* FSCTL */
3224 pSMB->IsRootFlag = 0;
3225 pSMB->Fid = fid; /* file handle always le */
3226 pSMB->ByteCount = 0;
3228 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3229 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3231 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3235 data_offset = le32_to_cpu(pSMBr->DataOffset);
3236 data_count = le32_to_cpu(pSMBr->DataCount);
3237 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3238 /* BB also check enough total bytes returned */
3239 rc = -EIO; /* bad smb */
3242 if (!data_count || (data_count > 2048)) {
3244 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3247 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3248 reparse_buf = (struct reparse_symlink_data *)
3249 ((char *)&pSMBr->hdr.Protocol + data_offset);
3250 if ((char *)reparse_buf >= end_of_smb) {
3254 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3255 cifs_dbg(FYI, "NFS style reparse tag\n");
3256 posix_buf = (struct reparse_posix_data *)reparse_buf;
3258 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3259 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3260 le64_to_cpu(posix_buf->InodeType));
3265 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3266 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3267 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3271 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3272 sub_len, is_unicode, nls_codepage);
3274 } else if (reparse_buf->ReparseTag !=
3275 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3280 /* Reparse tag is NTFS symlink */
3281 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3282 reparse_buf->PathBuffer;
3283 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3284 if (sub_start + sub_len > end_of_smb) {
3285 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3289 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3294 /* BB FIXME investigate remapping reserved chars here */
3295 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3300 cifs_buf_release(pSMB);
3303 * Note: On -EAGAIN error only caller can retry on handle based calls
3304 * since file handle passed in no longer valid.
3310 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3315 struct smb_com_transaction_compr_ioctl_req *pSMB;
3316 struct smb_com_transaction_ioctl_rsp *pSMBr;
3318 cifs_dbg(FYI, "Set compression for %u\n", fid);
3319 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3324 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3326 pSMB->TotalParameterCount = 0;
3327 pSMB->TotalDataCount = cpu_to_le32(2);
3328 pSMB->MaxParameterCount = 0;
3329 pSMB->MaxDataCount = 0;
3330 pSMB->MaxSetupCount = 4;
3332 pSMB->ParameterOffset = 0;
3333 pSMB->DataCount = cpu_to_le32(2);
3335 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3336 compression_state) - 4); /* 84 */
3337 pSMB->SetupCount = 4;
3338 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3339 pSMB->ParameterCount = 0;
3340 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3341 pSMB->IsFsctl = 1; /* FSCTL */
3342 pSMB->IsRootFlag = 0;
3343 pSMB->Fid = fid; /* file handle always le */
3344 /* 3 byte pad, followed by 2 byte compress state */
3345 pSMB->ByteCount = cpu_to_le16(5);
3346 inc_rfc1001_len(pSMB, 5);
3348 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3349 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3351 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3353 cifs_buf_release(pSMB);
3356 * Note: On -EAGAIN error only caller can retry on handle based calls
3357 * since file handle passed in no longer valid.
3363 #ifdef CONFIG_CIFS_POSIX
3365 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3366 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3367 struct cifs_posix_ace *cifs_ace)
3369 /* u8 cifs fields do not need le conversion */
3370 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3371 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3372 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3374 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3375 ace->e_perm, ace->e_tag, ace->e_id);
3381 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3382 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3383 const int acl_type, const int size_of_data_area)
3388 struct cifs_posix_ace *pACE;
3389 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3390 struct posix_acl_xattr_header *local_acl = (void *)trgt;
3392 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3395 if (acl_type == ACL_TYPE_ACCESS) {
3396 count = le16_to_cpu(cifs_acl->access_entry_count);
3397 pACE = &cifs_acl->ace_array[0];
3398 size = sizeof(struct cifs_posix_acl);
3399 size += sizeof(struct cifs_posix_ace) * count;
3400 /* check if we would go beyond end of SMB */
3401 if (size_of_data_area < size) {
3402 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3403 size_of_data_area, size);
3406 } else if (acl_type == ACL_TYPE_DEFAULT) {
3407 count = le16_to_cpu(cifs_acl->access_entry_count);
3408 size = sizeof(struct cifs_posix_acl);
3409 size += sizeof(struct cifs_posix_ace) * count;
3410 /* skip past access ACEs to get to default ACEs */
3411 pACE = &cifs_acl->ace_array[count];
3412 count = le16_to_cpu(cifs_acl->default_entry_count);
3413 size += sizeof(struct cifs_posix_ace) * count;
3414 /* check if we would go beyond end of SMB */
3415 if (size_of_data_area < size)
3422 size = posix_acl_xattr_size(count);
3423 if ((buflen == 0) || (local_acl == NULL)) {
3424 /* used to query ACL EA size */
3425 } else if (size > buflen) {
3427 } else /* buffer big enough */ {
3428 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3430 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3431 for (i = 0; i < count ; i++) {
3432 cifs_convert_ace(&ace[i], pACE);
3439 static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3440 const struct posix_acl_xattr_entry *local_ace)
3442 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3443 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3444 /* BB is there a better way to handle the large uid? */
3445 if (local_ace->e_id == cpu_to_le32(-1)) {
3446 /* Probably no need to le convert -1 on any arch but can not hurt */
3447 cifs_ace->cifs_uid = cpu_to_le64(-1);
3449 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3451 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3452 ace->e_perm, ace->e_tag, ace->e_id);
3456 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3457 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3458 const int buflen, const int acl_type)
3461 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3462 struct posix_acl_xattr_header *local_acl = (void *)pACL;
3463 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3467 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3470 count = posix_acl_xattr_count((size_t)buflen);
3471 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3472 count, buflen, le32_to_cpu(local_acl->a_version));
3473 if (le32_to_cpu(local_acl->a_version) != 2) {
3474 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3475 le32_to_cpu(local_acl->a_version));
3478 cifs_acl->version = cpu_to_le16(1);
3479 if (acl_type == ACL_TYPE_ACCESS) {
3480 cifs_acl->access_entry_count = cpu_to_le16(count);
3481 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3482 } else if (acl_type == ACL_TYPE_DEFAULT) {
3483 cifs_acl->default_entry_count = cpu_to_le16(count);
3484 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3486 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3489 for (i = 0; i < count; i++)
3490 convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3492 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3493 rc += sizeof(struct cifs_posix_acl);
3494 /* BB add check to make sure ACL does not overflow SMB */
3500 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3501 const unsigned char *searchName,
3502 char *acl_inf, const int buflen, const int acl_type,
3503 const struct nls_table *nls_codepage, int remap)
3505 /* SMB_QUERY_POSIX_ACL */
3506 TRANSACTION2_QPI_REQ *pSMB = NULL;
3507 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3511 __u16 params, byte_count;
3513 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3516 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3521 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3523 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3524 searchName, PATH_MAX, nls_codepage,
3526 name_len++; /* trailing null */
3528 pSMB->FileName[name_len] = 0;
3529 pSMB->FileName[name_len+1] = 0;
3531 name_len = copy_path_name(pSMB->FileName, searchName);
3534 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3535 pSMB->TotalDataCount = 0;
3536 pSMB->MaxParameterCount = cpu_to_le16(2);
3537 /* BB find exact max data count below from sess structure BB */
3538 pSMB->MaxDataCount = cpu_to_le16(4000);
3539 pSMB->MaxSetupCount = 0;
3543 pSMB->Reserved2 = 0;
3544 pSMB->ParameterOffset = cpu_to_le16(
3545 offsetof(struct smb_com_transaction2_qpi_req,
3546 InformationLevel) - 4);
3547 pSMB->DataCount = 0;
3548 pSMB->DataOffset = 0;
3549 pSMB->SetupCount = 1;
3550 pSMB->Reserved3 = 0;
3551 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3552 byte_count = params + 1 /* pad */ ;
3553 pSMB->TotalParameterCount = cpu_to_le16(params);
3554 pSMB->ParameterCount = pSMB->TotalParameterCount;
3555 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3556 pSMB->Reserved4 = 0;
3557 inc_rfc1001_len(pSMB, byte_count);
3558 pSMB->ByteCount = cpu_to_le16(byte_count);
3560 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3561 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3562 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3564 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3566 /* decode response */
3568 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3569 /* BB also check enough total bytes returned */
3570 if (rc || get_bcc(&pSMBr->hdr) < 2)
3571 rc = -EIO; /* bad smb */
3573 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3574 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3575 rc = cifs_copy_posix_acl(acl_inf,
3576 (char *)&pSMBr->hdr.Protocol+data_offset,
3577 buflen, acl_type, count);
3580 cifs_buf_release(pSMB);
3587 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3588 const unsigned char *fileName,
3589 const char *local_acl, const int buflen,
3591 const struct nls_table *nls_codepage, int remap)
3593 struct smb_com_transaction2_spi_req *pSMB = NULL;
3594 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3598 int bytes_returned = 0;
3599 __u16 params, byte_count, data_count, param_offset, offset;
3601 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3603 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3607 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3609 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3610 PATH_MAX, nls_codepage, remap);
3611 name_len++; /* trailing null */
3614 name_len = copy_path_name(pSMB->FileName, fileName);
3616 params = 6 + name_len;
3617 pSMB->MaxParameterCount = cpu_to_le16(2);
3618 /* BB find max SMB size from sess */
3619 pSMB->MaxDataCount = cpu_to_le16(1000);
3620 pSMB->MaxSetupCount = 0;
3624 pSMB->Reserved2 = 0;
3625 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3626 InformationLevel) - 4;
3627 offset = param_offset + params;
3628 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3629 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3631 /* convert to on the wire format for POSIX ACL */
3632 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3634 if (data_count == 0) {
3636 goto setACLerrorExit;
3638 pSMB->DataOffset = cpu_to_le16(offset);
3639 pSMB->SetupCount = 1;
3640 pSMB->Reserved3 = 0;
3641 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3642 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3643 byte_count = 3 /* pad */ + params + data_count;
3644 pSMB->DataCount = cpu_to_le16(data_count);
3645 pSMB->TotalDataCount = pSMB->DataCount;
3646 pSMB->ParameterCount = cpu_to_le16(params);
3647 pSMB->TotalParameterCount = pSMB->ParameterCount;
3648 pSMB->Reserved4 = 0;
3649 inc_rfc1001_len(pSMB, byte_count);
3650 pSMB->ByteCount = cpu_to_le16(byte_count);
3651 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3652 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3654 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3657 cifs_buf_release(pSMB);
3663 /* BB fix tabs in this function FIXME BB */
3665 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3666 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3669 struct smb_t2_qfi_req *pSMB = NULL;
3670 struct smb_t2_qfi_rsp *pSMBr = NULL;
3672 __u16 params, byte_count;
3674 cifs_dbg(FYI, "In GetExtAttr\n");
3679 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3684 params = 2 /* level */ + 2 /* fid */;
3685 pSMB->t2.TotalDataCount = 0;
3686 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3687 /* BB find exact max data count below from sess structure BB */
3688 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3689 pSMB->t2.MaxSetupCount = 0;
3690 pSMB->t2.Reserved = 0;
3692 pSMB->t2.Timeout = 0;
3693 pSMB->t2.Reserved2 = 0;
3694 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3696 pSMB->t2.DataCount = 0;
3697 pSMB->t2.DataOffset = 0;
3698 pSMB->t2.SetupCount = 1;
3699 pSMB->t2.Reserved3 = 0;
3700 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3701 byte_count = params + 1 /* pad */ ;
3702 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3703 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3704 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3707 inc_rfc1001_len(pSMB, byte_count);
3708 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3710 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3711 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3713 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3715 /* decode response */
3716 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3717 /* BB also check enough total bytes returned */
3718 if (rc || get_bcc(&pSMBr->hdr) < 2)
3719 /* If rc should we check for EOPNOSUPP and
3720 disable the srvino flag? or in caller? */
3721 rc = -EIO; /* bad smb */
3723 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3724 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3725 struct file_chattr_info *pfinfo;
3726 /* BB Do we need a cast or hash here ? */
3728 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3732 pfinfo = (struct file_chattr_info *)
3733 (data_offset + (char *) &pSMBr->hdr.Protocol);
3734 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3735 *pMask = le64_to_cpu(pfinfo->mask);
3739 cifs_buf_release(pSMB);
3741 goto GetExtAttrRetry;
3745 #endif /* CONFIG_POSIX */
3748 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3749 * all NT TRANSACTS that we init here have total parm and data under about 400
3750 * bytes (to fit in small cifs buffer size), which is the case so far, it
3751 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3752 * returned setup area) and MaxParameterCount (returned parms size) must be set
3756 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3757 const int parm_len, struct cifs_tcon *tcon,
3762 struct smb_com_ntransact_req *pSMB;
3764 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3768 *ret_buf = (void *)pSMB;
3770 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3771 pSMB->TotalDataCount = 0;
3772 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3773 pSMB->ParameterCount = pSMB->TotalParameterCount;
3774 pSMB->DataCount = pSMB->TotalDataCount;
3775 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3776 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3777 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3778 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3779 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3780 pSMB->SubCommand = cpu_to_le16(sub_command);
3785 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3786 __u32 *pparmlen, __u32 *pdatalen)
3789 __u32 data_count, data_offset, parm_count, parm_offset;
3790 struct smb_com_ntransact_rsp *pSMBr;
3799 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3801 bcc = get_bcc(&pSMBr->hdr);
3802 end_of_smb = 2 /* sizeof byte count */ + bcc +
3803 (char *)&pSMBr->ByteCount;
3805 data_offset = le32_to_cpu(pSMBr->DataOffset);
3806 data_count = le32_to_cpu(pSMBr->DataCount);
3807 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3808 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3810 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3811 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3813 /* should we also check that parm and data areas do not overlap? */
3814 if (*ppparm > end_of_smb) {
3815 cifs_dbg(FYI, "parms start after end of smb\n");
3817 } else if (parm_count + *ppparm > end_of_smb) {
3818 cifs_dbg(FYI, "parm end after end of smb\n");
3820 } else if (*ppdata > end_of_smb) {
3821 cifs_dbg(FYI, "data starts after end of smb\n");
3823 } else if (data_count + *ppdata > end_of_smb) {
3824 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3825 *ppdata, data_count, (data_count + *ppdata),
3828 } else if (parm_count + data_count > bcc) {
3829 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3832 *pdatalen = data_count;
3833 *pparmlen = parm_count;
3837 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3839 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3840 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3844 QUERY_SEC_DESC_REQ *pSMB;
3846 struct kvec rsp_iov;
3848 cifs_dbg(FYI, "GetCifsACL\n");
3853 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3854 8 /* parm len */, tcon, (void **) &pSMB);
3858 pSMB->MaxParameterCount = cpu_to_le32(4);
3859 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3860 pSMB->MaxSetupCount = 0;
3861 pSMB->Fid = fid; /* file handle always le */
3862 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3864 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3865 inc_rfc1001_len(pSMB, 11);
3866 iov[0].iov_base = (char *)pSMB;
3867 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3869 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3871 cifs_small_buf_release(pSMB);
3872 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3874 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3875 } else { /* decode response */
3879 struct smb_com_ntransact_rsp *pSMBr;
3882 /* validate_nttransact */
3883 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3884 &pdata, &parm_len, pbuflen);
3887 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3889 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3890 pSMBr, parm, *acl_inf);
3892 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3893 rc = -EIO; /* bad smb */
3898 /* BB check that data area is minimum length and as big as acl_len */
3900 acl_len = le32_to_cpu(*parm);
3901 if (acl_len != *pbuflen) {
3902 cifs_dbg(VFS, "acl length %d does not match %d\n",
3904 if (*pbuflen > acl_len)
3908 /* check if buffer is big enough for the acl
3909 header followed by the smallest SID */
3910 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3911 (*pbuflen >= 64 * 1024)) {
3912 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3916 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3917 if (*acl_inf == NULL) {
3924 free_rsp_buf(buf_type, rsp_iov.iov_base);
3929 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3930 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3932 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3934 int bytes_returned = 0;
3935 SET_SEC_DESC_REQ *pSMB = NULL;
3939 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3943 pSMB->MaxSetupCount = 0;
3947 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3948 data_count = acllen;
3949 data_offset = param_offset + param_count;
3950 byte_count = 3 /* pad */ + param_count;
3952 pSMB->DataCount = cpu_to_le32(data_count);
3953 pSMB->TotalDataCount = pSMB->DataCount;
3954 pSMB->MaxParameterCount = cpu_to_le32(4);
3955 pSMB->MaxDataCount = cpu_to_le32(16384);
3956 pSMB->ParameterCount = cpu_to_le32(param_count);
3957 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3958 pSMB->TotalParameterCount = pSMB->ParameterCount;
3959 pSMB->DataOffset = cpu_to_le32(data_offset);
3960 pSMB->SetupCount = 0;
3961 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3962 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3964 pSMB->Fid = fid; /* file handle always le */
3965 pSMB->Reserved2 = 0;
3966 pSMB->AclFlags = cpu_to_le32(aclflag);
3968 if (pntsd && acllen) {
3969 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3970 data_offset, pntsd, acllen);
3971 inc_rfc1001_len(pSMB, byte_count + data_count);
3973 inc_rfc1001_len(pSMB, byte_count);
3975 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3976 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3978 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3979 bytes_returned, rc);
3981 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3982 cifs_buf_release(pSMB);
3985 goto setCifsAclRetry;
3991 /* Legacy Query Path Information call for lookup to old servers such
3994 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3995 const char *search_name, FILE_ALL_INFO *data,
3996 const struct nls_table *nls_codepage, int remap)
3998 QUERY_INFORMATION_REQ *pSMB;
3999 QUERY_INFORMATION_RSP *pSMBr;
4004 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
4006 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
4011 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4013 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4014 search_name, PATH_MAX, nls_codepage,
4016 name_len++; /* trailing null */
4019 name_len = copy_path_name(pSMB->FileName, search_name);
4021 pSMB->BufferFormat = 0x04;
4022 name_len++; /* account for buffer type byte */
4023 inc_rfc1001_len(pSMB, (__u16)name_len);
4024 pSMB->ByteCount = cpu_to_le16(name_len);
4026 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4027 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4029 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4031 struct timespec64 ts;
4032 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4034 /* decode response */
4035 /* BB FIXME - add time zone adjustment BB */
4036 memset(data, 0, sizeof(FILE_ALL_INFO));
4039 /* decode time fields */
4040 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4041 data->LastWriteTime = data->ChangeTime;
4042 data->LastAccessTime = 0;
4043 data->AllocationSize =
4044 cpu_to_le64(le32_to_cpu(pSMBr->size));
4045 data->EndOfFile = data->AllocationSize;
4047 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4049 rc = -EIO; /* bad buffer passed in */
4051 cifs_buf_release(pSMB);
4060 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4061 u16 netfid, FILE_ALL_INFO *pFindData)
4063 struct smb_t2_qfi_req *pSMB = NULL;
4064 struct smb_t2_qfi_rsp *pSMBr = NULL;
4067 __u16 params, byte_count;
4070 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4075 params = 2 /* level */ + 2 /* fid */;
4076 pSMB->t2.TotalDataCount = 0;
4077 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4078 /* BB find exact max data count below from sess structure BB */
4079 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4080 pSMB->t2.MaxSetupCount = 0;
4081 pSMB->t2.Reserved = 0;
4083 pSMB->t2.Timeout = 0;
4084 pSMB->t2.Reserved2 = 0;
4085 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4087 pSMB->t2.DataCount = 0;
4088 pSMB->t2.DataOffset = 0;
4089 pSMB->t2.SetupCount = 1;
4090 pSMB->t2.Reserved3 = 0;
4091 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4092 byte_count = params + 1 /* pad */ ;
4093 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4094 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4095 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4098 inc_rfc1001_len(pSMB, byte_count);
4099 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4101 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4102 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4104 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
4105 } else { /* decode response */
4106 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4108 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4110 else if (get_bcc(&pSMBr->hdr) < 40)
4111 rc = -EIO; /* bad smb */
4112 else if (pFindData) {
4113 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4114 memcpy((char *) pFindData,
4115 (char *) &pSMBr->hdr.Protocol +
4116 data_offset, sizeof(FILE_ALL_INFO));
4120 cifs_buf_release(pSMB);
4122 goto QFileInfoRetry;
4128 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4129 const char *search_name, FILE_ALL_INFO *data,
4130 int legacy /* old style infolevel */,
4131 const struct nls_table *nls_codepage, int remap)
4133 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4134 TRANSACTION2_QPI_REQ *pSMB = NULL;
4135 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4139 __u16 params, byte_count;
4141 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4143 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4148 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4150 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4151 PATH_MAX, nls_codepage, remap);
4152 name_len++; /* trailing null */
4155 name_len = copy_path_name(pSMB->FileName, search_name);
4158 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4159 pSMB->TotalDataCount = 0;
4160 pSMB->MaxParameterCount = cpu_to_le16(2);
4161 /* BB find exact max SMB PDU from sess structure BB */
4162 pSMB->MaxDataCount = cpu_to_le16(4000);
4163 pSMB->MaxSetupCount = 0;
4167 pSMB->Reserved2 = 0;
4168 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4169 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4170 pSMB->DataCount = 0;
4171 pSMB->DataOffset = 0;
4172 pSMB->SetupCount = 1;
4173 pSMB->Reserved3 = 0;
4174 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4175 byte_count = params + 1 /* pad */ ;
4176 pSMB->TotalParameterCount = cpu_to_le16(params);
4177 pSMB->ParameterCount = pSMB->TotalParameterCount;
4179 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4181 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4182 pSMB->Reserved4 = 0;
4183 inc_rfc1001_len(pSMB, byte_count);
4184 pSMB->ByteCount = cpu_to_le16(byte_count);
4186 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4187 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4189 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4190 } else { /* decode response */
4191 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4193 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4195 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4196 rc = -EIO; /* bad smb */
4197 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4198 rc = -EIO; /* 24 or 26 expected but we do not read
4202 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4205 * On legacy responses we do not read the last field,
4206 * EAsize, fortunately since it varies by subdialect and
4207 * also note it differs on Set vs Get, ie two bytes or 4
4208 * bytes depending but we don't care here.
4211 size = sizeof(FILE_INFO_STANDARD);
4213 size = sizeof(FILE_ALL_INFO);
4214 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4219 cifs_buf_release(pSMB);
4221 goto QPathInfoRetry;
4227 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4228 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4230 struct smb_t2_qfi_req *pSMB = NULL;
4231 struct smb_t2_qfi_rsp *pSMBr = NULL;
4234 __u16 params, byte_count;
4237 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4242 params = 2 /* level */ + 2 /* fid */;
4243 pSMB->t2.TotalDataCount = 0;
4244 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4245 /* BB find exact max data count below from sess structure BB */
4246 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4247 pSMB->t2.MaxSetupCount = 0;
4248 pSMB->t2.Reserved = 0;
4250 pSMB->t2.Timeout = 0;
4251 pSMB->t2.Reserved2 = 0;
4252 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4254 pSMB->t2.DataCount = 0;
4255 pSMB->t2.DataOffset = 0;
4256 pSMB->t2.SetupCount = 1;
4257 pSMB->t2.Reserved3 = 0;
4258 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4259 byte_count = params + 1 /* pad */ ;
4260 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4261 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4262 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4265 inc_rfc1001_len(pSMB, byte_count);
4266 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4268 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4269 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4271 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
4272 } else { /* decode response */
4273 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4275 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4276 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4277 rc = -EIO; /* bad smb */
4279 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4280 memcpy((char *) pFindData,
4281 (char *) &pSMBr->hdr.Protocol +
4283 sizeof(FILE_UNIX_BASIC_INFO));
4287 cifs_buf_release(pSMB);
4289 goto UnixQFileInfoRetry;
4295 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4296 const unsigned char *searchName,
4297 FILE_UNIX_BASIC_INFO *pFindData,
4298 const struct nls_table *nls_codepage, int remap)
4300 /* SMB_QUERY_FILE_UNIX_BASIC */
4301 TRANSACTION2_QPI_REQ *pSMB = NULL;
4302 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4304 int bytes_returned = 0;
4306 __u16 params, byte_count;
4308 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4310 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4315 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4317 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4318 PATH_MAX, nls_codepage, remap);
4319 name_len++; /* trailing null */
4322 name_len = copy_path_name(pSMB->FileName, searchName);
4325 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4326 pSMB->TotalDataCount = 0;
4327 pSMB->MaxParameterCount = cpu_to_le16(2);
4328 /* BB find exact max SMB PDU from sess structure BB */
4329 pSMB->MaxDataCount = cpu_to_le16(4000);
4330 pSMB->MaxSetupCount = 0;
4334 pSMB->Reserved2 = 0;
4335 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4336 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4337 pSMB->DataCount = 0;
4338 pSMB->DataOffset = 0;
4339 pSMB->SetupCount = 1;
4340 pSMB->Reserved3 = 0;
4341 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4342 byte_count = params + 1 /* pad */ ;
4343 pSMB->TotalParameterCount = cpu_to_le16(params);
4344 pSMB->ParameterCount = pSMB->TotalParameterCount;
4345 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4346 pSMB->Reserved4 = 0;
4347 inc_rfc1001_len(pSMB, byte_count);
4348 pSMB->ByteCount = cpu_to_le16(byte_count);
4350 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4351 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4353 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
4354 } else { /* decode response */
4355 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4357 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4358 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4359 rc = -EIO; /* bad smb */
4361 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4362 memcpy((char *) pFindData,
4363 (char *) &pSMBr->hdr.Protocol +
4365 sizeof(FILE_UNIX_BASIC_INFO));
4368 cifs_buf_release(pSMB);
4370 goto UnixQPathInfoRetry;
4375 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4377 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4378 const char *searchName, struct cifs_sb_info *cifs_sb,
4379 __u16 *pnetfid, __u16 search_flags,
4380 struct cifs_search_info *psrch_inf, bool msearch)
4382 /* level 257 SMB_ */
4383 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4384 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4385 T2_FFIRST_RSP_PARMS *parms;
4387 int bytes_returned = 0;
4388 int name_len, remap;
4389 __u16 params, byte_count;
4390 struct nls_table *nls_codepage;
4392 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4395 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4400 nls_codepage = cifs_sb->local_nls;
4401 remap = cifs_remap(cifs_sb);
4403 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4405 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4406 PATH_MAX, nls_codepage, remap);
4407 /* We can not add the asterik earlier in case
4408 it got remapped to 0xF03A as if it were part of the
4409 directory name instead of a wildcard */
4412 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4413 pSMB->FileName[name_len+1] = 0;
4414 pSMB->FileName[name_len+2] = '*';
4415 pSMB->FileName[name_len+3] = 0;
4416 name_len += 4; /* now the trailing null */
4417 /* null terminate just in case */
4418 pSMB->FileName[name_len] = 0;
4419 pSMB->FileName[name_len+1] = 0;
4423 name_len = copy_path_name(pSMB->FileName, searchName);
4425 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4426 name_len = PATH_MAX-2;
4427 /* overwrite nul byte */
4428 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4429 pSMB->FileName[name_len] = '*';
4430 pSMB->FileName[name_len+1] = 0;
4435 params = 12 + name_len /* includes null */ ;
4436 pSMB->TotalDataCount = 0; /* no EAs */
4437 pSMB->MaxParameterCount = cpu_to_le16(10);
4438 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4439 pSMB->MaxSetupCount = 0;
4443 pSMB->Reserved2 = 0;
4444 byte_count = params + 1 /* pad */ ;
4445 pSMB->TotalParameterCount = cpu_to_le16(params);
4446 pSMB->ParameterCount = pSMB->TotalParameterCount;
4447 pSMB->ParameterOffset = cpu_to_le16(
4448 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4450 pSMB->DataCount = 0;
4451 pSMB->DataOffset = 0;
4452 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4453 pSMB->Reserved3 = 0;
4454 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4455 pSMB->SearchAttributes =
4456 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4458 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4459 pSMB->SearchFlags = cpu_to_le16(search_flags);
4460 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4462 /* BB what should we set StorageType to? Does it matter? BB */
4463 pSMB->SearchStorageType = 0;
4464 inc_rfc1001_len(pSMB, byte_count);
4465 pSMB->ByteCount = cpu_to_le16(byte_count);
4467 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4468 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4469 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4471 if (rc) {/* BB add logic to retry regular search if Unix search
4472 rejected unexpectedly by server */
4473 /* BB Add code to handle unsupported level rc */
4474 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4476 cifs_buf_release(pSMB);
4478 /* BB eventually could optimize out free and realloc of buf */
4481 goto findFirstRetry;
4482 } else { /* decode response */
4483 /* BB remember to free buffer if error BB */
4484 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4488 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4489 psrch_inf->unicode = true;
4491 psrch_inf->unicode = false;
4493 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4494 psrch_inf->smallBuf = false;
4495 psrch_inf->srch_entries_start =
4496 (char *) &pSMBr->hdr.Protocol +
4497 le16_to_cpu(pSMBr->t2.DataOffset);
4498 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4499 le16_to_cpu(pSMBr->t2.ParameterOffset));
4501 if (parms->EndofSearch)
4502 psrch_inf->endOfSearch = true;
4504 psrch_inf->endOfSearch = false;
4506 psrch_inf->entries_in_buffer =
4507 le16_to_cpu(parms->SearchCount);
4508 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4509 psrch_inf->entries_in_buffer;
4510 lnoff = le16_to_cpu(parms->LastNameOffset);
4511 if (CIFSMaxBufSize < lnoff) {
4512 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4513 psrch_inf->last_entry = NULL;
4517 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4521 *pnetfid = parms->SearchHandle;
4523 cifs_buf_release(pSMB);
4530 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4531 __u16 searchHandle, __u16 search_flags,
4532 struct cifs_search_info *psrch_inf)
4534 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4535 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4536 T2_FNEXT_RSP_PARMS *parms;
4537 char *response_data;
4540 unsigned int name_len;
4541 __u16 params, byte_count;
4543 cifs_dbg(FYI, "In FindNext\n");
4545 if (psrch_inf->endOfSearch)
4548 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4553 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4555 pSMB->TotalDataCount = 0; /* no EAs */
4556 pSMB->MaxParameterCount = cpu_to_le16(8);
4557 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4558 pSMB->MaxSetupCount = 0;
4562 pSMB->Reserved2 = 0;
4563 pSMB->ParameterOffset = cpu_to_le16(
4564 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4565 pSMB->DataCount = 0;
4566 pSMB->DataOffset = 0;
4567 pSMB->SetupCount = 1;
4568 pSMB->Reserved3 = 0;
4569 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4570 pSMB->SearchHandle = searchHandle; /* always kept as le */
4572 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4573 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4574 pSMB->ResumeKey = psrch_inf->resume_key;
4575 pSMB->SearchFlags = cpu_to_le16(search_flags);
4577 name_len = psrch_inf->resume_name_len;
4579 if (name_len < PATH_MAX) {
4580 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4581 byte_count += name_len;
4582 /* 14 byte parm len above enough for 2 byte null terminator */
4583 pSMB->ResumeFileName[name_len] = 0;
4584 pSMB->ResumeFileName[name_len+1] = 0;
4587 goto FNext2_err_exit;
4589 byte_count = params + 1 /* pad */ ;
4590 pSMB->TotalParameterCount = cpu_to_le16(params);
4591 pSMB->ParameterCount = pSMB->TotalParameterCount;
4592 inc_rfc1001_len(pSMB, byte_count);
4593 pSMB->ByteCount = cpu_to_le16(byte_count);
4595 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4596 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4597 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4600 psrch_inf->endOfSearch = true;
4601 cifs_buf_release(pSMB);
4602 rc = 0; /* search probably was closed at end of search*/
4604 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4605 } else { /* decode response */
4606 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4611 /* BB fixme add lock for file (srch_info) struct here */
4612 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4613 psrch_inf->unicode = true;
4615 psrch_inf->unicode = false;
4616 response_data = (char *) &pSMBr->hdr.Protocol +
4617 le16_to_cpu(pSMBr->t2.ParameterOffset);
4618 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4619 response_data = (char *)&pSMBr->hdr.Protocol +
4620 le16_to_cpu(pSMBr->t2.DataOffset);
4621 if (psrch_inf->smallBuf)
4622 cifs_small_buf_release(
4623 psrch_inf->ntwrk_buf_start);
4625 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4626 psrch_inf->srch_entries_start = response_data;
4627 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4628 psrch_inf->smallBuf = false;
4629 if (parms->EndofSearch)
4630 psrch_inf->endOfSearch = true;
4632 psrch_inf->endOfSearch = false;
4633 psrch_inf->entries_in_buffer =
4634 le16_to_cpu(parms->SearchCount);
4635 psrch_inf->index_of_last_entry +=
4636 psrch_inf->entries_in_buffer;
4637 lnoff = le16_to_cpu(parms->LastNameOffset);
4638 if (CIFSMaxBufSize < lnoff) {
4639 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4640 psrch_inf->last_entry = NULL;
4643 psrch_inf->last_entry =
4644 psrch_inf->srch_entries_start + lnoff;
4646 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4647 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4649 /* BB fixme add unlock here */
4654 /* BB On error, should we leave previous search buf (and count and
4655 last entry fields) intact or free the previous one? */
4657 /* Note: On -EAGAIN error only caller can retry on handle based calls
4658 since file handle passed in no longer valid */
4661 cifs_buf_release(pSMB);
4666 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4667 const __u16 searchHandle)
4670 FINDCLOSE_REQ *pSMB = NULL;
4672 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4673 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4675 /* no sense returning error if session restarted
4676 as file handle has been closed */
4682 pSMB->FileID = searchHandle;
4683 pSMB->ByteCount = 0;
4684 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4685 cifs_small_buf_release(pSMB);
4687 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4689 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4691 /* Since session is dead, search handle closed on server already */
4699 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4700 const char *search_name, __u64 *inode_number,
4701 const struct nls_table *nls_codepage, int remap)
4704 TRANSACTION2_QPI_REQ *pSMB = NULL;
4705 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4706 int name_len, bytes_returned;
4707 __u16 params, byte_count;
4709 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4713 GetInodeNumberRetry:
4714 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4719 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4721 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4722 search_name, PATH_MAX, nls_codepage,
4724 name_len++; /* trailing null */
4727 name_len = copy_path_name(pSMB->FileName, search_name);
4730 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4731 pSMB->TotalDataCount = 0;
4732 pSMB->MaxParameterCount = cpu_to_le16(2);
4733 /* BB find exact max data count below from sess structure BB */
4734 pSMB->MaxDataCount = cpu_to_le16(4000);
4735 pSMB->MaxSetupCount = 0;
4739 pSMB->Reserved2 = 0;
4740 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4741 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4742 pSMB->DataCount = 0;
4743 pSMB->DataOffset = 0;
4744 pSMB->SetupCount = 1;
4745 pSMB->Reserved3 = 0;
4746 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4747 byte_count = params + 1 /* pad */ ;
4748 pSMB->TotalParameterCount = cpu_to_le16(params);
4749 pSMB->ParameterCount = pSMB->TotalParameterCount;
4750 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4751 pSMB->Reserved4 = 0;
4752 inc_rfc1001_len(pSMB, byte_count);
4753 pSMB->ByteCount = cpu_to_le16(byte_count);
4755 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4756 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4758 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4760 /* decode response */
4761 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4762 /* BB also check enough total bytes returned */
4763 if (rc || get_bcc(&pSMBr->hdr) < 2)
4764 /* If rc should we check for EOPNOSUPP and
4765 disable the srvino flag? or in caller? */
4766 rc = -EIO; /* bad smb */
4768 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4769 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4770 struct file_internal_info *pfinfo;
4771 /* BB Do we need a cast or hash here ? */
4773 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4775 goto GetInodeNumOut;
4777 pfinfo = (struct file_internal_info *)
4778 (data_offset + (char *) &pSMBr->hdr.Protocol);
4779 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4783 cifs_buf_release(pSMB);
4785 goto GetInodeNumberRetry;
4790 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4791 const char *search_name, struct dfs_info3_param **target_nodes,
4792 unsigned int *num_of_nodes,
4793 const struct nls_table *nls_codepage, int remap)
4795 /* TRANS2_GET_DFS_REFERRAL */
4796 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4797 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4801 __u16 params, byte_count;
4803 *target_nodes = NULL;
4805 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4806 if (ses == NULL || ses->tcon_ipc == NULL)
4810 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4815 /* server pointer checked in called function,
4816 but should never be null here anyway */
4817 pSMB->hdr.Mid = get_next_mid(ses->server);
4818 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4819 pSMB->hdr.Uid = ses->Suid;
4820 if (ses->capabilities & CAP_STATUS32)
4821 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4822 if (ses->capabilities & CAP_DFS)
4823 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4825 if (ses->capabilities & CAP_UNICODE) {
4826 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4828 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4829 search_name, PATH_MAX, nls_codepage,
4831 name_len++; /* trailing null */
4833 } else { /* BB improve the check for buffer overruns BB */
4834 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4837 if (ses->server->sign)
4838 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4840 pSMB->hdr.Uid = ses->Suid;
4842 params = 2 /* level */ + name_len /*includes null */ ;
4843 pSMB->TotalDataCount = 0;
4844 pSMB->DataCount = 0;
4845 pSMB->DataOffset = 0;
4846 pSMB->MaxParameterCount = 0;
4847 /* BB find exact max SMB PDU from sess structure BB */
4848 pSMB->MaxDataCount = cpu_to_le16(4000);
4849 pSMB->MaxSetupCount = 0;
4853 pSMB->Reserved2 = 0;
4854 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4855 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4856 pSMB->SetupCount = 1;
4857 pSMB->Reserved3 = 0;
4858 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4859 byte_count = params + 3 /* pad */ ;
4860 pSMB->ParameterCount = cpu_to_le16(params);
4861 pSMB->TotalParameterCount = pSMB->ParameterCount;
4862 pSMB->MaxReferralLevel = cpu_to_le16(3);
4863 inc_rfc1001_len(pSMB, byte_count);
4864 pSMB->ByteCount = cpu_to_le16(byte_count);
4866 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4867 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4869 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4872 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4874 /* BB Also check if enough total bytes returned? */
4875 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4876 rc = -EIO; /* bad smb */
4880 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4881 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4883 /* parse returned result into more usable form */
4884 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4885 le16_to_cpu(pSMBr->t2.DataCount),
4886 num_of_nodes, target_nodes, nls_codepage,
4888 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4891 cifs_buf_release(pSMB);
4899 /* Query File System Info such as free space to old servers such as Win 9x */
4901 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4902 struct kstatfs *FSData)
4904 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4905 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4906 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4907 FILE_SYSTEM_ALLOC_INFO *response_data;
4909 int bytes_returned = 0;
4910 __u16 params, byte_count;
4912 cifs_dbg(FYI, "OldQFSInfo\n");
4914 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4919 params = 2; /* level */
4920 pSMB->TotalDataCount = 0;
4921 pSMB->MaxParameterCount = cpu_to_le16(2);
4922 pSMB->MaxDataCount = cpu_to_le16(1000);
4923 pSMB->MaxSetupCount = 0;
4927 pSMB->Reserved2 = 0;
4928 byte_count = params + 1 /* pad */ ;
4929 pSMB->TotalParameterCount = cpu_to_le16(params);
4930 pSMB->ParameterCount = pSMB->TotalParameterCount;
4931 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4932 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4933 pSMB->DataCount = 0;
4934 pSMB->DataOffset = 0;
4935 pSMB->SetupCount = 1;
4936 pSMB->Reserved3 = 0;
4937 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4938 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4939 inc_rfc1001_len(pSMB, byte_count);
4940 pSMB->ByteCount = cpu_to_le16(byte_count);
4942 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4943 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4945 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4946 } else { /* decode response */
4947 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4949 if (rc || get_bcc(&pSMBr->hdr) < 18)
4950 rc = -EIO; /* bad smb */
4952 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4953 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4954 get_bcc(&pSMBr->hdr), data_offset);
4956 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4957 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4959 le16_to_cpu(response_data->BytesPerSector) *
4960 le32_to_cpu(response_data->
4961 SectorsPerAllocationUnit);
4963 * much prefer larger but if server doesn't report
4964 * a valid size than 4K is a reasonable minimum
4966 if (FSData->f_bsize < 512)
4967 FSData->f_bsize = 4096;
4970 le32_to_cpu(response_data->TotalAllocationUnits);
4971 FSData->f_bfree = FSData->f_bavail =
4972 le32_to_cpu(response_data->FreeAllocationUnits);
4973 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4974 (unsigned long long)FSData->f_blocks,
4975 (unsigned long long)FSData->f_bfree,
4979 cifs_buf_release(pSMB);
4982 goto oldQFSInfoRetry;
4988 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4989 struct kstatfs *FSData)
4991 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4992 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4993 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4994 FILE_SYSTEM_INFO *response_data;
4996 int bytes_returned = 0;
4997 __u16 params, byte_count;
4999 cifs_dbg(FYI, "In QFSInfo\n");
5001 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5006 params = 2; /* level */
5007 pSMB->TotalDataCount = 0;
5008 pSMB->MaxParameterCount = cpu_to_le16(2);
5009 pSMB->MaxDataCount = cpu_to_le16(1000);
5010 pSMB->MaxSetupCount = 0;
5014 pSMB->Reserved2 = 0;
5015 byte_count = params + 1 /* pad */ ;
5016 pSMB->TotalParameterCount = cpu_to_le16(params);
5017 pSMB->ParameterCount = pSMB->TotalParameterCount;
5018 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5019 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5020 pSMB->DataCount = 0;
5021 pSMB->DataOffset = 0;
5022 pSMB->SetupCount = 1;
5023 pSMB->Reserved3 = 0;
5024 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5025 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5026 inc_rfc1001_len(pSMB, byte_count);
5027 pSMB->ByteCount = cpu_to_le16(byte_count);
5029 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5030 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5032 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5033 } else { /* decode response */
5034 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5036 if (rc || get_bcc(&pSMBr->hdr) < 24)
5037 rc = -EIO; /* bad smb */
5039 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5043 *) (((char *) &pSMBr->hdr.Protocol) +
5046 le32_to_cpu(response_data->BytesPerSector) *
5047 le32_to_cpu(response_data->
5048 SectorsPerAllocationUnit);
5050 * much prefer larger but if server doesn't report
5051 * a valid size than 4K is a reasonable minimum
5053 if (FSData->f_bsize < 512)
5054 FSData->f_bsize = 4096;
5057 le64_to_cpu(response_data->TotalAllocationUnits);
5058 FSData->f_bfree = FSData->f_bavail =
5059 le64_to_cpu(response_data->FreeAllocationUnits);
5060 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5061 (unsigned long long)FSData->f_blocks,
5062 (unsigned long long)FSData->f_bfree,
5066 cifs_buf_release(pSMB);
5075 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5077 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5078 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5079 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5080 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5082 int bytes_returned = 0;
5083 __u16 params, byte_count;
5085 cifs_dbg(FYI, "In QFSAttributeInfo\n");
5087 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5092 params = 2; /* level */
5093 pSMB->TotalDataCount = 0;
5094 pSMB->MaxParameterCount = cpu_to_le16(2);
5095 /* BB find exact max SMB PDU from sess structure BB */
5096 pSMB->MaxDataCount = cpu_to_le16(1000);
5097 pSMB->MaxSetupCount = 0;
5101 pSMB->Reserved2 = 0;
5102 byte_count = params + 1 /* pad */ ;
5103 pSMB->TotalParameterCount = cpu_to_le16(params);
5104 pSMB->ParameterCount = pSMB->TotalParameterCount;
5105 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5106 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5107 pSMB->DataCount = 0;
5108 pSMB->DataOffset = 0;
5109 pSMB->SetupCount = 1;
5110 pSMB->Reserved3 = 0;
5111 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5112 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5113 inc_rfc1001_len(pSMB, byte_count);
5114 pSMB->ByteCount = cpu_to_le16(byte_count);
5116 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5117 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5119 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5120 } else { /* decode response */
5121 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5123 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5124 /* BB also check if enough bytes returned */
5125 rc = -EIO; /* bad smb */
5127 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5129 (FILE_SYSTEM_ATTRIBUTE_INFO
5130 *) (((char *) &pSMBr->hdr.Protocol) +
5132 memcpy(&tcon->fsAttrInfo, response_data,
5133 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5136 cifs_buf_release(pSMB);
5139 goto QFSAttributeRetry;
5145 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5147 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5148 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5149 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5150 FILE_SYSTEM_DEVICE_INFO *response_data;
5152 int bytes_returned = 0;
5153 __u16 params, byte_count;
5155 cifs_dbg(FYI, "In QFSDeviceInfo\n");
5157 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5162 params = 2; /* level */
5163 pSMB->TotalDataCount = 0;
5164 pSMB->MaxParameterCount = cpu_to_le16(2);
5165 /* BB find exact max SMB PDU from sess structure BB */
5166 pSMB->MaxDataCount = cpu_to_le16(1000);
5167 pSMB->MaxSetupCount = 0;
5171 pSMB->Reserved2 = 0;
5172 byte_count = params + 1 /* pad */ ;
5173 pSMB->TotalParameterCount = cpu_to_le16(params);
5174 pSMB->ParameterCount = pSMB->TotalParameterCount;
5175 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5176 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5178 pSMB->DataCount = 0;
5179 pSMB->DataOffset = 0;
5180 pSMB->SetupCount = 1;
5181 pSMB->Reserved3 = 0;
5182 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5183 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5184 inc_rfc1001_len(pSMB, byte_count);
5185 pSMB->ByteCount = cpu_to_le16(byte_count);
5187 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5188 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5190 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5191 } else { /* decode response */
5192 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5194 if (rc || get_bcc(&pSMBr->hdr) <
5195 sizeof(FILE_SYSTEM_DEVICE_INFO))
5196 rc = -EIO; /* bad smb */
5198 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5200 (FILE_SYSTEM_DEVICE_INFO *)
5201 (((char *) &pSMBr->hdr.Protocol) +
5203 memcpy(&tcon->fsDevInfo, response_data,
5204 sizeof(FILE_SYSTEM_DEVICE_INFO));
5207 cifs_buf_release(pSMB);
5210 goto QFSDeviceRetry;
5216 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5218 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5219 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5220 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5221 FILE_SYSTEM_UNIX_INFO *response_data;
5223 int bytes_returned = 0;
5224 __u16 params, byte_count;
5226 cifs_dbg(FYI, "In QFSUnixInfo\n");
5228 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5229 (void **) &pSMB, (void **) &pSMBr);
5233 params = 2; /* level */
5234 pSMB->TotalDataCount = 0;
5235 pSMB->DataCount = 0;
5236 pSMB->DataOffset = 0;
5237 pSMB->MaxParameterCount = cpu_to_le16(2);
5238 /* BB find exact max SMB PDU from sess structure BB */
5239 pSMB->MaxDataCount = cpu_to_le16(100);
5240 pSMB->MaxSetupCount = 0;
5244 pSMB->Reserved2 = 0;
5245 byte_count = params + 1 /* pad */ ;
5246 pSMB->ParameterCount = cpu_to_le16(params);
5247 pSMB->TotalParameterCount = pSMB->ParameterCount;
5248 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5249 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5250 pSMB->SetupCount = 1;
5251 pSMB->Reserved3 = 0;
5252 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5253 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5254 inc_rfc1001_len(pSMB, byte_count);
5255 pSMB->ByteCount = cpu_to_le16(byte_count);
5257 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5258 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5260 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5261 } else { /* decode response */
5262 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5264 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5265 rc = -EIO; /* bad smb */
5267 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5269 (FILE_SYSTEM_UNIX_INFO
5270 *) (((char *) &pSMBr->hdr.Protocol) +
5272 memcpy(&tcon->fsUnixInfo, response_data,
5273 sizeof(FILE_SYSTEM_UNIX_INFO));
5276 cifs_buf_release(pSMB);
5286 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5288 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5289 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5290 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5292 int bytes_returned = 0;
5293 __u16 params, param_offset, offset, byte_count;
5295 cifs_dbg(FYI, "In SETFSUnixInfo\n");
5297 /* BB switch to small buf init to save memory */
5298 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5299 (void **) &pSMB, (void **) &pSMBr);
5303 params = 4; /* 2 bytes zero followed by info level. */
5304 pSMB->MaxSetupCount = 0;
5308 pSMB->Reserved2 = 0;
5309 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5311 offset = param_offset + params;
5313 pSMB->MaxParameterCount = cpu_to_le16(4);
5314 /* BB find exact max SMB PDU from sess structure BB */
5315 pSMB->MaxDataCount = cpu_to_le16(100);
5316 pSMB->SetupCount = 1;
5317 pSMB->Reserved3 = 0;
5318 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5319 byte_count = 1 /* pad */ + params + 12;
5321 pSMB->DataCount = cpu_to_le16(12);
5322 pSMB->ParameterCount = cpu_to_le16(params);
5323 pSMB->TotalDataCount = pSMB->DataCount;
5324 pSMB->TotalParameterCount = pSMB->ParameterCount;
5325 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5326 pSMB->DataOffset = cpu_to_le16(offset);
5330 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5333 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5334 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5335 pSMB->ClientUnixCap = cpu_to_le64(cap);
5337 inc_rfc1001_len(pSMB, byte_count);
5338 pSMB->ByteCount = cpu_to_le16(byte_count);
5340 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5341 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5343 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5344 } else { /* decode response */
5345 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5347 rc = -EIO; /* bad smb */
5349 cifs_buf_release(pSMB);
5352 goto SETFSUnixRetry;
5360 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5361 struct kstatfs *FSData)
5363 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5364 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5365 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5366 FILE_SYSTEM_POSIX_INFO *response_data;
5368 int bytes_returned = 0;
5369 __u16 params, byte_count;
5371 cifs_dbg(FYI, "In QFSPosixInfo\n");
5373 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5378 params = 2; /* level */
5379 pSMB->TotalDataCount = 0;
5380 pSMB->DataCount = 0;
5381 pSMB->DataOffset = 0;
5382 pSMB->MaxParameterCount = cpu_to_le16(2);
5383 /* BB find exact max SMB PDU from sess structure BB */
5384 pSMB->MaxDataCount = cpu_to_le16(100);
5385 pSMB->MaxSetupCount = 0;
5389 pSMB->Reserved2 = 0;
5390 byte_count = params + 1 /* pad */ ;
5391 pSMB->ParameterCount = cpu_to_le16(params);
5392 pSMB->TotalParameterCount = pSMB->ParameterCount;
5393 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5394 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5395 pSMB->SetupCount = 1;
5396 pSMB->Reserved3 = 0;
5397 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5398 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5399 inc_rfc1001_len(pSMB, byte_count);
5400 pSMB->ByteCount = cpu_to_le16(byte_count);
5402 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5403 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5405 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5406 } else { /* decode response */
5407 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5409 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5410 rc = -EIO; /* bad smb */
5412 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5414 (FILE_SYSTEM_POSIX_INFO
5415 *) (((char *) &pSMBr->hdr.Protocol) +
5418 le32_to_cpu(response_data->BlockSize);
5420 * much prefer larger but if server doesn't report
5421 * a valid size than 4K is a reasonable minimum
5423 if (FSData->f_bsize < 512)
5424 FSData->f_bsize = 4096;
5427 le64_to_cpu(response_data->TotalBlocks);
5429 le64_to_cpu(response_data->BlocksAvail);
5430 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5431 FSData->f_bavail = FSData->f_bfree;
5434 le64_to_cpu(response_data->UserBlocksAvail);
5436 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5438 le64_to_cpu(response_data->TotalFileNodes);
5439 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5441 le64_to_cpu(response_data->FreeFileNodes);
5444 cifs_buf_release(pSMB);
5454 * We can not use write of zero bytes trick to set file size due to need for
5455 * large file support. Also note that this SetPathInfo is preferred to
5456 * SetFileInfo based method in next routine which is only needed to work around
5457 * a sharing violation bugin Samba which this routine can run into.
5460 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5461 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5462 bool set_allocation)
5464 struct smb_com_transaction2_spi_req *pSMB = NULL;
5465 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5466 struct file_end_of_file_info *parm_data;
5469 int bytes_returned = 0;
5470 int remap = cifs_remap(cifs_sb);
5472 __u16 params, byte_count, data_count, param_offset, offset;
5474 cifs_dbg(FYI, "In SetEOF\n");
5476 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5481 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5483 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5484 PATH_MAX, cifs_sb->local_nls, remap);
5485 name_len++; /* trailing null */
5488 name_len = copy_path_name(pSMB->FileName, file_name);
5490 params = 6 + name_len;
5491 data_count = sizeof(struct file_end_of_file_info);
5492 pSMB->MaxParameterCount = cpu_to_le16(2);
5493 pSMB->MaxDataCount = cpu_to_le16(4100);
5494 pSMB->MaxSetupCount = 0;
5498 pSMB->Reserved2 = 0;
5499 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5500 InformationLevel) - 4;
5501 offset = param_offset + params;
5502 if (set_allocation) {
5503 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5504 pSMB->InformationLevel =
5505 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5507 pSMB->InformationLevel =
5508 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5509 } else /* Set File Size */ {
5510 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5511 pSMB->InformationLevel =
5512 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5514 pSMB->InformationLevel =
5515 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5519 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5521 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5522 pSMB->DataOffset = cpu_to_le16(offset);
5523 pSMB->SetupCount = 1;
5524 pSMB->Reserved3 = 0;
5525 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5526 byte_count = 3 /* pad */ + params + data_count;
5527 pSMB->DataCount = cpu_to_le16(data_count);
5528 pSMB->TotalDataCount = pSMB->DataCount;
5529 pSMB->ParameterCount = cpu_to_le16(params);
5530 pSMB->TotalParameterCount = pSMB->ParameterCount;
5531 pSMB->Reserved4 = 0;
5532 inc_rfc1001_len(pSMB, byte_count);
5533 parm_data->FileSize = cpu_to_le64(size);
5534 pSMB->ByteCount = cpu_to_le16(byte_count);
5535 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5536 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5538 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5540 cifs_buf_release(pSMB);
5549 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5550 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5552 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5553 struct file_end_of_file_info *parm_data;
5555 __u16 params, param_offset, offset, byte_count, count;
5557 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5559 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5564 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5565 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5568 pSMB->MaxSetupCount = 0;
5572 pSMB->Reserved2 = 0;
5573 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5574 offset = param_offset + params;
5576 count = sizeof(struct file_end_of_file_info);
5577 pSMB->MaxParameterCount = cpu_to_le16(2);
5578 /* BB find exact max SMB PDU from sess structure BB */
5579 pSMB->MaxDataCount = cpu_to_le16(1000);
5580 pSMB->SetupCount = 1;
5581 pSMB->Reserved3 = 0;
5582 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5583 byte_count = 3 /* pad */ + params + count;
5584 pSMB->DataCount = cpu_to_le16(count);
5585 pSMB->ParameterCount = cpu_to_le16(params);
5586 pSMB->TotalDataCount = pSMB->DataCount;
5587 pSMB->TotalParameterCount = pSMB->ParameterCount;
5588 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5589 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5591 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5592 pSMB->DataOffset = cpu_to_le16(offset);
5593 parm_data->FileSize = cpu_to_le64(size);
5594 pSMB->Fid = cfile->fid.netfid;
5595 if (set_allocation) {
5596 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5597 pSMB->InformationLevel =
5598 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5600 pSMB->InformationLevel =
5601 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5602 } else /* Set File Size */ {
5603 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5604 pSMB->InformationLevel =
5605 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5607 pSMB->InformationLevel =
5608 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5610 pSMB->Reserved4 = 0;
5611 inc_rfc1001_len(pSMB, byte_count);
5612 pSMB->ByteCount = cpu_to_le16(byte_count);
5613 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5614 cifs_small_buf_release(pSMB);
5616 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5620 /* Note: On -EAGAIN error only caller can retry on handle based calls
5621 since file handle passed in no longer valid */
5626 /* Some legacy servers such as NT4 require that the file times be set on
5627 an open handle, rather than by pathname - this is awkward due to
5628 potential access conflicts on the open, but it is unavoidable for these
5629 old servers since the only other choice is to go from 100 nanosecond DCE
5630 time and resort to the original setpathinfo level which takes the ancient
5631 DOS time format with 2 second granularity */
5633 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5634 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5636 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5639 __u16 params, param_offset, offset, byte_count, count;
5641 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5642 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5647 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5648 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5651 pSMB->MaxSetupCount = 0;
5655 pSMB->Reserved2 = 0;
5656 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5657 offset = param_offset + params;
5659 data_offset = (char *)pSMB +
5660 offsetof(struct smb_hdr, Protocol) + offset;
5662 count = sizeof(FILE_BASIC_INFO);
5663 pSMB->MaxParameterCount = cpu_to_le16(2);
5664 /* BB find max SMB PDU from sess */
5665 pSMB->MaxDataCount = cpu_to_le16(1000);
5666 pSMB->SetupCount = 1;
5667 pSMB->Reserved3 = 0;
5668 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5669 byte_count = 3 /* pad */ + params + count;
5670 pSMB->DataCount = cpu_to_le16(count);
5671 pSMB->ParameterCount = cpu_to_le16(params);
5672 pSMB->TotalDataCount = pSMB->DataCount;
5673 pSMB->TotalParameterCount = pSMB->ParameterCount;
5674 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5675 pSMB->DataOffset = cpu_to_le16(offset);
5677 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5678 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5680 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5681 pSMB->Reserved4 = 0;
5682 inc_rfc1001_len(pSMB, byte_count);
5683 pSMB->ByteCount = cpu_to_le16(byte_count);
5684 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5685 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5686 cifs_small_buf_release(pSMB);
5688 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5691 /* Note: On -EAGAIN error only caller can retry on handle based calls
5692 since file handle passed in no longer valid */
5698 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5699 bool delete_file, __u16 fid, __u32 pid_of_opener)
5701 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5704 __u16 params, param_offset, offset, byte_count, count;
5706 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5707 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5712 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5713 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5716 pSMB->MaxSetupCount = 0;
5720 pSMB->Reserved2 = 0;
5721 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5722 offset = param_offset + params;
5724 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5725 data_offset = (char *)(pSMB) + offset + 4;
5728 pSMB->MaxParameterCount = cpu_to_le16(2);
5729 /* BB find max SMB PDU from sess */
5730 pSMB->MaxDataCount = cpu_to_le16(1000);
5731 pSMB->SetupCount = 1;
5732 pSMB->Reserved3 = 0;
5733 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5734 byte_count = 3 /* pad */ + params + count;
5735 pSMB->DataCount = cpu_to_le16(count);
5736 pSMB->ParameterCount = cpu_to_le16(params);
5737 pSMB->TotalDataCount = pSMB->DataCount;
5738 pSMB->TotalParameterCount = pSMB->ParameterCount;
5739 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5740 pSMB->DataOffset = cpu_to_le16(offset);
5742 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5743 pSMB->Reserved4 = 0;
5744 inc_rfc1001_len(pSMB, byte_count);
5745 pSMB->ByteCount = cpu_to_le16(byte_count);
5746 *data_offset = delete_file ? 1 : 0;
5747 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5748 cifs_small_buf_release(pSMB);
5750 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5756 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5757 const char *fileName, const FILE_BASIC_INFO *data,
5758 const struct nls_table *nls_codepage,
5759 struct cifs_sb_info *cifs_sb)
5762 struct cifs_open_parms oparms;
5763 struct cifs_fid fid;
5767 oparms.cifs_sb = cifs_sb;
5768 oparms.desired_access = GENERIC_WRITE;
5769 oparms.create_options = cifs_create_options(cifs_sb, 0);
5770 oparms.disposition = FILE_OPEN;
5771 oparms.path = fileName;
5773 oparms.reconnect = false;
5775 rc = CIFS_open(xid, &oparms, &oplock, NULL);
5779 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5780 CIFSSMBClose(xid, tcon, fid.netfid);
5787 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5788 const char *fileName, const FILE_BASIC_INFO *data,
5789 const struct nls_table *nls_codepage,
5790 struct cifs_sb_info *cifs_sb)
5792 TRANSACTION2_SPI_REQ *pSMB = NULL;
5793 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5796 int bytes_returned = 0;
5798 __u16 params, param_offset, offset, byte_count, count;
5799 int remap = cifs_remap(cifs_sb);
5801 cifs_dbg(FYI, "In SetTimes\n");
5804 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5809 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5811 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5812 PATH_MAX, nls_codepage, remap);
5813 name_len++; /* trailing null */
5816 name_len = copy_path_name(pSMB->FileName, fileName);
5819 params = 6 + name_len;
5820 count = sizeof(FILE_BASIC_INFO);
5821 pSMB->MaxParameterCount = cpu_to_le16(2);
5822 /* BB find max SMB PDU from sess structure BB */
5823 pSMB->MaxDataCount = cpu_to_le16(1000);
5824 pSMB->MaxSetupCount = 0;
5828 pSMB->Reserved2 = 0;
5829 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5830 InformationLevel) - 4;
5831 offset = param_offset + params;
5832 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5833 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5834 pSMB->DataOffset = cpu_to_le16(offset);
5835 pSMB->SetupCount = 1;
5836 pSMB->Reserved3 = 0;
5837 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5838 byte_count = 3 /* pad */ + params + count;
5840 pSMB->DataCount = cpu_to_le16(count);
5841 pSMB->ParameterCount = cpu_to_le16(params);
5842 pSMB->TotalDataCount = pSMB->DataCount;
5843 pSMB->TotalParameterCount = pSMB->ParameterCount;
5844 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5845 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5847 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5848 pSMB->Reserved4 = 0;
5849 inc_rfc1001_len(pSMB, byte_count);
5850 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5851 pSMB->ByteCount = cpu_to_le16(byte_count);
5852 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5853 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5855 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5857 cifs_buf_release(pSMB);
5862 if (rc == -EOPNOTSUPP)
5863 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5864 nls_codepage, cifs_sb);
5870 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5871 const struct cifs_unix_set_info_args *args)
5873 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5874 u64 mode = args->mode;
5876 if (uid_valid(args->uid))
5877 uid = from_kuid(&init_user_ns, args->uid);
5878 if (gid_valid(args->gid))
5879 gid = from_kgid(&init_user_ns, args->gid);
5882 * Samba server ignores set of file size to zero due to bugs in some
5883 * older clients, but we should be precise - we use SetFileSize to
5884 * set file size and do not want to truncate file size to zero
5885 * accidentally as happened on one Samba server beta by putting
5886 * zero instead of -1 here
5888 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5889 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5890 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5891 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5892 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5893 data_offset->Uid = cpu_to_le64(uid);
5894 data_offset->Gid = cpu_to_le64(gid);
5895 /* better to leave device as zero when it is */
5896 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5897 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5898 data_offset->Permissions = cpu_to_le64(mode);
5901 data_offset->Type = cpu_to_le32(UNIX_FILE);
5902 else if (S_ISDIR(mode))
5903 data_offset->Type = cpu_to_le32(UNIX_DIR);
5904 else if (S_ISLNK(mode))
5905 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5906 else if (S_ISCHR(mode))
5907 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5908 else if (S_ISBLK(mode))
5909 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5910 else if (S_ISFIFO(mode))
5911 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5912 else if (S_ISSOCK(mode))
5913 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5917 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5918 const struct cifs_unix_set_info_args *args,
5919 u16 fid, u32 pid_of_opener)
5921 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5924 u16 params, param_offset, offset, byte_count, count;
5926 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5927 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5932 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5933 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5936 pSMB->MaxSetupCount = 0;
5940 pSMB->Reserved2 = 0;
5941 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5942 offset = param_offset + params;
5944 data_offset = (char *)pSMB +
5945 offsetof(struct smb_hdr, Protocol) + offset;
5947 count = sizeof(FILE_UNIX_BASIC_INFO);
5949 pSMB->MaxParameterCount = cpu_to_le16(2);
5950 /* BB find max SMB PDU from sess */
5951 pSMB->MaxDataCount = cpu_to_le16(1000);
5952 pSMB->SetupCount = 1;
5953 pSMB->Reserved3 = 0;
5954 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5955 byte_count = 3 /* pad */ + params + count;
5956 pSMB->DataCount = cpu_to_le16(count);
5957 pSMB->ParameterCount = cpu_to_le16(params);
5958 pSMB->TotalDataCount = pSMB->DataCount;
5959 pSMB->TotalParameterCount = pSMB->ParameterCount;
5960 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5961 pSMB->DataOffset = cpu_to_le16(offset);
5963 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5964 pSMB->Reserved4 = 0;
5965 inc_rfc1001_len(pSMB, byte_count);
5966 pSMB->ByteCount = cpu_to_le16(byte_count);
5968 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5970 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5971 cifs_small_buf_release(pSMB);
5973 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5976 /* Note: On -EAGAIN error only caller can retry on handle based calls
5977 since file handle passed in no longer valid */
5983 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5984 const char *file_name,
5985 const struct cifs_unix_set_info_args *args,
5986 const struct nls_table *nls_codepage, int remap)
5988 TRANSACTION2_SPI_REQ *pSMB = NULL;
5989 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5992 int bytes_returned = 0;
5993 FILE_UNIX_BASIC_INFO *data_offset;
5994 __u16 params, param_offset, offset, count, byte_count;
5996 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5998 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6003 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6005 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6006 PATH_MAX, nls_codepage, remap);
6007 name_len++; /* trailing null */
6010 name_len = copy_path_name(pSMB->FileName, file_name);
6013 params = 6 + name_len;
6014 count = sizeof(FILE_UNIX_BASIC_INFO);
6015 pSMB->MaxParameterCount = cpu_to_le16(2);
6016 /* BB find max SMB PDU from sess structure BB */
6017 pSMB->MaxDataCount = cpu_to_le16(1000);
6018 pSMB->MaxSetupCount = 0;
6022 pSMB->Reserved2 = 0;
6023 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6024 InformationLevel) - 4;
6025 offset = param_offset + params;
6026 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
6027 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
6028 memset(data_offset, 0, count);
6029 pSMB->DataOffset = cpu_to_le16(offset);
6030 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6031 pSMB->SetupCount = 1;
6032 pSMB->Reserved3 = 0;
6033 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6034 byte_count = 3 /* pad */ + params + count;
6035 pSMB->ParameterCount = cpu_to_le16(params);
6036 pSMB->DataCount = cpu_to_le16(count);
6037 pSMB->TotalParameterCount = pSMB->ParameterCount;
6038 pSMB->TotalDataCount = pSMB->DataCount;
6039 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6040 pSMB->Reserved4 = 0;
6041 inc_rfc1001_len(pSMB, byte_count);
6043 cifs_fill_unix_set_info(data_offset, args);
6045 pSMB->ByteCount = cpu_to_le16(byte_count);
6046 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6047 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6049 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6051 cifs_buf_release(pSMB);
6057 #ifdef CONFIG_CIFS_XATTR
6059 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6060 * function used by listxattr and getxattr type calls. When ea_name is set,
6061 * it looks for that attribute name and stuffs that value into the EAData
6062 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6063 * buffer. In both cases, the return value is either the length of the
6064 * resulting data or a negative error code. If EAData is a NULL pointer then
6065 * the data isn't copied to it, but the length is returned.
6068 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6069 const unsigned char *searchName, const unsigned char *ea_name,
6070 char *EAData, size_t buf_size,
6071 struct cifs_sb_info *cifs_sb)
6073 /* BB assumes one setup word */
6074 TRANSACTION2_QPI_REQ *pSMB = NULL;
6075 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6076 int remap = cifs_remap(cifs_sb);
6077 struct nls_table *nls_codepage = cifs_sb->local_nls;
6081 struct fealist *ea_response_data;
6082 struct fea *temp_fea;
6085 __u16 params, byte_count, data_offset;
6086 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6088 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6090 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6095 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6097 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6098 PATH_MAX, nls_codepage, remap);
6099 list_len++; /* trailing null */
6102 list_len = copy_path_name(pSMB->FileName, searchName);
6105 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6106 pSMB->TotalDataCount = 0;
6107 pSMB->MaxParameterCount = cpu_to_le16(2);
6108 /* BB find exact max SMB PDU from sess structure BB */
6109 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6110 pSMB->MaxSetupCount = 0;
6114 pSMB->Reserved2 = 0;
6115 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6116 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6117 pSMB->DataCount = 0;
6118 pSMB->DataOffset = 0;
6119 pSMB->SetupCount = 1;
6120 pSMB->Reserved3 = 0;
6121 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6122 byte_count = params + 1 /* pad */ ;
6123 pSMB->TotalParameterCount = cpu_to_le16(params);
6124 pSMB->ParameterCount = pSMB->TotalParameterCount;
6125 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6126 pSMB->Reserved4 = 0;
6127 inc_rfc1001_len(pSMB, byte_count);
6128 pSMB->ByteCount = cpu_to_le16(byte_count);
6130 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6131 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6133 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6138 /* BB also check enough total bytes returned */
6139 /* BB we need to improve the validity checking
6140 of these trans2 responses */
6142 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6143 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6144 rc = -EIO; /* bad smb */
6148 /* check that length of list is not more than bcc */
6149 /* check that each entry does not go beyond length
6151 /* check that each element of each entry does not
6152 go beyond end of list */
6153 /* validate_trans2_offsets() */
6154 /* BB check if start of smb + data_offset > &bcc+ bcc */
6156 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6157 ea_response_data = (struct fealist *)
6158 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6160 list_len = le32_to_cpu(ea_response_data->list_len);
6161 cifs_dbg(FYI, "ea length %d\n", list_len);
6162 if (list_len <= 8) {
6163 cifs_dbg(FYI, "empty EA list returned from server\n");
6164 /* didn't find the named attribute */
6170 /* make sure list_len doesn't go past end of SMB */
6171 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6172 if ((char *)ea_response_data + list_len > end_of_smb) {
6173 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6178 /* account for ea list len */
6180 temp_fea = ea_response_data->list;
6181 temp_ptr = (char *)temp_fea;
6182 while (list_len > 0) {
6183 unsigned int name_len;
6188 /* make sure we can read name_len and value_len */
6190 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6195 name_len = temp_fea->name_len;
6196 value_len = le16_to_cpu(temp_fea->value_len);
6197 list_len -= name_len + 1 + value_len;
6199 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6205 if (ea_name_len == name_len &&
6206 memcmp(ea_name, temp_ptr, name_len) == 0) {
6207 temp_ptr += name_len + 1;
6211 if ((size_t)value_len > buf_size) {
6215 memcpy(EAData, temp_ptr, value_len);
6219 /* account for prefix user. and trailing null */
6220 rc += (5 + 1 + name_len);
6221 if (rc < (int) buf_size) {
6222 memcpy(EAData, "user.", 5);
6224 memcpy(EAData, temp_ptr, name_len);
6226 /* null terminate name */
6229 } else if (buf_size == 0) {
6230 /* skip copy - calc size only */
6232 /* stop before overrun buffer */
6237 temp_ptr += name_len + 1 + value_len;
6238 temp_fea = (struct fea *)temp_ptr;
6241 /* didn't find the named attribute */
6246 cifs_buf_release(pSMB);
6254 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6255 const char *fileName, const char *ea_name, const void *ea_value,
6256 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6257 struct cifs_sb_info *cifs_sb)
6259 struct smb_com_transaction2_spi_req *pSMB = NULL;
6260 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6261 struct fealist *parm_data;
6264 int bytes_returned = 0;
6265 __u16 params, param_offset, byte_count, offset, count;
6266 int remap = cifs_remap(cifs_sb);
6268 cifs_dbg(FYI, "In SetEA\n");
6270 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6275 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6277 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6278 PATH_MAX, nls_codepage, remap);
6279 name_len++; /* trailing null */
6282 name_len = copy_path_name(pSMB->FileName, fileName);
6285 params = 6 + name_len;
6287 /* done calculating parms using name_len of file name,
6288 now use name_len to calculate length of ea name
6289 we are going to create in the inode xattrs */
6290 if (ea_name == NULL)
6293 name_len = strnlen(ea_name, 255);
6295 count = sizeof(*parm_data) + ea_value_len + name_len;
6296 pSMB->MaxParameterCount = cpu_to_le16(2);
6297 /* BB find max SMB PDU from sess */
6298 pSMB->MaxDataCount = cpu_to_le16(1000);
6299 pSMB->MaxSetupCount = 0;
6303 pSMB->Reserved2 = 0;
6304 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6305 InformationLevel) - 4;
6306 offset = param_offset + params;
6307 pSMB->InformationLevel =
6308 cpu_to_le16(SMB_SET_FILE_EA);
6310 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6311 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6312 pSMB->DataOffset = cpu_to_le16(offset);
6313 pSMB->SetupCount = 1;
6314 pSMB->Reserved3 = 0;
6315 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6316 byte_count = 3 /* pad */ + params + count;
6317 pSMB->DataCount = cpu_to_le16(count);
6318 parm_data->list_len = cpu_to_le32(count);
6319 parm_data->list[0].EA_flags = 0;
6320 /* we checked above that name len is less than 255 */
6321 parm_data->list[0].name_len = (__u8)name_len;
6322 /* EA names are always ASCII */
6324 strncpy(parm_data->list[0].name, ea_name, name_len);
6325 parm_data->list[0].name[name_len] = 0;
6326 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6327 /* caller ensures that ea_value_len is less than 64K but
6328 we need to ensure that it fits within the smb */
6330 /*BB add length check to see if it would fit in
6331 negotiated SMB buffer size BB */
6332 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6334 memcpy(parm_data->list[0].name+name_len+1,
6335 ea_value, ea_value_len);
6337 pSMB->TotalDataCount = pSMB->DataCount;
6338 pSMB->ParameterCount = cpu_to_le16(params);
6339 pSMB->TotalParameterCount = pSMB->ParameterCount;
6340 pSMB->Reserved4 = 0;
6341 inc_rfc1001_len(pSMB, byte_count);
6342 pSMB->ByteCount = cpu_to_le16(byte_count);
6343 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6344 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6346 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6348 cifs_buf_release(pSMB);