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->status != CifsGood) || (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) - 1;
2562 pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2567 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2569 /* Note: On -EAGAIN error only caller can retry on handle based calls
2570 since file handle passed in no longer valid */
2577 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2580 CLOSE_REQ *pSMB = NULL;
2581 cifs_dbg(FYI, "In CIFSSMBClose\n");
2583 /* do not retry on dead session on close */
2584 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2590 pSMB->FileID = (__u16) smb_file_id;
2591 pSMB->LastWriteTime = 0xFFFFFFFF;
2592 pSMB->ByteCount = 0;
2593 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2594 cifs_small_buf_release(pSMB);
2595 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2598 /* EINTR is expected when user ctl-c to kill app */
2599 cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2603 /* Since session is dead, file will be closed on server already */
2611 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2614 FLUSH_REQ *pSMB = NULL;
2615 cifs_dbg(FYI, "In CIFSSMBFlush\n");
2617 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2621 pSMB->FileID = (__u16) smb_file_id;
2622 pSMB->ByteCount = 0;
2623 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2624 cifs_small_buf_release(pSMB);
2625 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2627 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2633 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2634 const char *from_name, const char *to_name,
2635 struct cifs_sb_info *cifs_sb)
2638 RENAME_REQ *pSMB = NULL;
2639 RENAME_RSP *pSMBr = NULL;
2641 int name_len, name_len2;
2643 int remap = cifs_remap(cifs_sb);
2645 cifs_dbg(FYI, "In CIFSSMBRename\n");
2647 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2652 pSMB->BufferFormat = 0x04;
2653 pSMB->SearchAttributes =
2654 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2657 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2658 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2659 from_name, PATH_MAX,
2660 cifs_sb->local_nls, remap);
2661 name_len++; /* trailing null */
2663 pSMB->OldFileName[name_len] = 0x04; /* pad */
2664 /* protocol requires ASCII signature byte on Unicode string */
2665 pSMB->OldFileName[name_len + 1] = 0x00;
2667 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2668 to_name, PATH_MAX, cifs_sb->local_nls,
2670 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2671 name_len2 *= 2; /* convert to bytes */
2673 name_len = copy_path_name(pSMB->OldFileName, from_name);
2674 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2675 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2676 name_len2++; /* signature byte */
2679 count = 1 /* 1st signature byte */ + name_len + name_len2;
2680 inc_rfc1001_len(pSMB, count);
2681 pSMB->ByteCount = cpu_to_le16(count);
2683 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2684 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2685 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2687 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2689 cifs_buf_release(pSMB);
2697 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2698 int netfid, const char *target_name,
2699 const struct nls_table *nls_codepage, int remap)
2701 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2702 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2703 struct set_file_rename *rename_info;
2705 char dummy_string[30];
2707 int bytes_returned = 0;
2709 __u16 params, param_offset, offset, count, byte_count;
2711 cifs_dbg(FYI, "Rename to File by handle\n");
2712 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2718 pSMB->MaxSetupCount = 0;
2722 pSMB->Reserved2 = 0;
2723 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2724 offset = param_offset + params;
2726 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2727 data_offset = (char *)(pSMB) + offset + 4;
2728 rename_info = (struct set_file_rename *) data_offset;
2729 pSMB->MaxParameterCount = cpu_to_le16(2);
2730 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2731 pSMB->SetupCount = 1;
2732 pSMB->Reserved3 = 0;
2733 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2734 byte_count = 3 /* pad */ + params;
2735 pSMB->ParameterCount = cpu_to_le16(params);
2736 pSMB->TotalParameterCount = pSMB->ParameterCount;
2737 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2738 pSMB->DataOffset = cpu_to_le16(offset);
2739 /* construct random name ".cifs_tmp<inodenum><mid>" */
2740 rename_info->overwrite = cpu_to_le32(1);
2741 rename_info->root_fid = 0;
2742 /* unicode only call */
2743 if (target_name == NULL) {
2744 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2746 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2747 dummy_string, 24, nls_codepage, remap);
2750 cifsConvertToUTF16((__le16 *)rename_info->target_name,
2751 target_name, PATH_MAX, nls_codepage,
2754 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2755 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2756 byte_count += count;
2757 pSMB->DataCount = cpu_to_le16(count);
2758 pSMB->TotalDataCount = pSMB->DataCount;
2760 pSMB->InformationLevel =
2761 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2762 pSMB->Reserved4 = 0;
2763 inc_rfc1001_len(pSMB, byte_count);
2764 pSMB->ByteCount = cpu_to_le16(byte_count);
2765 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2766 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2767 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2769 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2772 cifs_buf_release(pSMB);
2774 /* Note: On -EAGAIN error only caller can retry on handle based calls
2775 since file handle passed in no longer valid */
2781 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2782 const char *fromName, const __u16 target_tid, const char *toName,
2783 const int flags, const struct nls_table *nls_codepage, int remap)
2786 COPY_REQ *pSMB = NULL;
2787 COPY_RSP *pSMBr = NULL;
2789 int name_len, name_len2;
2792 cifs_dbg(FYI, "In CIFSSMBCopy\n");
2794 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2799 pSMB->BufferFormat = 0x04;
2800 pSMB->Tid2 = target_tid;
2802 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2804 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2805 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2806 fromName, PATH_MAX, nls_codepage,
2808 name_len++; /* trailing null */
2810 pSMB->OldFileName[name_len] = 0x04; /* pad */
2811 /* protocol requires ASCII signature byte on Unicode string */
2812 pSMB->OldFileName[name_len + 1] = 0x00;
2814 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2815 toName, PATH_MAX, nls_codepage, remap);
2816 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2817 name_len2 *= 2; /* convert to bytes */
2819 name_len = copy_path_name(pSMB->OldFileName, fromName);
2820 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
2821 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2822 name_len2++; /* signature byte */
2825 count = 1 /* 1st signature byte */ + name_len + name_len2;
2826 inc_rfc1001_len(pSMB, count);
2827 pSMB->ByteCount = cpu_to_le16(count);
2829 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2830 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2832 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2833 rc, le16_to_cpu(pSMBr->CopyCount));
2835 cifs_buf_release(pSMB);
2844 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2845 const char *fromName, const char *toName,
2846 const struct nls_table *nls_codepage, int remap)
2848 TRANSACTION2_SPI_REQ *pSMB = NULL;
2849 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2852 int name_len_target;
2854 int bytes_returned = 0;
2855 __u16 params, param_offset, offset, byte_count;
2857 cifs_dbg(FYI, "In Symlink Unix style\n");
2859 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2864 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2866 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2867 /* find define for this maxpathcomponent */
2868 PATH_MAX, nls_codepage, remap);
2869 name_len++; /* trailing null */
2873 name_len = copy_path_name(pSMB->FileName, fromName);
2875 params = 6 + name_len;
2876 pSMB->MaxSetupCount = 0;
2880 pSMB->Reserved2 = 0;
2881 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2882 InformationLevel) - 4;
2883 offset = param_offset + params;
2885 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2886 data_offset = (char *)pSMB + offset + 4;
2887 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2889 cifsConvertToUTF16((__le16 *) data_offset, toName,
2890 /* find define for this maxpathcomponent */
2891 PATH_MAX, nls_codepage, remap);
2892 name_len_target++; /* trailing null */
2893 name_len_target *= 2;
2895 name_len_target = copy_path_name(data_offset, toName);
2898 pSMB->MaxParameterCount = cpu_to_le16(2);
2899 /* BB find exact max on data count below from sess */
2900 pSMB->MaxDataCount = cpu_to_le16(1000);
2901 pSMB->SetupCount = 1;
2902 pSMB->Reserved3 = 0;
2903 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2904 byte_count = 3 /* pad */ + params + name_len_target;
2905 pSMB->DataCount = cpu_to_le16(name_len_target);
2906 pSMB->ParameterCount = cpu_to_le16(params);
2907 pSMB->TotalDataCount = pSMB->DataCount;
2908 pSMB->TotalParameterCount = pSMB->ParameterCount;
2909 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2910 pSMB->DataOffset = cpu_to_le16(offset);
2911 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2912 pSMB->Reserved4 = 0;
2913 inc_rfc1001_len(pSMB, byte_count);
2914 pSMB->ByteCount = cpu_to_le16(byte_count);
2915 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2916 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2917 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2919 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2922 cifs_buf_release(pSMB);
2925 goto createSymLinkRetry;
2931 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2932 const char *fromName, const char *toName,
2933 const struct nls_table *nls_codepage, int remap)
2935 TRANSACTION2_SPI_REQ *pSMB = NULL;
2936 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2939 int name_len_target;
2941 int bytes_returned = 0;
2942 __u16 params, param_offset, offset, byte_count;
2944 cifs_dbg(FYI, "In Create Hard link Unix style\n");
2945 createHardLinkRetry:
2946 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2951 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2952 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2953 PATH_MAX, nls_codepage, remap);
2954 name_len++; /* trailing null */
2958 name_len = copy_path_name(pSMB->FileName, toName);
2960 params = 6 + name_len;
2961 pSMB->MaxSetupCount = 0;
2965 pSMB->Reserved2 = 0;
2966 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2967 InformationLevel) - 4;
2968 offset = param_offset + params;
2970 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2971 data_offset = (char *)pSMB + offset + 4;
2972 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2974 cifsConvertToUTF16((__le16 *) data_offset, fromName,
2975 PATH_MAX, nls_codepage, remap);
2976 name_len_target++; /* trailing null */
2977 name_len_target *= 2;
2979 name_len_target = copy_path_name(data_offset, fromName);
2982 pSMB->MaxParameterCount = cpu_to_le16(2);
2983 /* BB find exact max on data count below from sess*/
2984 pSMB->MaxDataCount = cpu_to_le16(1000);
2985 pSMB->SetupCount = 1;
2986 pSMB->Reserved3 = 0;
2987 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2988 byte_count = 3 /* pad */ + params + name_len_target;
2989 pSMB->ParameterCount = cpu_to_le16(params);
2990 pSMB->TotalParameterCount = pSMB->ParameterCount;
2991 pSMB->DataCount = cpu_to_le16(name_len_target);
2992 pSMB->TotalDataCount = pSMB->DataCount;
2993 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2994 pSMB->DataOffset = cpu_to_le16(offset);
2995 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2996 pSMB->Reserved4 = 0;
2997 inc_rfc1001_len(pSMB, byte_count);
2998 pSMB->ByteCount = cpu_to_le16(byte_count);
2999 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3000 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3001 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3003 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
3006 cifs_buf_release(pSMB);
3008 goto createHardLinkRetry;
3014 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3015 const char *from_name, const char *to_name,
3016 struct cifs_sb_info *cifs_sb)
3019 NT_RENAME_REQ *pSMB = NULL;
3020 RENAME_RSP *pSMBr = NULL;
3022 int name_len, name_len2;
3024 int remap = cifs_remap(cifs_sb);
3026 cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3027 winCreateHardLinkRetry:
3029 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3034 pSMB->SearchAttributes =
3035 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3037 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3038 pSMB->ClusterCount = 0;
3040 pSMB->BufferFormat = 0x04;
3042 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3044 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3045 PATH_MAX, cifs_sb->local_nls, remap);
3046 name_len++; /* trailing null */
3049 /* protocol specifies ASCII buffer format (0x04) for unicode */
3050 pSMB->OldFileName[name_len] = 0x04;
3051 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3053 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3054 to_name, PATH_MAX, cifs_sb->local_nls,
3056 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
3057 name_len2 *= 2; /* convert to bytes */
3059 name_len = copy_path_name(pSMB->OldFileName, from_name);
3060 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
3061 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
3062 name_len2++; /* signature byte */
3065 count = 1 /* string type byte */ + name_len + name_len2;
3066 inc_rfc1001_len(pSMB, count);
3067 pSMB->ByteCount = cpu_to_le16(count);
3069 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3070 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3071 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3073 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3075 cifs_buf_release(pSMB);
3077 goto winCreateHardLinkRetry;
3083 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3084 const unsigned char *searchName, char **symlinkinfo,
3085 const struct nls_table *nls_codepage, int remap)
3087 /* SMB_QUERY_FILE_UNIX_LINK */
3088 TRANSACTION2_QPI_REQ *pSMB = NULL;
3089 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3093 __u16 params, byte_count;
3096 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3099 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3104 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3106 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3107 searchName, PATH_MAX, nls_codepage,
3109 name_len++; /* trailing null */
3112 name_len = copy_path_name(pSMB->FileName, searchName);
3115 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3116 pSMB->TotalDataCount = 0;
3117 pSMB->MaxParameterCount = cpu_to_le16(2);
3118 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3119 pSMB->MaxSetupCount = 0;
3123 pSMB->Reserved2 = 0;
3124 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3125 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3126 pSMB->DataCount = 0;
3127 pSMB->DataOffset = 0;
3128 pSMB->SetupCount = 1;
3129 pSMB->Reserved3 = 0;
3130 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3131 byte_count = params + 1 /* pad */ ;
3132 pSMB->TotalParameterCount = cpu_to_le16(params);
3133 pSMB->ParameterCount = pSMB->TotalParameterCount;
3134 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3135 pSMB->Reserved4 = 0;
3136 inc_rfc1001_len(pSMB, byte_count);
3137 pSMB->ByteCount = cpu_to_le16(byte_count);
3139 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3140 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3142 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3144 /* decode response */
3146 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3147 /* BB also check enough total bytes returned */
3148 if (rc || get_bcc(&pSMBr->hdr) < 2)
3152 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3154 data_start = ((char *) &pSMBr->hdr.Protocol) +
3155 le16_to_cpu(pSMBr->t2.DataOffset);
3157 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3162 /* BB FIXME investigate remapping reserved chars here */
3163 *symlinkinfo = cifs_strndup_from_utf16(data_start,
3164 count, is_unicode, nls_codepage);
3169 cifs_buf_release(pSMB);
3171 goto querySymLinkRetry;
3176 * Recent Windows versions now create symlinks more frequently
3177 * and they use the "reparse point" mechanism below. We can of course
3178 * do symlinks nicely to Samba and other servers which support the
3179 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3180 * "MF" symlinks optionally, but for recent Windows we really need to
3181 * reenable the code below and fix the cifs_symlink callers to handle this.
3182 * In the interim this code has been moved to its own config option so
3183 * it is not compiled in by default until callers fixed up and more tested.
3186 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3187 __u16 fid, char **symlinkinfo,
3188 const struct nls_table *nls_codepage)
3192 struct smb_com_transaction_ioctl_req *pSMB;
3193 struct smb_com_transaction_ioctl_rsp *pSMBr;
3195 unsigned int sub_len;
3197 struct reparse_symlink_data *reparse_buf;
3198 struct reparse_posix_data *posix_buf;
3199 __u32 data_offset, data_count;
3202 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3203 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3208 pSMB->TotalParameterCount = 0 ;
3209 pSMB->TotalDataCount = 0;
3210 pSMB->MaxParameterCount = cpu_to_le32(2);
3211 /* BB find exact data count max from sess structure BB */
3212 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3213 pSMB->MaxSetupCount = 4;
3215 pSMB->ParameterOffset = 0;
3216 pSMB->DataCount = 0;
3217 pSMB->DataOffset = 0;
3218 pSMB->SetupCount = 4;
3219 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3220 pSMB->ParameterCount = pSMB->TotalParameterCount;
3221 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3222 pSMB->IsFsctl = 1; /* FSCTL */
3223 pSMB->IsRootFlag = 0;
3224 pSMB->Fid = fid; /* file handle always le */
3225 pSMB->ByteCount = 0;
3227 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3228 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3230 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3234 data_offset = le32_to_cpu(pSMBr->DataOffset);
3235 data_count = le32_to_cpu(pSMBr->DataCount);
3236 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3237 /* BB also check enough total bytes returned */
3238 rc = -EIO; /* bad smb */
3241 if (!data_count || (data_count > 2048)) {
3243 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3246 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3247 reparse_buf = (struct reparse_symlink_data *)
3248 ((char *)&pSMBr->hdr.Protocol + data_offset);
3249 if ((char *)reparse_buf >= end_of_smb) {
3253 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3254 cifs_dbg(FYI, "NFS style reparse tag\n");
3255 posix_buf = (struct reparse_posix_data *)reparse_buf;
3257 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3258 cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3259 le64_to_cpu(posix_buf->InodeType));
3264 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3265 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3266 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3270 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3271 sub_len, is_unicode, nls_codepage);
3273 } else if (reparse_buf->ReparseTag !=
3274 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3279 /* Reparse tag is NTFS symlink */
3280 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3281 reparse_buf->PathBuffer;
3282 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3283 if (sub_start + sub_len > end_of_smb) {
3284 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3288 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3293 /* BB FIXME investigate remapping reserved chars here */
3294 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3299 cifs_buf_release(pSMB);
3302 * Note: On -EAGAIN error only caller can retry on handle based calls
3303 * since file handle passed in no longer valid.
3309 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3314 struct smb_com_transaction_compr_ioctl_req *pSMB;
3315 struct smb_com_transaction_ioctl_rsp *pSMBr;
3317 cifs_dbg(FYI, "Set compression for %u\n", fid);
3318 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3323 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3325 pSMB->TotalParameterCount = 0;
3326 pSMB->TotalDataCount = cpu_to_le32(2);
3327 pSMB->MaxParameterCount = 0;
3328 pSMB->MaxDataCount = 0;
3329 pSMB->MaxSetupCount = 4;
3331 pSMB->ParameterOffset = 0;
3332 pSMB->DataCount = cpu_to_le32(2);
3334 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3335 compression_state) - 4); /* 84 */
3336 pSMB->SetupCount = 4;
3337 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3338 pSMB->ParameterCount = 0;
3339 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3340 pSMB->IsFsctl = 1; /* FSCTL */
3341 pSMB->IsRootFlag = 0;
3342 pSMB->Fid = fid; /* file handle always le */
3343 /* 3 byte pad, followed by 2 byte compress state */
3344 pSMB->ByteCount = cpu_to_le16(5);
3345 inc_rfc1001_len(pSMB, 5);
3347 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3348 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3350 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3352 cifs_buf_release(pSMB);
3355 * Note: On -EAGAIN error only caller can retry on handle based calls
3356 * since file handle passed in no longer valid.
3362 #ifdef CONFIG_CIFS_POSIX
3364 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3365 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3366 struct cifs_posix_ace *cifs_ace)
3368 /* u8 cifs fields do not need le conversion */
3369 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3370 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
3371 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3373 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3374 ace->e_perm, ace->e_tag, ace->e_id);
3380 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3381 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3382 const int acl_type, const int size_of_data_area)
3387 struct cifs_posix_ace *pACE;
3388 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3389 struct posix_acl_xattr_header *local_acl = (void *)trgt;
3391 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3394 if (acl_type == ACL_TYPE_ACCESS) {
3395 count = le16_to_cpu(cifs_acl->access_entry_count);
3396 pACE = &cifs_acl->ace_array[0];
3397 size = sizeof(struct cifs_posix_acl);
3398 size += sizeof(struct cifs_posix_ace) * count;
3399 /* check if we would go beyond end of SMB */
3400 if (size_of_data_area < size) {
3401 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3402 size_of_data_area, size);
3405 } else if (acl_type == ACL_TYPE_DEFAULT) {
3406 count = le16_to_cpu(cifs_acl->access_entry_count);
3407 size = sizeof(struct cifs_posix_acl);
3408 size += sizeof(struct cifs_posix_ace) * count;
3409 /* skip past access ACEs to get to default ACEs */
3410 pACE = &cifs_acl->ace_array[count];
3411 count = le16_to_cpu(cifs_acl->default_entry_count);
3412 size += sizeof(struct cifs_posix_ace) * count;
3413 /* check if we would go beyond end of SMB */
3414 if (size_of_data_area < size)
3421 size = posix_acl_xattr_size(count);
3422 if ((buflen == 0) || (local_acl == NULL)) {
3423 /* used to query ACL EA size */
3424 } else if (size > buflen) {
3426 } else /* buffer big enough */ {
3427 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3429 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3430 for (i = 0; i < count ; i++) {
3431 cifs_convert_ace(&ace[i], pACE);
3438 static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3439 const struct posix_acl_xattr_entry *local_ace)
3441 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3442 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
3443 /* BB is there a better way to handle the large uid? */
3444 if (local_ace->e_id == cpu_to_le32(-1)) {
3445 /* Probably no need to le convert -1 on any arch but can not hurt */
3446 cifs_ace->cifs_uid = cpu_to_le64(-1);
3448 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3450 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3451 ace->e_perm, ace->e_tag, ace->e_id);
3455 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3456 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3457 const int buflen, const int acl_type)
3460 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3461 struct posix_acl_xattr_header *local_acl = (void *)pACL;
3462 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3466 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3469 count = posix_acl_xattr_count((size_t)buflen);
3470 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3471 count, buflen, le32_to_cpu(local_acl->a_version));
3472 if (le32_to_cpu(local_acl->a_version) != 2) {
3473 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3474 le32_to_cpu(local_acl->a_version));
3477 cifs_acl->version = cpu_to_le16(1);
3478 if (acl_type == ACL_TYPE_ACCESS) {
3479 cifs_acl->access_entry_count = cpu_to_le16(count);
3480 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3481 } else if (acl_type == ACL_TYPE_DEFAULT) {
3482 cifs_acl->default_entry_count = cpu_to_le16(count);
3483 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3485 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3488 for (i = 0; i < count; i++)
3489 convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3491 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3492 rc += sizeof(struct cifs_posix_acl);
3493 /* BB add check to make sure ACL does not overflow SMB */
3499 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3500 const unsigned char *searchName,
3501 char *acl_inf, const int buflen, const int acl_type,
3502 const struct nls_table *nls_codepage, int remap)
3504 /* SMB_QUERY_POSIX_ACL */
3505 TRANSACTION2_QPI_REQ *pSMB = NULL;
3506 TRANSACTION2_QPI_RSP *pSMBr = NULL;
3510 __u16 params, byte_count;
3512 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3515 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3520 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3522 cifsConvertToUTF16((__le16 *) pSMB->FileName,
3523 searchName, PATH_MAX, nls_codepage,
3525 name_len++; /* trailing null */
3527 pSMB->FileName[name_len] = 0;
3528 pSMB->FileName[name_len+1] = 0;
3530 name_len = copy_path_name(pSMB->FileName, searchName);
3533 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
3534 pSMB->TotalDataCount = 0;
3535 pSMB->MaxParameterCount = cpu_to_le16(2);
3536 /* BB find exact max data count below from sess structure BB */
3537 pSMB->MaxDataCount = cpu_to_le16(4000);
3538 pSMB->MaxSetupCount = 0;
3542 pSMB->Reserved2 = 0;
3543 pSMB->ParameterOffset = cpu_to_le16(
3544 offsetof(struct smb_com_transaction2_qpi_req,
3545 InformationLevel) - 4);
3546 pSMB->DataCount = 0;
3547 pSMB->DataOffset = 0;
3548 pSMB->SetupCount = 1;
3549 pSMB->Reserved3 = 0;
3550 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3551 byte_count = params + 1 /* pad */ ;
3552 pSMB->TotalParameterCount = cpu_to_le16(params);
3553 pSMB->ParameterCount = pSMB->TotalParameterCount;
3554 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3555 pSMB->Reserved4 = 0;
3556 inc_rfc1001_len(pSMB, byte_count);
3557 pSMB->ByteCount = cpu_to_le16(byte_count);
3559 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3560 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3561 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3563 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3565 /* decode response */
3567 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3568 /* BB also check enough total bytes returned */
3569 if (rc || get_bcc(&pSMBr->hdr) < 2)
3570 rc = -EIO; /* bad smb */
3572 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3573 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3574 rc = cifs_copy_posix_acl(acl_inf,
3575 (char *)&pSMBr->hdr.Protocol+data_offset,
3576 buflen, acl_type, count);
3579 cifs_buf_release(pSMB);
3586 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3587 const unsigned char *fileName,
3588 const char *local_acl, const int buflen,
3590 const struct nls_table *nls_codepage, int remap)
3592 struct smb_com_transaction2_spi_req *pSMB = NULL;
3593 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3597 int bytes_returned = 0;
3598 __u16 params, byte_count, data_count, param_offset, offset;
3600 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3602 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3606 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3608 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3609 PATH_MAX, nls_codepage, remap);
3610 name_len++; /* trailing null */
3613 name_len = copy_path_name(pSMB->FileName, fileName);
3615 params = 6 + name_len;
3616 pSMB->MaxParameterCount = cpu_to_le16(2);
3617 /* BB find max SMB size from sess */
3618 pSMB->MaxDataCount = cpu_to_le16(1000);
3619 pSMB->MaxSetupCount = 0;
3623 pSMB->Reserved2 = 0;
3624 param_offset = offsetof(struct smb_com_transaction2_spi_req,
3625 InformationLevel) - 4;
3626 offset = param_offset + params;
3627 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3628 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3630 /* convert to on the wire format for POSIX ACL */
3631 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3633 if (data_count == 0) {
3635 goto setACLerrorExit;
3637 pSMB->DataOffset = cpu_to_le16(offset);
3638 pSMB->SetupCount = 1;
3639 pSMB->Reserved3 = 0;
3640 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3641 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3642 byte_count = 3 /* pad */ + params + data_count;
3643 pSMB->DataCount = cpu_to_le16(data_count);
3644 pSMB->TotalDataCount = pSMB->DataCount;
3645 pSMB->ParameterCount = cpu_to_le16(params);
3646 pSMB->TotalParameterCount = pSMB->ParameterCount;
3647 pSMB->Reserved4 = 0;
3648 inc_rfc1001_len(pSMB, byte_count);
3649 pSMB->ByteCount = cpu_to_le16(byte_count);
3650 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3651 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3653 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3656 cifs_buf_release(pSMB);
3662 /* BB fix tabs in this function FIXME BB */
3664 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3665 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3668 struct smb_t2_qfi_req *pSMB = NULL;
3669 struct smb_t2_qfi_rsp *pSMBr = NULL;
3671 __u16 params, byte_count;
3673 cifs_dbg(FYI, "In GetExtAttr\n");
3678 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3683 params = 2 /* level */ + 2 /* fid */;
3684 pSMB->t2.TotalDataCount = 0;
3685 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3686 /* BB find exact max data count below from sess structure BB */
3687 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3688 pSMB->t2.MaxSetupCount = 0;
3689 pSMB->t2.Reserved = 0;
3691 pSMB->t2.Timeout = 0;
3692 pSMB->t2.Reserved2 = 0;
3693 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3695 pSMB->t2.DataCount = 0;
3696 pSMB->t2.DataOffset = 0;
3697 pSMB->t2.SetupCount = 1;
3698 pSMB->t2.Reserved3 = 0;
3699 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3700 byte_count = params + 1 /* pad */ ;
3701 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3702 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3703 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3706 inc_rfc1001_len(pSMB, byte_count);
3707 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3709 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3710 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3712 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3714 /* decode response */
3715 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3716 /* BB also check enough total bytes returned */
3717 if (rc || get_bcc(&pSMBr->hdr) < 2)
3718 /* If rc should we check for EOPNOSUPP and
3719 disable the srvino flag? or in caller? */
3720 rc = -EIO; /* bad smb */
3722 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3723 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3724 struct file_chattr_info *pfinfo;
3725 /* BB Do we need a cast or hash here ? */
3727 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3731 pfinfo = (struct file_chattr_info *)
3732 (data_offset + (char *) &pSMBr->hdr.Protocol);
3733 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3734 *pMask = le64_to_cpu(pfinfo->mask);
3738 cifs_buf_release(pSMB);
3740 goto GetExtAttrRetry;
3744 #endif /* CONFIG_POSIX */
3747 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3748 * all NT TRANSACTS that we init here have total parm and data under about 400
3749 * bytes (to fit in small cifs buffer size), which is the case so far, it
3750 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3751 * returned setup area) and MaxParameterCount (returned parms size) must be set
3755 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3756 const int parm_len, struct cifs_tcon *tcon,
3761 struct smb_com_ntransact_req *pSMB;
3763 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3767 *ret_buf = (void *)pSMB;
3769 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3770 pSMB->TotalDataCount = 0;
3771 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3772 pSMB->ParameterCount = pSMB->TotalParameterCount;
3773 pSMB->DataCount = pSMB->TotalDataCount;
3774 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3775 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3776 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3777 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3778 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3779 pSMB->SubCommand = cpu_to_le16(sub_command);
3784 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3785 __u32 *pparmlen, __u32 *pdatalen)
3788 __u32 data_count, data_offset, parm_count, parm_offset;
3789 struct smb_com_ntransact_rsp *pSMBr;
3798 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3800 bcc = get_bcc(&pSMBr->hdr);
3801 end_of_smb = 2 /* sizeof byte count */ + bcc +
3802 (char *)&pSMBr->ByteCount;
3804 data_offset = le32_to_cpu(pSMBr->DataOffset);
3805 data_count = le32_to_cpu(pSMBr->DataCount);
3806 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3807 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3809 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3810 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3812 /* should we also check that parm and data areas do not overlap? */
3813 if (*ppparm > end_of_smb) {
3814 cifs_dbg(FYI, "parms start after end of smb\n");
3816 } else if (parm_count + *ppparm > end_of_smb) {
3817 cifs_dbg(FYI, "parm end after end of smb\n");
3819 } else if (*ppdata > end_of_smb) {
3820 cifs_dbg(FYI, "data starts after end of smb\n");
3822 } else if (data_count + *ppdata > end_of_smb) {
3823 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3824 *ppdata, data_count, (data_count + *ppdata),
3827 } else if (parm_count + data_count > bcc) {
3828 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3831 *pdatalen = data_count;
3832 *pparmlen = parm_count;
3836 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3838 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3839 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3843 QUERY_SEC_DESC_REQ *pSMB;
3845 struct kvec rsp_iov;
3847 cifs_dbg(FYI, "GetCifsACL\n");
3852 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3853 8 /* parm len */, tcon, (void **) &pSMB);
3857 pSMB->MaxParameterCount = cpu_to_le32(4);
3858 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3859 pSMB->MaxSetupCount = 0;
3860 pSMB->Fid = fid; /* file handle always le */
3861 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3863 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3864 inc_rfc1001_len(pSMB, 11);
3865 iov[0].iov_base = (char *)pSMB;
3866 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3868 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3870 cifs_small_buf_release(pSMB);
3871 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3873 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3874 } else { /* decode response */
3878 struct smb_com_ntransact_rsp *pSMBr;
3881 /* validate_nttransact */
3882 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3883 &pdata, &parm_len, pbuflen);
3886 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3888 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3889 pSMBr, parm, *acl_inf);
3891 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3892 rc = -EIO; /* bad smb */
3897 /* BB check that data area is minimum length and as big as acl_len */
3899 acl_len = le32_to_cpu(*parm);
3900 if (acl_len != *pbuflen) {
3901 cifs_dbg(VFS, "acl length %d does not match %d\n",
3903 if (*pbuflen > acl_len)
3907 /* check if buffer is big enough for the acl
3908 header followed by the smallest SID */
3909 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3910 (*pbuflen >= 64 * 1024)) {
3911 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3915 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3916 if (*acl_inf == NULL) {
3923 free_rsp_buf(buf_type, rsp_iov.iov_base);
3928 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3929 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3931 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3933 int bytes_returned = 0;
3934 SET_SEC_DESC_REQ *pSMB = NULL;
3938 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3942 pSMB->MaxSetupCount = 0;
3946 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3947 data_count = acllen;
3948 data_offset = param_offset + param_count;
3949 byte_count = 3 /* pad */ + param_count;
3951 pSMB->DataCount = cpu_to_le32(data_count);
3952 pSMB->TotalDataCount = pSMB->DataCount;
3953 pSMB->MaxParameterCount = cpu_to_le32(4);
3954 pSMB->MaxDataCount = cpu_to_le32(16384);
3955 pSMB->ParameterCount = cpu_to_le32(param_count);
3956 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3957 pSMB->TotalParameterCount = pSMB->ParameterCount;
3958 pSMB->DataOffset = cpu_to_le32(data_offset);
3959 pSMB->SetupCount = 0;
3960 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3961 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3963 pSMB->Fid = fid; /* file handle always le */
3964 pSMB->Reserved2 = 0;
3965 pSMB->AclFlags = cpu_to_le32(aclflag);
3967 if (pntsd && acllen) {
3968 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3969 data_offset, pntsd, acllen);
3970 inc_rfc1001_len(pSMB, byte_count + data_count);
3972 inc_rfc1001_len(pSMB, byte_count);
3974 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3975 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3977 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3978 bytes_returned, rc);
3980 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3981 cifs_buf_release(pSMB);
3984 goto setCifsAclRetry;
3990 /* Legacy Query Path Information call for lookup to old servers such
3993 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3994 const char *search_name, FILE_ALL_INFO *data,
3995 const struct nls_table *nls_codepage, int remap)
3997 QUERY_INFORMATION_REQ *pSMB;
3998 QUERY_INFORMATION_RSP *pSMBr;
4003 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
4005 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
4010 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4012 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4013 search_name, PATH_MAX, nls_codepage,
4015 name_len++; /* trailing null */
4018 name_len = copy_path_name(pSMB->FileName, search_name);
4020 pSMB->BufferFormat = 0x04;
4021 name_len++; /* account for buffer type byte */
4022 inc_rfc1001_len(pSMB, (__u16)name_len);
4023 pSMB->ByteCount = cpu_to_le16(name_len);
4025 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4026 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4028 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4030 struct timespec64 ts;
4031 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4033 /* decode response */
4034 /* BB FIXME - add time zone adjustment BB */
4035 memset(data, 0, sizeof(FILE_ALL_INFO));
4038 /* decode time fields */
4039 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4040 data->LastWriteTime = data->ChangeTime;
4041 data->LastAccessTime = 0;
4042 data->AllocationSize =
4043 cpu_to_le64(le32_to_cpu(pSMBr->size));
4044 data->EndOfFile = data->AllocationSize;
4046 cpu_to_le32(le16_to_cpu(pSMBr->attr));
4048 rc = -EIO; /* bad buffer passed in */
4050 cifs_buf_release(pSMB);
4059 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4060 u16 netfid, FILE_ALL_INFO *pFindData)
4062 struct smb_t2_qfi_req *pSMB = NULL;
4063 struct smb_t2_qfi_rsp *pSMBr = NULL;
4066 __u16 params, byte_count;
4069 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4074 params = 2 /* level */ + 2 /* fid */;
4075 pSMB->t2.TotalDataCount = 0;
4076 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4077 /* BB find exact max data count below from sess structure BB */
4078 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4079 pSMB->t2.MaxSetupCount = 0;
4080 pSMB->t2.Reserved = 0;
4082 pSMB->t2.Timeout = 0;
4083 pSMB->t2.Reserved2 = 0;
4084 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4086 pSMB->t2.DataCount = 0;
4087 pSMB->t2.DataOffset = 0;
4088 pSMB->t2.SetupCount = 1;
4089 pSMB->t2.Reserved3 = 0;
4090 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4091 byte_count = params + 1 /* pad */ ;
4092 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4093 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4094 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4097 inc_rfc1001_len(pSMB, byte_count);
4098 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4100 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4101 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4103 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
4104 } else { /* decode response */
4105 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4107 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4109 else if (get_bcc(&pSMBr->hdr) < 40)
4110 rc = -EIO; /* bad smb */
4111 else if (pFindData) {
4112 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4113 memcpy((char *) pFindData,
4114 (char *) &pSMBr->hdr.Protocol +
4115 data_offset, sizeof(FILE_ALL_INFO));
4119 cifs_buf_release(pSMB);
4121 goto QFileInfoRetry;
4127 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4128 const char *search_name, FILE_ALL_INFO *data,
4129 int legacy /* old style infolevel */,
4130 const struct nls_table *nls_codepage, int remap)
4132 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4133 TRANSACTION2_QPI_REQ *pSMB = NULL;
4134 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4138 __u16 params, byte_count;
4140 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4142 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4147 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4149 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4150 PATH_MAX, nls_codepage, remap);
4151 name_len++; /* trailing null */
4154 name_len = copy_path_name(pSMB->FileName, search_name);
4157 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4158 pSMB->TotalDataCount = 0;
4159 pSMB->MaxParameterCount = cpu_to_le16(2);
4160 /* BB find exact max SMB PDU from sess structure BB */
4161 pSMB->MaxDataCount = cpu_to_le16(4000);
4162 pSMB->MaxSetupCount = 0;
4166 pSMB->Reserved2 = 0;
4167 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4168 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4169 pSMB->DataCount = 0;
4170 pSMB->DataOffset = 0;
4171 pSMB->SetupCount = 1;
4172 pSMB->Reserved3 = 0;
4173 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4174 byte_count = params + 1 /* pad */ ;
4175 pSMB->TotalParameterCount = cpu_to_le16(params);
4176 pSMB->ParameterCount = pSMB->TotalParameterCount;
4178 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4180 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4181 pSMB->Reserved4 = 0;
4182 inc_rfc1001_len(pSMB, byte_count);
4183 pSMB->ByteCount = cpu_to_le16(byte_count);
4185 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4186 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4188 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4189 } else { /* decode response */
4190 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4192 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4194 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4195 rc = -EIO; /* bad smb */
4196 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4197 rc = -EIO; /* 24 or 26 expected but we do not read
4201 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4204 * On legacy responses we do not read the last field,
4205 * EAsize, fortunately since it varies by subdialect and
4206 * also note it differs on Set vs Get, ie two bytes or 4
4207 * bytes depending but we don't care here.
4210 size = sizeof(FILE_INFO_STANDARD);
4212 size = sizeof(FILE_ALL_INFO);
4213 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4218 cifs_buf_release(pSMB);
4220 goto QPathInfoRetry;
4226 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4227 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4229 struct smb_t2_qfi_req *pSMB = NULL;
4230 struct smb_t2_qfi_rsp *pSMBr = NULL;
4233 __u16 params, byte_count;
4236 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4241 params = 2 /* level */ + 2 /* fid */;
4242 pSMB->t2.TotalDataCount = 0;
4243 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4244 /* BB find exact max data count below from sess structure BB */
4245 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4246 pSMB->t2.MaxSetupCount = 0;
4247 pSMB->t2.Reserved = 0;
4249 pSMB->t2.Timeout = 0;
4250 pSMB->t2.Reserved2 = 0;
4251 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4253 pSMB->t2.DataCount = 0;
4254 pSMB->t2.DataOffset = 0;
4255 pSMB->t2.SetupCount = 1;
4256 pSMB->t2.Reserved3 = 0;
4257 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4258 byte_count = params + 1 /* pad */ ;
4259 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4260 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4261 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4264 inc_rfc1001_len(pSMB, byte_count);
4265 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4267 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4268 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4270 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
4271 } else { /* decode response */
4272 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4274 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4275 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4276 rc = -EIO; /* bad smb */
4278 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4279 memcpy((char *) pFindData,
4280 (char *) &pSMBr->hdr.Protocol +
4282 sizeof(FILE_UNIX_BASIC_INFO));
4286 cifs_buf_release(pSMB);
4288 goto UnixQFileInfoRetry;
4294 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4295 const unsigned char *searchName,
4296 FILE_UNIX_BASIC_INFO *pFindData,
4297 const struct nls_table *nls_codepage, int remap)
4299 /* SMB_QUERY_FILE_UNIX_BASIC */
4300 TRANSACTION2_QPI_REQ *pSMB = NULL;
4301 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4303 int bytes_returned = 0;
4305 __u16 params, byte_count;
4307 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4309 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4314 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4316 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4317 PATH_MAX, nls_codepage, remap);
4318 name_len++; /* trailing null */
4321 name_len = copy_path_name(pSMB->FileName, searchName);
4324 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4325 pSMB->TotalDataCount = 0;
4326 pSMB->MaxParameterCount = cpu_to_le16(2);
4327 /* BB find exact max SMB PDU from sess structure BB */
4328 pSMB->MaxDataCount = cpu_to_le16(4000);
4329 pSMB->MaxSetupCount = 0;
4333 pSMB->Reserved2 = 0;
4334 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4335 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4336 pSMB->DataCount = 0;
4337 pSMB->DataOffset = 0;
4338 pSMB->SetupCount = 1;
4339 pSMB->Reserved3 = 0;
4340 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4341 byte_count = params + 1 /* pad */ ;
4342 pSMB->TotalParameterCount = cpu_to_le16(params);
4343 pSMB->ParameterCount = pSMB->TotalParameterCount;
4344 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4345 pSMB->Reserved4 = 0;
4346 inc_rfc1001_len(pSMB, byte_count);
4347 pSMB->ByteCount = cpu_to_le16(byte_count);
4349 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4350 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4352 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
4353 } else { /* decode response */
4354 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4356 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4357 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4358 rc = -EIO; /* bad smb */
4360 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4361 memcpy((char *) pFindData,
4362 (char *) &pSMBr->hdr.Protocol +
4364 sizeof(FILE_UNIX_BASIC_INFO));
4367 cifs_buf_release(pSMB);
4369 goto UnixQPathInfoRetry;
4374 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4376 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4377 const char *searchName, struct cifs_sb_info *cifs_sb,
4378 __u16 *pnetfid, __u16 search_flags,
4379 struct cifs_search_info *psrch_inf, bool msearch)
4381 /* level 257 SMB_ */
4382 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4383 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4384 T2_FFIRST_RSP_PARMS *parms;
4386 int bytes_returned = 0;
4387 int name_len, remap;
4388 __u16 params, byte_count;
4389 struct nls_table *nls_codepage;
4391 cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4394 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4399 nls_codepage = cifs_sb->local_nls;
4400 remap = cifs_remap(cifs_sb);
4402 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4404 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4405 PATH_MAX, nls_codepage, remap);
4406 /* We can not add the asterik earlier in case
4407 it got remapped to 0xF03A as if it were part of the
4408 directory name instead of a wildcard */
4411 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4412 pSMB->FileName[name_len+1] = 0;
4413 pSMB->FileName[name_len+2] = '*';
4414 pSMB->FileName[name_len+3] = 0;
4415 name_len += 4; /* now the trailing null */
4416 /* null terminate just in case */
4417 pSMB->FileName[name_len] = 0;
4418 pSMB->FileName[name_len+1] = 0;
4422 name_len = copy_path_name(pSMB->FileName, searchName);
4424 if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4425 name_len = PATH_MAX-2;
4426 /* overwrite nul byte */
4427 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4428 pSMB->FileName[name_len] = '*';
4429 pSMB->FileName[name_len+1] = 0;
4434 params = 12 + name_len /* includes null */ ;
4435 pSMB->TotalDataCount = 0; /* no EAs */
4436 pSMB->MaxParameterCount = cpu_to_le16(10);
4437 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4438 pSMB->MaxSetupCount = 0;
4442 pSMB->Reserved2 = 0;
4443 byte_count = params + 1 /* pad */ ;
4444 pSMB->TotalParameterCount = cpu_to_le16(params);
4445 pSMB->ParameterCount = pSMB->TotalParameterCount;
4446 pSMB->ParameterOffset = cpu_to_le16(
4447 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4449 pSMB->DataCount = 0;
4450 pSMB->DataOffset = 0;
4451 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
4452 pSMB->Reserved3 = 0;
4453 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4454 pSMB->SearchAttributes =
4455 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4457 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4458 pSMB->SearchFlags = cpu_to_le16(search_flags);
4459 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4461 /* BB what should we set StorageType to? Does it matter? BB */
4462 pSMB->SearchStorageType = 0;
4463 inc_rfc1001_len(pSMB, byte_count);
4464 pSMB->ByteCount = cpu_to_le16(byte_count);
4466 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4467 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4468 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4470 if (rc) {/* BB add logic to retry regular search if Unix search
4471 rejected unexpectedly by server */
4472 /* BB Add code to handle unsupported level rc */
4473 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4475 cifs_buf_release(pSMB);
4477 /* BB eventually could optimize out free and realloc of buf */
4480 goto findFirstRetry;
4481 } else { /* decode response */
4482 /* BB remember to free buffer if error BB */
4483 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4487 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4488 psrch_inf->unicode = true;
4490 psrch_inf->unicode = false;
4492 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4493 psrch_inf->smallBuf = false;
4494 psrch_inf->srch_entries_start =
4495 (char *) &pSMBr->hdr.Protocol +
4496 le16_to_cpu(pSMBr->t2.DataOffset);
4497 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4498 le16_to_cpu(pSMBr->t2.ParameterOffset));
4500 if (parms->EndofSearch)
4501 psrch_inf->endOfSearch = true;
4503 psrch_inf->endOfSearch = false;
4505 psrch_inf->entries_in_buffer =
4506 le16_to_cpu(parms->SearchCount);
4507 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4508 psrch_inf->entries_in_buffer;
4509 lnoff = le16_to_cpu(parms->LastNameOffset);
4510 if (CIFSMaxBufSize < lnoff) {
4511 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4512 psrch_inf->last_entry = NULL;
4516 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4520 *pnetfid = parms->SearchHandle;
4522 cifs_buf_release(pSMB);
4529 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4530 __u16 searchHandle, __u16 search_flags,
4531 struct cifs_search_info *psrch_inf)
4533 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4534 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4535 T2_FNEXT_RSP_PARMS *parms;
4536 char *response_data;
4539 unsigned int name_len;
4540 __u16 params, byte_count;
4542 cifs_dbg(FYI, "In FindNext\n");
4544 if (psrch_inf->endOfSearch)
4547 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4552 params = 14; /* includes 2 bytes of null string, converted to LE below*/
4554 pSMB->TotalDataCount = 0; /* no EAs */
4555 pSMB->MaxParameterCount = cpu_to_le16(8);
4556 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4557 pSMB->MaxSetupCount = 0;
4561 pSMB->Reserved2 = 0;
4562 pSMB->ParameterOffset = cpu_to_le16(
4563 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4564 pSMB->DataCount = 0;
4565 pSMB->DataOffset = 0;
4566 pSMB->SetupCount = 1;
4567 pSMB->Reserved3 = 0;
4568 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4569 pSMB->SearchHandle = searchHandle; /* always kept as le */
4571 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4572 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4573 pSMB->ResumeKey = psrch_inf->resume_key;
4574 pSMB->SearchFlags = cpu_to_le16(search_flags);
4576 name_len = psrch_inf->resume_name_len;
4578 if (name_len < PATH_MAX) {
4579 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4580 byte_count += name_len;
4581 /* 14 byte parm len above enough for 2 byte null terminator */
4582 pSMB->ResumeFileName[name_len] = 0;
4583 pSMB->ResumeFileName[name_len+1] = 0;
4586 goto FNext2_err_exit;
4588 byte_count = params + 1 /* pad */ ;
4589 pSMB->TotalParameterCount = cpu_to_le16(params);
4590 pSMB->ParameterCount = pSMB->TotalParameterCount;
4591 inc_rfc1001_len(pSMB, byte_count);
4592 pSMB->ByteCount = cpu_to_le16(byte_count);
4594 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4595 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4596 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4599 psrch_inf->endOfSearch = true;
4600 cifs_buf_release(pSMB);
4601 rc = 0; /* search probably was closed at end of search*/
4603 cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4604 } else { /* decode response */
4605 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4610 /* BB fixme add lock for file (srch_info) struct here */
4611 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4612 psrch_inf->unicode = true;
4614 psrch_inf->unicode = false;
4615 response_data = (char *) &pSMBr->hdr.Protocol +
4616 le16_to_cpu(pSMBr->t2.ParameterOffset);
4617 parms = (T2_FNEXT_RSP_PARMS *)response_data;
4618 response_data = (char *)&pSMBr->hdr.Protocol +
4619 le16_to_cpu(pSMBr->t2.DataOffset);
4620 if (psrch_inf->smallBuf)
4621 cifs_small_buf_release(
4622 psrch_inf->ntwrk_buf_start);
4624 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4625 psrch_inf->srch_entries_start = response_data;
4626 psrch_inf->ntwrk_buf_start = (char *)pSMB;
4627 psrch_inf->smallBuf = false;
4628 if (parms->EndofSearch)
4629 psrch_inf->endOfSearch = true;
4631 psrch_inf->endOfSearch = false;
4632 psrch_inf->entries_in_buffer =
4633 le16_to_cpu(parms->SearchCount);
4634 psrch_inf->index_of_last_entry +=
4635 psrch_inf->entries_in_buffer;
4636 lnoff = le16_to_cpu(parms->LastNameOffset);
4637 if (CIFSMaxBufSize < lnoff) {
4638 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4639 psrch_inf->last_entry = NULL;
4642 psrch_inf->last_entry =
4643 psrch_inf->srch_entries_start + lnoff;
4645 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4646 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4648 /* BB fixme add unlock here */
4653 /* BB On error, should we leave previous search buf (and count and
4654 last entry fields) intact or free the previous one? */
4656 /* Note: On -EAGAIN error only caller can retry on handle based calls
4657 since file handle passed in no longer valid */
4660 cifs_buf_release(pSMB);
4665 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4666 const __u16 searchHandle)
4669 FINDCLOSE_REQ *pSMB = NULL;
4671 cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4672 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4674 /* no sense returning error if session restarted
4675 as file handle has been closed */
4681 pSMB->FileID = searchHandle;
4682 pSMB->ByteCount = 0;
4683 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4684 cifs_small_buf_release(pSMB);
4686 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4688 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4690 /* Since session is dead, search handle closed on server already */
4698 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4699 const char *search_name, __u64 *inode_number,
4700 const struct nls_table *nls_codepage, int remap)
4703 TRANSACTION2_QPI_REQ *pSMB = NULL;
4704 TRANSACTION2_QPI_RSP *pSMBr = NULL;
4705 int name_len, bytes_returned;
4706 __u16 params, byte_count;
4708 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4712 GetInodeNumberRetry:
4713 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4718 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4720 cifsConvertToUTF16((__le16 *) pSMB->FileName,
4721 search_name, PATH_MAX, nls_codepage,
4723 name_len++; /* trailing null */
4726 name_len = copy_path_name(pSMB->FileName, search_name);
4729 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
4730 pSMB->TotalDataCount = 0;
4731 pSMB->MaxParameterCount = cpu_to_le16(2);
4732 /* BB find exact max data count below from sess structure BB */
4733 pSMB->MaxDataCount = cpu_to_le16(4000);
4734 pSMB->MaxSetupCount = 0;
4738 pSMB->Reserved2 = 0;
4739 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4740 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4741 pSMB->DataCount = 0;
4742 pSMB->DataOffset = 0;
4743 pSMB->SetupCount = 1;
4744 pSMB->Reserved3 = 0;
4745 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4746 byte_count = params + 1 /* pad */ ;
4747 pSMB->TotalParameterCount = cpu_to_le16(params);
4748 pSMB->ParameterCount = pSMB->TotalParameterCount;
4749 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4750 pSMB->Reserved4 = 0;
4751 inc_rfc1001_len(pSMB, byte_count);
4752 pSMB->ByteCount = cpu_to_le16(byte_count);
4754 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4755 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4757 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4759 /* decode response */
4760 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4761 /* BB also check enough total bytes returned */
4762 if (rc || get_bcc(&pSMBr->hdr) < 2)
4763 /* If rc should we check for EOPNOSUPP and
4764 disable the srvino flag? or in caller? */
4765 rc = -EIO; /* bad smb */
4767 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4768 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4769 struct file_internal_info *pfinfo;
4770 /* BB Do we need a cast or hash here ? */
4772 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4774 goto GetInodeNumOut;
4776 pfinfo = (struct file_internal_info *)
4777 (data_offset + (char *) &pSMBr->hdr.Protocol);
4778 *inode_number = le64_to_cpu(pfinfo->UniqueId);
4782 cifs_buf_release(pSMB);
4784 goto GetInodeNumberRetry;
4789 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4790 const char *search_name, struct dfs_info3_param **target_nodes,
4791 unsigned int *num_of_nodes,
4792 const struct nls_table *nls_codepage, int remap)
4794 /* TRANS2_GET_DFS_REFERRAL */
4795 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4796 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4800 __u16 params, byte_count;
4802 *target_nodes = NULL;
4804 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4805 if (ses == NULL || ses->tcon_ipc == NULL)
4809 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4814 /* server pointer checked in called function,
4815 but should never be null here anyway */
4816 pSMB->hdr.Mid = get_next_mid(ses->server);
4817 pSMB->hdr.Tid = ses->tcon_ipc->tid;
4818 pSMB->hdr.Uid = ses->Suid;
4819 if (ses->capabilities & CAP_STATUS32)
4820 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4821 if (ses->capabilities & CAP_DFS)
4822 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4824 if (ses->capabilities & CAP_UNICODE) {
4825 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4827 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4828 search_name, PATH_MAX, nls_codepage,
4830 name_len++; /* trailing null */
4832 } else { /* BB improve the check for buffer overruns BB */
4833 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4836 if (ses->server->sign)
4837 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4839 pSMB->hdr.Uid = ses->Suid;
4841 params = 2 /* level */ + name_len /*includes null */ ;
4842 pSMB->TotalDataCount = 0;
4843 pSMB->DataCount = 0;
4844 pSMB->DataOffset = 0;
4845 pSMB->MaxParameterCount = 0;
4846 /* BB find exact max SMB PDU from sess structure BB */
4847 pSMB->MaxDataCount = cpu_to_le16(4000);
4848 pSMB->MaxSetupCount = 0;
4852 pSMB->Reserved2 = 0;
4853 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4854 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4855 pSMB->SetupCount = 1;
4856 pSMB->Reserved3 = 0;
4857 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4858 byte_count = params + 3 /* pad */ ;
4859 pSMB->ParameterCount = cpu_to_le16(params);
4860 pSMB->TotalParameterCount = pSMB->ParameterCount;
4861 pSMB->MaxReferralLevel = cpu_to_le16(3);
4862 inc_rfc1001_len(pSMB, byte_count);
4863 pSMB->ByteCount = cpu_to_le16(byte_count);
4865 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4866 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4868 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4871 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4873 /* BB Also check if enough total bytes returned? */
4874 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4875 rc = -EIO; /* bad smb */
4879 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4880 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4882 /* parse returned result into more usable form */
4883 rc = parse_dfs_referrals(&pSMBr->dfs_data,
4884 le16_to_cpu(pSMBr->t2.DataCount),
4885 num_of_nodes, target_nodes, nls_codepage,
4887 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4890 cifs_buf_release(pSMB);
4898 /* Query File System Info such as free space to old servers such as Win 9x */
4900 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4901 struct kstatfs *FSData)
4903 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4904 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4905 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4906 FILE_SYSTEM_ALLOC_INFO *response_data;
4908 int bytes_returned = 0;
4909 __u16 params, byte_count;
4911 cifs_dbg(FYI, "OldQFSInfo\n");
4913 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4918 params = 2; /* level */
4919 pSMB->TotalDataCount = 0;
4920 pSMB->MaxParameterCount = cpu_to_le16(2);
4921 pSMB->MaxDataCount = cpu_to_le16(1000);
4922 pSMB->MaxSetupCount = 0;
4926 pSMB->Reserved2 = 0;
4927 byte_count = params + 1 /* pad */ ;
4928 pSMB->TotalParameterCount = cpu_to_le16(params);
4929 pSMB->ParameterCount = pSMB->TotalParameterCount;
4930 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4931 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4932 pSMB->DataCount = 0;
4933 pSMB->DataOffset = 0;
4934 pSMB->SetupCount = 1;
4935 pSMB->Reserved3 = 0;
4936 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4937 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4938 inc_rfc1001_len(pSMB, byte_count);
4939 pSMB->ByteCount = cpu_to_le16(byte_count);
4941 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4942 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4944 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4945 } else { /* decode response */
4946 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4948 if (rc || get_bcc(&pSMBr->hdr) < 18)
4949 rc = -EIO; /* bad smb */
4951 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4952 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
4953 get_bcc(&pSMBr->hdr), data_offset);
4955 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4956 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4958 le16_to_cpu(response_data->BytesPerSector) *
4959 le32_to_cpu(response_data->
4960 SectorsPerAllocationUnit);
4962 * much prefer larger but if server doesn't report
4963 * a valid size than 4K is a reasonable minimum
4965 if (FSData->f_bsize < 512)
4966 FSData->f_bsize = 4096;
4969 le32_to_cpu(response_data->TotalAllocationUnits);
4970 FSData->f_bfree = FSData->f_bavail =
4971 le32_to_cpu(response_data->FreeAllocationUnits);
4972 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
4973 (unsigned long long)FSData->f_blocks,
4974 (unsigned long long)FSData->f_bfree,
4978 cifs_buf_release(pSMB);
4981 goto oldQFSInfoRetry;
4987 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4988 struct kstatfs *FSData)
4990 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4991 TRANSACTION2_QFSI_REQ *pSMB = NULL;
4992 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4993 FILE_SYSTEM_INFO *response_data;
4995 int bytes_returned = 0;
4996 __u16 params, byte_count;
4998 cifs_dbg(FYI, "In QFSInfo\n");
5000 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5005 params = 2; /* level */
5006 pSMB->TotalDataCount = 0;
5007 pSMB->MaxParameterCount = cpu_to_le16(2);
5008 pSMB->MaxDataCount = cpu_to_le16(1000);
5009 pSMB->MaxSetupCount = 0;
5013 pSMB->Reserved2 = 0;
5014 byte_count = params + 1 /* pad */ ;
5015 pSMB->TotalParameterCount = cpu_to_le16(params);
5016 pSMB->ParameterCount = pSMB->TotalParameterCount;
5017 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5018 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5019 pSMB->DataCount = 0;
5020 pSMB->DataOffset = 0;
5021 pSMB->SetupCount = 1;
5022 pSMB->Reserved3 = 0;
5023 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5024 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5025 inc_rfc1001_len(pSMB, byte_count);
5026 pSMB->ByteCount = cpu_to_le16(byte_count);
5028 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5029 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5031 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5032 } else { /* decode response */
5033 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5035 if (rc || get_bcc(&pSMBr->hdr) < 24)
5036 rc = -EIO; /* bad smb */
5038 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5042 *) (((char *) &pSMBr->hdr.Protocol) +
5045 le32_to_cpu(response_data->BytesPerSector) *
5046 le32_to_cpu(response_data->
5047 SectorsPerAllocationUnit);
5049 * much prefer larger but if server doesn't report
5050 * a valid size than 4K is a reasonable minimum
5052 if (FSData->f_bsize < 512)
5053 FSData->f_bsize = 4096;
5056 le64_to_cpu(response_data->TotalAllocationUnits);
5057 FSData->f_bfree = FSData->f_bavail =
5058 le64_to_cpu(response_data->FreeAllocationUnits);
5059 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
5060 (unsigned long long)FSData->f_blocks,
5061 (unsigned long long)FSData->f_bfree,
5065 cifs_buf_release(pSMB);
5074 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5076 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5077 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5078 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5079 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5081 int bytes_returned = 0;
5082 __u16 params, byte_count;
5084 cifs_dbg(FYI, "In QFSAttributeInfo\n");
5086 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5091 params = 2; /* level */
5092 pSMB->TotalDataCount = 0;
5093 pSMB->MaxParameterCount = cpu_to_le16(2);
5094 /* BB find exact max SMB PDU from sess structure BB */
5095 pSMB->MaxDataCount = cpu_to_le16(1000);
5096 pSMB->MaxSetupCount = 0;
5100 pSMB->Reserved2 = 0;
5101 byte_count = params + 1 /* pad */ ;
5102 pSMB->TotalParameterCount = cpu_to_le16(params);
5103 pSMB->ParameterCount = pSMB->TotalParameterCount;
5104 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5105 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5106 pSMB->DataCount = 0;
5107 pSMB->DataOffset = 0;
5108 pSMB->SetupCount = 1;
5109 pSMB->Reserved3 = 0;
5110 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5111 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5112 inc_rfc1001_len(pSMB, byte_count);
5113 pSMB->ByteCount = cpu_to_le16(byte_count);
5115 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5116 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5118 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5119 } else { /* decode response */
5120 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5122 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5123 /* BB also check if enough bytes returned */
5124 rc = -EIO; /* bad smb */
5126 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5128 (FILE_SYSTEM_ATTRIBUTE_INFO
5129 *) (((char *) &pSMBr->hdr.Protocol) +
5131 memcpy(&tcon->fsAttrInfo, response_data,
5132 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5135 cifs_buf_release(pSMB);
5138 goto QFSAttributeRetry;
5144 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5146 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5147 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5148 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5149 FILE_SYSTEM_DEVICE_INFO *response_data;
5151 int bytes_returned = 0;
5152 __u16 params, byte_count;
5154 cifs_dbg(FYI, "In QFSDeviceInfo\n");
5156 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5161 params = 2; /* level */
5162 pSMB->TotalDataCount = 0;
5163 pSMB->MaxParameterCount = cpu_to_le16(2);
5164 /* BB find exact max SMB PDU from sess structure BB */
5165 pSMB->MaxDataCount = cpu_to_le16(1000);
5166 pSMB->MaxSetupCount = 0;
5170 pSMB->Reserved2 = 0;
5171 byte_count = params + 1 /* pad */ ;
5172 pSMB->TotalParameterCount = cpu_to_le16(params);
5173 pSMB->ParameterCount = pSMB->TotalParameterCount;
5174 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5175 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5177 pSMB->DataCount = 0;
5178 pSMB->DataOffset = 0;
5179 pSMB->SetupCount = 1;
5180 pSMB->Reserved3 = 0;
5181 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5182 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5183 inc_rfc1001_len(pSMB, byte_count);
5184 pSMB->ByteCount = cpu_to_le16(byte_count);
5186 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5187 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5189 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5190 } else { /* decode response */
5191 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5193 if (rc || get_bcc(&pSMBr->hdr) <
5194 sizeof(FILE_SYSTEM_DEVICE_INFO))
5195 rc = -EIO; /* bad smb */
5197 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5199 (FILE_SYSTEM_DEVICE_INFO *)
5200 (((char *) &pSMBr->hdr.Protocol) +
5202 memcpy(&tcon->fsDevInfo, response_data,
5203 sizeof(FILE_SYSTEM_DEVICE_INFO));
5206 cifs_buf_release(pSMB);
5209 goto QFSDeviceRetry;
5215 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5217 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5218 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5219 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5220 FILE_SYSTEM_UNIX_INFO *response_data;
5222 int bytes_returned = 0;
5223 __u16 params, byte_count;
5225 cifs_dbg(FYI, "In QFSUnixInfo\n");
5227 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5228 (void **) &pSMB, (void **) &pSMBr);
5232 params = 2; /* level */
5233 pSMB->TotalDataCount = 0;
5234 pSMB->DataCount = 0;
5235 pSMB->DataOffset = 0;
5236 pSMB->MaxParameterCount = cpu_to_le16(2);
5237 /* BB find exact max SMB PDU from sess structure BB */
5238 pSMB->MaxDataCount = cpu_to_le16(100);
5239 pSMB->MaxSetupCount = 0;
5243 pSMB->Reserved2 = 0;
5244 byte_count = params + 1 /* pad */ ;
5245 pSMB->ParameterCount = cpu_to_le16(params);
5246 pSMB->TotalParameterCount = pSMB->ParameterCount;
5247 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5248 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5249 pSMB->SetupCount = 1;
5250 pSMB->Reserved3 = 0;
5251 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5252 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5253 inc_rfc1001_len(pSMB, byte_count);
5254 pSMB->ByteCount = cpu_to_le16(byte_count);
5256 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5257 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5259 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5260 } else { /* decode response */
5261 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5263 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5264 rc = -EIO; /* bad smb */
5266 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5268 (FILE_SYSTEM_UNIX_INFO
5269 *) (((char *) &pSMBr->hdr.Protocol) +
5271 memcpy(&tcon->fsUnixInfo, response_data,
5272 sizeof(FILE_SYSTEM_UNIX_INFO));
5275 cifs_buf_release(pSMB);
5285 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5287 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5288 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5289 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5291 int bytes_returned = 0;
5292 __u16 params, param_offset, offset, byte_count;
5294 cifs_dbg(FYI, "In SETFSUnixInfo\n");
5296 /* BB switch to small buf init to save memory */
5297 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5298 (void **) &pSMB, (void **) &pSMBr);
5302 params = 4; /* 2 bytes zero followed by info level. */
5303 pSMB->MaxSetupCount = 0;
5307 pSMB->Reserved2 = 0;
5308 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5310 offset = param_offset + params;
5312 pSMB->MaxParameterCount = cpu_to_le16(4);
5313 /* BB find exact max SMB PDU from sess structure BB */
5314 pSMB->MaxDataCount = cpu_to_le16(100);
5315 pSMB->SetupCount = 1;
5316 pSMB->Reserved3 = 0;
5317 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5318 byte_count = 1 /* pad */ + params + 12;
5320 pSMB->DataCount = cpu_to_le16(12);
5321 pSMB->ParameterCount = cpu_to_le16(params);
5322 pSMB->TotalDataCount = pSMB->DataCount;
5323 pSMB->TotalParameterCount = pSMB->ParameterCount;
5324 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5325 pSMB->DataOffset = cpu_to_le16(offset);
5329 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5332 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5333 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5334 pSMB->ClientUnixCap = cpu_to_le64(cap);
5336 inc_rfc1001_len(pSMB, byte_count);
5337 pSMB->ByteCount = cpu_to_le16(byte_count);
5339 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5340 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5342 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5343 } else { /* decode response */
5344 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5346 rc = -EIO; /* bad smb */
5348 cifs_buf_release(pSMB);
5351 goto SETFSUnixRetry;
5359 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5360 struct kstatfs *FSData)
5362 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5363 TRANSACTION2_QFSI_REQ *pSMB = NULL;
5364 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5365 FILE_SYSTEM_POSIX_INFO *response_data;
5367 int bytes_returned = 0;
5368 __u16 params, byte_count;
5370 cifs_dbg(FYI, "In QFSPosixInfo\n");
5372 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5377 params = 2; /* level */
5378 pSMB->TotalDataCount = 0;
5379 pSMB->DataCount = 0;
5380 pSMB->DataOffset = 0;
5381 pSMB->MaxParameterCount = cpu_to_le16(2);
5382 /* BB find exact max SMB PDU from sess structure BB */
5383 pSMB->MaxDataCount = cpu_to_le16(100);
5384 pSMB->MaxSetupCount = 0;
5388 pSMB->Reserved2 = 0;
5389 byte_count = params + 1 /* pad */ ;
5390 pSMB->ParameterCount = cpu_to_le16(params);
5391 pSMB->TotalParameterCount = pSMB->ParameterCount;
5392 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5393 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5394 pSMB->SetupCount = 1;
5395 pSMB->Reserved3 = 0;
5396 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5397 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5398 inc_rfc1001_len(pSMB, byte_count);
5399 pSMB->ByteCount = cpu_to_le16(byte_count);
5401 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5402 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5404 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5405 } else { /* decode response */
5406 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5408 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5409 rc = -EIO; /* bad smb */
5411 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5413 (FILE_SYSTEM_POSIX_INFO
5414 *) (((char *) &pSMBr->hdr.Protocol) +
5417 le32_to_cpu(response_data->BlockSize);
5419 * much prefer larger but if server doesn't report
5420 * a valid size than 4K is a reasonable minimum
5422 if (FSData->f_bsize < 512)
5423 FSData->f_bsize = 4096;
5426 le64_to_cpu(response_data->TotalBlocks);
5428 le64_to_cpu(response_data->BlocksAvail);
5429 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5430 FSData->f_bavail = FSData->f_bfree;
5433 le64_to_cpu(response_data->UserBlocksAvail);
5435 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5437 le64_to_cpu(response_data->TotalFileNodes);
5438 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5440 le64_to_cpu(response_data->FreeFileNodes);
5443 cifs_buf_release(pSMB);
5453 * We can not use write of zero bytes trick to set file size due to need for
5454 * large file support. Also note that this SetPathInfo is preferred to
5455 * SetFileInfo based method in next routine which is only needed to work around
5456 * a sharing violation bugin Samba which this routine can run into.
5459 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5460 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5461 bool set_allocation)
5463 struct smb_com_transaction2_spi_req *pSMB = NULL;
5464 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5465 struct file_end_of_file_info *parm_data;
5468 int bytes_returned = 0;
5469 int remap = cifs_remap(cifs_sb);
5471 __u16 params, byte_count, data_count, param_offset, offset;
5473 cifs_dbg(FYI, "In SetEOF\n");
5475 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5480 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5482 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5483 PATH_MAX, cifs_sb->local_nls, remap);
5484 name_len++; /* trailing null */
5487 name_len = copy_path_name(pSMB->FileName, file_name);
5489 params = 6 + name_len;
5490 data_count = sizeof(struct file_end_of_file_info);
5491 pSMB->MaxParameterCount = cpu_to_le16(2);
5492 pSMB->MaxDataCount = cpu_to_le16(4100);
5493 pSMB->MaxSetupCount = 0;
5497 pSMB->Reserved2 = 0;
5498 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5499 InformationLevel) - 4;
5500 offset = param_offset + params;
5501 if (set_allocation) {
5502 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5503 pSMB->InformationLevel =
5504 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5506 pSMB->InformationLevel =
5507 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5508 } else /* Set File Size */ {
5509 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5510 pSMB->InformationLevel =
5511 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5513 pSMB->InformationLevel =
5514 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5518 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5520 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5521 pSMB->DataOffset = cpu_to_le16(offset);
5522 pSMB->SetupCount = 1;
5523 pSMB->Reserved3 = 0;
5524 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5525 byte_count = 3 /* pad */ + params + data_count;
5526 pSMB->DataCount = cpu_to_le16(data_count);
5527 pSMB->TotalDataCount = pSMB->DataCount;
5528 pSMB->ParameterCount = cpu_to_le16(params);
5529 pSMB->TotalParameterCount = pSMB->ParameterCount;
5530 pSMB->Reserved4 = 0;
5531 inc_rfc1001_len(pSMB, byte_count);
5532 parm_data->FileSize = cpu_to_le64(size);
5533 pSMB->ByteCount = cpu_to_le16(byte_count);
5534 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5535 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5537 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5539 cifs_buf_release(pSMB);
5548 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5549 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5551 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5552 struct file_end_of_file_info *parm_data;
5554 __u16 params, param_offset, offset, byte_count, count;
5556 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5558 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5563 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5564 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5567 pSMB->MaxSetupCount = 0;
5571 pSMB->Reserved2 = 0;
5572 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5573 offset = param_offset + params;
5575 count = sizeof(struct file_end_of_file_info);
5576 pSMB->MaxParameterCount = cpu_to_le16(2);
5577 /* BB find exact max SMB PDU from sess structure BB */
5578 pSMB->MaxDataCount = cpu_to_le16(1000);
5579 pSMB->SetupCount = 1;
5580 pSMB->Reserved3 = 0;
5581 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5582 byte_count = 3 /* pad */ + params + count;
5583 pSMB->DataCount = cpu_to_le16(count);
5584 pSMB->ParameterCount = cpu_to_le16(params);
5585 pSMB->TotalDataCount = pSMB->DataCount;
5586 pSMB->TotalParameterCount = pSMB->ParameterCount;
5587 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5588 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5590 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5591 pSMB->DataOffset = cpu_to_le16(offset);
5592 parm_data->FileSize = cpu_to_le64(size);
5593 pSMB->Fid = cfile->fid.netfid;
5594 if (set_allocation) {
5595 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5596 pSMB->InformationLevel =
5597 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5599 pSMB->InformationLevel =
5600 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5601 } else /* Set File Size */ {
5602 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5603 pSMB->InformationLevel =
5604 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5606 pSMB->InformationLevel =
5607 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5609 pSMB->Reserved4 = 0;
5610 inc_rfc1001_len(pSMB, byte_count);
5611 pSMB->ByteCount = cpu_to_le16(byte_count);
5612 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5613 cifs_small_buf_release(pSMB);
5615 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5619 /* Note: On -EAGAIN error only caller can retry on handle based calls
5620 since file handle passed in no longer valid */
5625 /* Some legacy servers such as NT4 require that the file times be set on
5626 an open handle, rather than by pathname - this is awkward due to
5627 potential access conflicts on the open, but it is unavoidable for these
5628 old servers since the only other choice is to go from 100 nanosecond DCE
5629 time and resort to the original setpathinfo level which takes the ancient
5630 DOS time format with 2 second granularity */
5632 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5633 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5635 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5638 __u16 params, param_offset, offset, byte_count, count;
5640 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5641 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5646 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5647 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5650 pSMB->MaxSetupCount = 0;
5654 pSMB->Reserved2 = 0;
5655 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5656 offset = param_offset + params;
5658 data_offset = (char *)pSMB +
5659 offsetof(struct smb_hdr, Protocol) + offset;
5661 count = sizeof(FILE_BASIC_INFO);
5662 pSMB->MaxParameterCount = cpu_to_le16(2);
5663 /* BB find max SMB PDU from sess */
5664 pSMB->MaxDataCount = cpu_to_le16(1000);
5665 pSMB->SetupCount = 1;
5666 pSMB->Reserved3 = 0;
5667 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5668 byte_count = 3 /* pad */ + params + count;
5669 pSMB->DataCount = cpu_to_le16(count);
5670 pSMB->ParameterCount = cpu_to_le16(params);
5671 pSMB->TotalDataCount = pSMB->DataCount;
5672 pSMB->TotalParameterCount = pSMB->ParameterCount;
5673 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5674 pSMB->DataOffset = cpu_to_le16(offset);
5676 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5677 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5679 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5680 pSMB->Reserved4 = 0;
5681 inc_rfc1001_len(pSMB, byte_count);
5682 pSMB->ByteCount = cpu_to_le16(byte_count);
5683 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5684 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5685 cifs_small_buf_release(pSMB);
5687 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5690 /* Note: On -EAGAIN error only caller can retry on handle based calls
5691 since file handle passed in no longer valid */
5697 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5698 bool delete_file, __u16 fid, __u32 pid_of_opener)
5700 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5703 __u16 params, param_offset, offset, byte_count, count;
5705 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5706 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5711 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5712 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5715 pSMB->MaxSetupCount = 0;
5719 pSMB->Reserved2 = 0;
5720 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5721 offset = param_offset + params;
5723 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5724 data_offset = (char *)(pSMB) + offset + 4;
5727 pSMB->MaxParameterCount = cpu_to_le16(2);
5728 /* BB find max SMB PDU from sess */
5729 pSMB->MaxDataCount = cpu_to_le16(1000);
5730 pSMB->SetupCount = 1;
5731 pSMB->Reserved3 = 0;
5732 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5733 byte_count = 3 /* pad */ + params + count;
5734 pSMB->DataCount = cpu_to_le16(count);
5735 pSMB->ParameterCount = cpu_to_le16(params);
5736 pSMB->TotalDataCount = pSMB->DataCount;
5737 pSMB->TotalParameterCount = pSMB->ParameterCount;
5738 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5739 pSMB->DataOffset = cpu_to_le16(offset);
5741 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5742 pSMB->Reserved4 = 0;
5743 inc_rfc1001_len(pSMB, byte_count);
5744 pSMB->ByteCount = cpu_to_le16(byte_count);
5745 *data_offset = delete_file ? 1 : 0;
5746 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5747 cifs_small_buf_release(pSMB);
5749 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5755 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5756 const char *fileName, const FILE_BASIC_INFO *data,
5757 const struct nls_table *nls_codepage,
5758 struct cifs_sb_info *cifs_sb)
5761 struct cifs_open_parms oparms;
5762 struct cifs_fid fid;
5766 oparms.cifs_sb = cifs_sb;
5767 oparms.desired_access = GENERIC_WRITE;
5768 oparms.create_options = cifs_create_options(cifs_sb, 0);
5769 oparms.disposition = FILE_OPEN;
5770 oparms.path = fileName;
5772 oparms.reconnect = false;
5774 rc = CIFS_open(xid, &oparms, &oplock, NULL);
5778 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5779 CIFSSMBClose(xid, tcon, fid.netfid);
5786 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5787 const char *fileName, const FILE_BASIC_INFO *data,
5788 const struct nls_table *nls_codepage,
5789 struct cifs_sb_info *cifs_sb)
5791 TRANSACTION2_SPI_REQ *pSMB = NULL;
5792 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5795 int bytes_returned = 0;
5797 __u16 params, param_offset, offset, byte_count, count;
5798 int remap = cifs_remap(cifs_sb);
5800 cifs_dbg(FYI, "In SetTimes\n");
5803 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5808 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5810 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5811 PATH_MAX, nls_codepage, remap);
5812 name_len++; /* trailing null */
5815 name_len = copy_path_name(pSMB->FileName, fileName);
5818 params = 6 + name_len;
5819 count = sizeof(FILE_BASIC_INFO);
5820 pSMB->MaxParameterCount = cpu_to_le16(2);
5821 /* BB find max SMB PDU from sess structure BB */
5822 pSMB->MaxDataCount = cpu_to_le16(1000);
5823 pSMB->MaxSetupCount = 0;
5827 pSMB->Reserved2 = 0;
5828 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5829 InformationLevel) - 4;
5830 offset = param_offset + params;
5831 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5832 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5833 pSMB->DataOffset = cpu_to_le16(offset);
5834 pSMB->SetupCount = 1;
5835 pSMB->Reserved3 = 0;
5836 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5837 byte_count = 3 /* pad */ + params + count;
5839 pSMB->DataCount = cpu_to_le16(count);
5840 pSMB->ParameterCount = cpu_to_le16(params);
5841 pSMB->TotalDataCount = pSMB->DataCount;
5842 pSMB->TotalParameterCount = pSMB->ParameterCount;
5843 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5844 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5846 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5847 pSMB->Reserved4 = 0;
5848 inc_rfc1001_len(pSMB, byte_count);
5849 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5850 pSMB->ByteCount = cpu_to_le16(byte_count);
5851 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5852 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5854 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5856 cifs_buf_release(pSMB);
5861 if (rc == -EOPNOTSUPP)
5862 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5863 nls_codepage, cifs_sb);
5869 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5870 const struct cifs_unix_set_info_args *args)
5872 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5873 u64 mode = args->mode;
5875 if (uid_valid(args->uid))
5876 uid = from_kuid(&init_user_ns, args->uid);
5877 if (gid_valid(args->gid))
5878 gid = from_kgid(&init_user_ns, args->gid);
5881 * Samba server ignores set of file size to zero due to bugs in some
5882 * older clients, but we should be precise - we use SetFileSize to
5883 * set file size and do not want to truncate file size to zero
5884 * accidentally as happened on one Samba server beta by putting
5885 * zero instead of -1 here
5887 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5888 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5889 data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5890 data_offset->LastAccessTime = cpu_to_le64(args->atime);
5891 data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5892 data_offset->Uid = cpu_to_le64(uid);
5893 data_offset->Gid = cpu_to_le64(gid);
5894 /* better to leave device as zero when it is */
5895 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5896 data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5897 data_offset->Permissions = cpu_to_le64(mode);
5900 data_offset->Type = cpu_to_le32(UNIX_FILE);
5901 else if (S_ISDIR(mode))
5902 data_offset->Type = cpu_to_le32(UNIX_DIR);
5903 else if (S_ISLNK(mode))
5904 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5905 else if (S_ISCHR(mode))
5906 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5907 else if (S_ISBLK(mode))
5908 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5909 else if (S_ISFIFO(mode))
5910 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5911 else if (S_ISSOCK(mode))
5912 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5916 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5917 const struct cifs_unix_set_info_args *args,
5918 u16 fid, u32 pid_of_opener)
5920 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5923 u16 params, param_offset, offset, byte_count, count;
5925 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5926 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5931 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5932 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5935 pSMB->MaxSetupCount = 0;
5939 pSMB->Reserved2 = 0;
5940 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5941 offset = param_offset + params;
5943 data_offset = (char *)pSMB +
5944 offsetof(struct smb_hdr, Protocol) + offset;
5946 count = sizeof(FILE_UNIX_BASIC_INFO);
5948 pSMB->MaxParameterCount = cpu_to_le16(2);
5949 /* BB find max SMB PDU from sess */
5950 pSMB->MaxDataCount = cpu_to_le16(1000);
5951 pSMB->SetupCount = 1;
5952 pSMB->Reserved3 = 0;
5953 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5954 byte_count = 3 /* pad */ + params + count;
5955 pSMB->DataCount = cpu_to_le16(count);
5956 pSMB->ParameterCount = cpu_to_le16(params);
5957 pSMB->TotalDataCount = pSMB->DataCount;
5958 pSMB->TotalParameterCount = pSMB->ParameterCount;
5959 pSMB->ParameterOffset = cpu_to_le16(param_offset);
5960 pSMB->DataOffset = cpu_to_le16(offset);
5962 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5963 pSMB->Reserved4 = 0;
5964 inc_rfc1001_len(pSMB, byte_count);
5965 pSMB->ByteCount = cpu_to_le16(byte_count);
5967 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5969 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5970 cifs_small_buf_release(pSMB);
5972 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5975 /* Note: On -EAGAIN error only caller can retry on handle based calls
5976 since file handle passed in no longer valid */
5982 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5983 const char *file_name,
5984 const struct cifs_unix_set_info_args *args,
5985 const struct nls_table *nls_codepage, int remap)
5987 TRANSACTION2_SPI_REQ *pSMB = NULL;
5988 TRANSACTION2_SPI_RSP *pSMBr = NULL;
5991 int bytes_returned = 0;
5992 FILE_UNIX_BASIC_INFO *data_offset;
5993 __u16 params, param_offset, offset, count, byte_count;
5995 cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5997 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6002 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6004 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6005 PATH_MAX, nls_codepage, remap);
6006 name_len++; /* trailing null */
6009 name_len = copy_path_name(pSMB->FileName, file_name);
6012 params = 6 + name_len;
6013 count = sizeof(FILE_UNIX_BASIC_INFO);
6014 pSMB->MaxParameterCount = cpu_to_le16(2);
6015 /* BB find max SMB PDU from sess structure BB */
6016 pSMB->MaxDataCount = cpu_to_le16(1000);
6017 pSMB->MaxSetupCount = 0;
6021 pSMB->Reserved2 = 0;
6022 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6023 InformationLevel) - 4;
6024 offset = param_offset + params;
6025 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
6026 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
6027 memset(data_offset, 0, count);
6028 pSMB->DataOffset = cpu_to_le16(offset);
6029 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6030 pSMB->SetupCount = 1;
6031 pSMB->Reserved3 = 0;
6032 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6033 byte_count = 3 /* pad */ + params + count;
6034 pSMB->ParameterCount = cpu_to_le16(params);
6035 pSMB->DataCount = cpu_to_le16(count);
6036 pSMB->TotalParameterCount = pSMB->ParameterCount;
6037 pSMB->TotalDataCount = pSMB->DataCount;
6038 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6039 pSMB->Reserved4 = 0;
6040 inc_rfc1001_len(pSMB, byte_count);
6042 cifs_fill_unix_set_info(data_offset, args);
6044 pSMB->ByteCount = cpu_to_le16(byte_count);
6045 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6046 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6048 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6050 cifs_buf_release(pSMB);
6056 #ifdef CONFIG_CIFS_XATTR
6058 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6059 * function used by listxattr and getxattr type calls. When ea_name is set,
6060 * it looks for that attribute name and stuffs that value into the EAData
6061 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6062 * buffer. In both cases, the return value is either the length of the
6063 * resulting data or a negative error code. If EAData is a NULL pointer then
6064 * the data isn't copied to it, but the length is returned.
6067 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6068 const unsigned char *searchName, const unsigned char *ea_name,
6069 char *EAData, size_t buf_size,
6070 struct cifs_sb_info *cifs_sb)
6072 /* BB assumes one setup word */
6073 TRANSACTION2_QPI_REQ *pSMB = NULL;
6074 TRANSACTION2_QPI_RSP *pSMBr = NULL;
6075 int remap = cifs_remap(cifs_sb);
6076 struct nls_table *nls_codepage = cifs_sb->local_nls;
6080 struct fealist *ea_response_data;
6081 struct fea *temp_fea;
6084 __u16 params, byte_count, data_offset;
6085 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6087 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6089 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6094 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6096 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6097 PATH_MAX, nls_codepage, remap);
6098 list_len++; /* trailing null */
6101 list_len = copy_path_name(pSMB->FileName, searchName);
6104 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6105 pSMB->TotalDataCount = 0;
6106 pSMB->MaxParameterCount = cpu_to_le16(2);
6107 /* BB find exact max SMB PDU from sess structure BB */
6108 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6109 pSMB->MaxSetupCount = 0;
6113 pSMB->Reserved2 = 0;
6114 pSMB->ParameterOffset = cpu_to_le16(offsetof(
6115 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6116 pSMB->DataCount = 0;
6117 pSMB->DataOffset = 0;
6118 pSMB->SetupCount = 1;
6119 pSMB->Reserved3 = 0;
6120 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6121 byte_count = params + 1 /* pad */ ;
6122 pSMB->TotalParameterCount = cpu_to_le16(params);
6123 pSMB->ParameterCount = pSMB->TotalParameterCount;
6124 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6125 pSMB->Reserved4 = 0;
6126 inc_rfc1001_len(pSMB, byte_count);
6127 pSMB->ByteCount = cpu_to_le16(byte_count);
6129 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6130 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6132 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6137 /* BB also check enough total bytes returned */
6138 /* BB we need to improve the validity checking
6139 of these trans2 responses */
6141 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6142 if (rc || get_bcc(&pSMBr->hdr) < 4) {
6143 rc = -EIO; /* bad smb */
6147 /* check that length of list is not more than bcc */
6148 /* check that each entry does not go beyond length
6150 /* check that each element of each entry does not
6151 go beyond end of list */
6152 /* validate_trans2_offsets() */
6153 /* BB check if start of smb + data_offset > &bcc+ bcc */
6155 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6156 ea_response_data = (struct fealist *)
6157 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6159 list_len = le32_to_cpu(ea_response_data->list_len);
6160 cifs_dbg(FYI, "ea length %d\n", list_len);
6161 if (list_len <= 8) {
6162 cifs_dbg(FYI, "empty EA list returned from server\n");
6163 /* didn't find the named attribute */
6169 /* make sure list_len doesn't go past end of SMB */
6170 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6171 if ((char *)ea_response_data + list_len > end_of_smb) {
6172 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6177 /* account for ea list len */
6179 temp_fea = ea_response_data->list;
6180 temp_ptr = (char *)temp_fea;
6181 while (list_len > 0) {
6182 unsigned int name_len;
6187 /* make sure we can read name_len and value_len */
6189 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6194 name_len = temp_fea->name_len;
6195 value_len = le16_to_cpu(temp_fea->value_len);
6196 list_len -= name_len + 1 + value_len;
6198 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6204 if (ea_name_len == name_len &&
6205 memcmp(ea_name, temp_ptr, name_len) == 0) {
6206 temp_ptr += name_len + 1;
6210 if ((size_t)value_len > buf_size) {
6214 memcpy(EAData, temp_ptr, value_len);
6218 /* account for prefix user. and trailing null */
6219 rc += (5 + 1 + name_len);
6220 if (rc < (int) buf_size) {
6221 memcpy(EAData, "user.", 5);
6223 memcpy(EAData, temp_ptr, name_len);
6225 /* null terminate name */
6228 } else if (buf_size == 0) {
6229 /* skip copy - calc size only */
6231 /* stop before overrun buffer */
6236 temp_ptr += name_len + 1 + value_len;
6237 temp_fea = (struct fea *)temp_ptr;
6240 /* didn't find the named attribute */
6245 cifs_buf_release(pSMB);
6253 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6254 const char *fileName, const char *ea_name, const void *ea_value,
6255 const __u16 ea_value_len, const struct nls_table *nls_codepage,
6256 struct cifs_sb_info *cifs_sb)
6258 struct smb_com_transaction2_spi_req *pSMB = NULL;
6259 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6260 struct fealist *parm_data;
6263 int bytes_returned = 0;
6264 __u16 params, param_offset, byte_count, offset, count;
6265 int remap = cifs_remap(cifs_sb);
6267 cifs_dbg(FYI, "In SetEA\n");
6269 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6274 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6276 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6277 PATH_MAX, nls_codepage, remap);
6278 name_len++; /* trailing null */
6281 name_len = copy_path_name(pSMB->FileName, fileName);
6284 params = 6 + name_len;
6286 /* done calculating parms using name_len of file name,
6287 now use name_len to calculate length of ea name
6288 we are going to create in the inode xattrs */
6289 if (ea_name == NULL)
6292 name_len = strnlen(ea_name, 255);
6294 count = sizeof(*parm_data) + ea_value_len + name_len;
6295 pSMB->MaxParameterCount = cpu_to_le16(2);
6296 /* BB find max SMB PDU from sess */
6297 pSMB->MaxDataCount = cpu_to_le16(1000);
6298 pSMB->MaxSetupCount = 0;
6302 pSMB->Reserved2 = 0;
6303 param_offset = offsetof(struct smb_com_transaction2_spi_req,
6304 InformationLevel) - 4;
6305 offset = param_offset + params;
6306 pSMB->InformationLevel =
6307 cpu_to_le16(SMB_SET_FILE_EA);
6309 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6310 pSMB->ParameterOffset = cpu_to_le16(param_offset);
6311 pSMB->DataOffset = cpu_to_le16(offset);
6312 pSMB->SetupCount = 1;
6313 pSMB->Reserved3 = 0;
6314 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6315 byte_count = 3 /* pad */ + params + count;
6316 pSMB->DataCount = cpu_to_le16(count);
6317 parm_data->list_len = cpu_to_le32(count);
6318 parm_data->list[0].EA_flags = 0;
6319 /* we checked above that name len is less than 255 */
6320 parm_data->list[0].name_len = (__u8)name_len;
6321 /* EA names are always ASCII */
6323 strncpy(parm_data->list[0].name, ea_name, name_len);
6324 parm_data->list[0].name[name_len] = 0;
6325 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6326 /* caller ensures that ea_value_len is less than 64K but
6327 we need to ensure that it fits within the smb */
6329 /*BB add length check to see if it would fit in
6330 negotiated SMB buffer size BB */
6331 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6333 memcpy(parm_data->list[0].name+name_len+1,
6334 ea_value, ea_value_len);
6336 pSMB->TotalDataCount = pSMB->DataCount;
6337 pSMB->ParameterCount = cpu_to_le16(params);
6338 pSMB->TotalParameterCount = pSMB->ParameterCount;
6339 pSMB->Reserved4 = 0;
6340 inc_rfc1001_len(pSMB, byte_count);
6341 pSMB->ByteCount = cpu_to_le16(byte_count);
6342 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6343 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6345 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6347 cifs_buf_release(pSMB);