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"
33 #include "smbdirect.h"
34 #ifdef CONFIG_CIFS_DFS_UPCALL
35 #include "dfs_cache.h"
38 #ifdef CONFIG_CIFS_POSIX
43 {CIFS_PROT
, "\2NT LM 0.12"},
44 {POSIX_PROT
, "\2POSIX 2"},
52 {CIFS_PROT
, "\2NT LM 0.12"},
57 /* define the number of elements in the cifs dialect array */
58 #ifdef CONFIG_CIFS_POSIX
59 #define CIFS_NUM_PROT 2
61 #define CIFS_NUM_PROT 1
62 #endif /* CIFS_POSIX */
65 /* reconnect the socket, tcon, and smb session if needed */
67 cifs_reconnect_tcon(struct cifs_tcon
*tcon
, int smb_command
)
71 struct TCP_Server_Info
*server
;
72 struct nls_table
*nls_codepage
;
75 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
76 * tcp and smb session status done differently for those three - in the
86 * only tree disconnect, open, and write, (and ulogoff which does not
87 * have tcon) are allowed as we start umount
89 spin_lock(&tcon
->tc_lock
);
90 if (tcon
->status
== TID_EXITING
) {
91 if (smb_command
!= SMB_COM_TREE_DISCONNECT
) {
92 spin_unlock(&tcon
->tc_lock
);
93 cifs_dbg(FYI
, "can not send cmd %d while umounting\n",
98 spin_unlock(&tcon
->tc_lock
);
100 rc
= cifs_wait_for_server_reconnect(server
, tcon
->retry
);
104 spin_lock(&ses
->chan_lock
);
105 if (!cifs_chan_needs_reconnect(ses
, server
) && !tcon
->need_reconnect
) {
106 spin_unlock(&ses
->chan_lock
);
109 spin_unlock(&ses
->chan_lock
);
111 nls_codepage
= load_nls_default();
114 * Recheck after acquire mutex. If another thread is negotiating
115 * and the server never sends an answer the socket will be closed
116 * and tcpStatus set to reconnect.
118 spin_lock(&server
->srv_lock
);
119 if (server
->tcpStatus
== CifsNeedReconnect
) {
120 spin_unlock(&server
->srv_lock
);
124 spin_unlock(&server
->srv_lock
);
127 * need to prevent multiple threads trying to simultaneously
128 * reconnect the same SMB session
130 spin_lock(&ses
->chan_lock
);
131 if (!cifs_chan_needs_reconnect(ses
, server
)) {
132 spin_unlock(&ses
->chan_lock
);
134 /* this means that we only need to tree connect */
135 if (tcon
->need_reconnect
)
136 goto skip_sess_setup
;
141 spin_unlock(&ses
->chan_lock
);
143 mutex_lock(&ses
->session_mutex
);
144 rc
= cifs_negotiate_protocol(0, ses
, server
);
146 rc
= cifs_setup_session(0, ses
, server
, nls_codepage
);
148 /* do we need to reconnect tcon? */
149 if (rc
|| !tcon
->need_reconnect
) {
150 mutex_unlock(&ses
->session_mutex
);
155 cifs_mark_open_files_invalid(tcon
);
156 rc
= cifs_tree_connect(0, tcon
, nls_codepage
);
157 mutex_unlock(&ses
->session_mutex
);
158 cifs_dbg(FYI
, "reconnect tcon rc = %d\n", rc
);
161 pr_warn_once("reconnect tcon failed rc = %d\n", rc
);
165 atomic_inc(&tconInfoReconnectCount
);
167 /* tell server Unix caps we support */
169 reset_cifs_unix_caps(0, tcon
, NULL
, NULL
);
172 * Removed call to reopen open files here. It is safer (and faster) to
173 * reopen files one at a time as needed in read and write.
175 * FIXME: what about file locks? don't we need to reclaim them ASAP?
180 * Check if handle based operation so we know whether we can continue
181 * or not without returning to caller to reset file handle
183 switch (smb_command
) {
184 case SMB_COM_READ_ANDX
:
185 case SMB_COM_WRITE_ANDX
:
187 case SMB_COM_FIND_CLOSE2
:
188 case SMB_COM_LOCKING_ANDX
:
192 unload_nls(nls_codepage
);
196 /* Allocate and return pointer to an SMB request buffer, and set basic
197 SMB information in the SMB header. If the return code is zero, this
198 function must have filled in request_buf pointer */
200 small_smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
205 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
209 *request_buf
= cifs_small_buf_get();
210 if (*request_buf
== NULL
) {
211 /* BB should we add a retry in here if not a writepage? */
215 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
,
219 cifs_stats_inc(&tcon
->num_smbs_sent
);
225 small_smb_init_no_tc(const int smb_command
, const int wct
,
226 struct cifs_ses
*ses
, void **request_buf
)
229 struct smb_hdr
*buffer
;
231 rc
= small_smb_init(smb_command
, wct
, NULL
, request_buf
);
235 buffer
= (struct smb_hdr
*)*request_buf
;
236 buffer
->Mid
= get_next_mid(ses
->server
);
237 if (ses
->capabilities
& CAP_UNICODE
)
238 buffer
->Flags2
|= SMBFLG2_UNICODE
;
239 if (ses
->capabilities
& CAP_STATUS32
)
240 buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
242 /* uid, tid can stay at zero as set in header assemble */
244 /* BB add support for turning on the signing when
245 this function is used after 1st of session setup requests */
250 /* If the return code is zero, this function must fill in request_buf pointer */
252 __smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
253 void **request_buf
, void **response_buf
)
255 *request_buf
= cifs_buf_get();
256 if (*request_buf
== NULL
) {
257 /* BB should we add a retry in here if not a writepage? */
260 /* Although the original thought was we needed the response buf for */
261 /* potential retries of smb operations it turns out we can determine */
262 /* from the mid flags when the request buffer can be resent without */
263 /* having to use a second distinct buffer for the response */
265 *response_buf
= *request_buf
;
267 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
, tcon
,
271 cifs_stats_inc(&tcon
->num_smbs_sent
);
276 /* If the return code is zero, this function must fill in request_buf pointer */
278 smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
279 void **request_buf
, void **response_buf
)
283 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
287 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
291 smb_init_no_reconnect(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
292 void **request_buf
, void **response_buf
)
294 spin_lock(&tcon
->ses
->chan_lock
);
295 if (cifs_chan_needs_reconnect(tcon
->ses
, tcon
->ses
->server
) ||
296 tcon
->need_reconnect
) {
297 spin_unlock(&tcon
->ses
->chan_lock
);
300 spin_unlock(&tcon
->ses
->chan_lock
);
302 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
305 static int validate_t2(struct smb_t2_rsp
*pSMB
)
307 unsigned int total_size
;
309 /* check for plausible wct */
310 if (pSMB
->hdr
.WordCount
< 10)
313 /* check for parm and data offset going beyond end of smb */
314 if (get_unaligned_le16(&pSMB
->t2_rsp
.ParameterOffset
) > 1024 ||
315 get_unaligned_le16(&pSMB
->t2_rsp
.DataOffset
) > 1024)
318 total_size
= get_unaligned_le16(&pSMB
->t2_rsp
.ParameterCount
);
319 if (total_size
>= 512)
322 /* check that bcc is at least as big as parms + data, and that it is
323 * less than negotiated smb buffer
325 total_size
+= get_unaligned_le16(&pSMB
->t2_rsp
.DataCount
);
326 if (total_size
> get_bcc(&pSMB
->hdr
) ||
327 total_size
>= CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
)
332 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB
,
333 sizeof(struct smb_t2_rsp
) + 16);
338 decode_ext_sec_blob(struct cifs_ses
*ses
, NEGOTIATE_RSP
*pSMBr
)
342 char *guid
= pSMBr
->u
.extended_response
.GUID
;
343 struct TCP_Server_Info
*server
= ses
->server
;
345 count
= get_bcc(&pSMBr
->hdr
);
346 if (count
< SMB1_CLIENT_GUID_SIZE
)
349 spin_lock(&cifs_tcp_ses_lock
);
350 if (server
->srv_count
> 1) {
351 spin_unlock(&cifs_tcp_ses_lock
);
352 if (memcmp(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
) != 0) {
353 cifs_dbg(FYI
, "server UID changed\n");
354 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
357 spin_unlock(&cifs_tcp_ses_lock
);
358 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
361 if (count
== SMB1_CLIENT_GUID_SIZE
) {
362 server
->sec_ntlmssp
= true;
364 count
-= SMB1_CLIENT_GUID_SIZE
;
365 rc
= decode_negTokenInit(
366 pSMBr
->u
.extended_response
.SecurityBlob
, count
, server
);
375 should_set_ext_sec_flag(enum securityEnum sectype
)
382 if (global_secflags
&
383 (CIFSSEC_MAY_KRB5
| CIFSSEC_MAY_NTLMSSP
))
392 CIFSSMBNegotiate(const unsigned int xid
,
393 struct cifs_ses
*ses
,
394 struct TCP_Server_Info
*server
)
397 NEGOTIATE_RSP
*pSMBr
;
404 WARN(1, "%s: server is NULL!\n", __func__
);
408 rc
= smb_init(SMB_COM_NEGOTIATE
, 0, NULL
/* no tcon yet */ ,
409 (void **) &pSMB
, (void **) &pSMBr
);
413 pSMB
->hdr
.Mid
= get_next_mid(server
);
414 pSMB
->hdr
.Flags2
|= (SMBFLG2_UNICODE
| SMBFLG2_ERR_STATUS
);
416 if (should_set_ext_sec_flag(ses
->sectype
)) {
417 cifs_dbg(FYI
, "Requesting extended security\n");
418 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
423 * We know that all the name entries in the protocols array
424 * are short (< 16 bytes anyway) and are NUL terminated.
426 for (i
= 0; i
< CIFS_NUM_PROT
; i
++) {
427 size_t len
= strlen(protocols
[i
].name
) + 1;
429 memcpy(&pSMB
->DialectsArray
[count
], protocols
[i
].name
, len
);
432 inc_rfc1001_len(pSMB
, count
);
433 pSMB
->ByteCount
= cpu_to_le16(count
);
435 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
436 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
440 server
->dialect
= le16_to_cpu(pSMBr
->DialectIndex
);
441 cifs_dbg(FYI
, "Dialect: %d\n", server
->dialect
);
442 /* Check wct = 1 error case */
443 if ((pSMBr
->hdr
.WordCount
<= 13) || (server
->dialect
== BAD_PROT
)) {
444 /* core returns wct = 1, but we do not ask for core - otherwise
445 small wct just comes when dialect index is -1 indicating we
446 could not negotiate a common dialect */
449 } else if (pSMBr
->hdr
.WordCount
!= 17) {
454 /* else wct == 17, NTLM or better */
456 server
->sec_mode
= pSMBr
->SecurityMode
;
457 if ((server
->sec_mode
& SECMODE_USER
) == 0)
458 cifs_dbg(FYI
, "share mode security\n");
460 /* one byte, so no need to convert this or EncryptionKeyLen from
462 server
->maxReq
= min_t(unsigned int, le16_to_cpu(pSMBr
->MaxMpxCount
),
464 set_credits(server
, server
->maxReq
);
465 /* probably no need to store and check maxvcs */
466 server
->maxBuf
= le32_to_cpu(pSMBr
->MaxBufferSize
);
467 /* set up max_read for readahead check */
468 server
->max_read
= server
->maxBuf
;
469 server
->max_rw
= le32_to_cpu(pSMBr
->MaxRawSize
);
470 cifs_dbg(NOISY
, "Max buf = %d\n", ses
->server
->maxBuf
);
471 server
->capabilities
= le32_to_cpu(pSMBr
->Capabilities
);
472 server
->timeAdj
= (int)(__s16
)le16_to_cpu(pSMBr
->ServerTimeZone
);
473 server
->timeAdj
*= 60;
475 if (pSMBr
->EncryptionKeyLength
== CIFS_CRYPTO_KEY_SIZE
) {
476 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
477 memcpy(ses
->server
->cryptkey
, pSMBr
->u
.EncryptionKey
,
478 CIFS_CRYPTO_KEY_SIZE
);
479 } else if (pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
||
480 server
->capabilities
& CAP_EXTENDED_SECURITY
) {
481 server
->negflavor
= CIFS_NEGFLAVOR_EXTENDED
;
482 rc
= decode_ext_sec_blob(ses
, pSMBr
);
483 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
484 rc
= -EIO
; /* no crypt key only if plain text pwd */
486 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
487 server
->capabilities
&= ~CAP_EXTENDED_SECURITY
;
491 rc
= cifs_enable_signing(server
, ses
->sign
);
493 cifs_buf_release(pSMB
);
495 cifs_dbg(FYI
, "negprot rc %d\n", rc
);
500 CIFSSMBTDis(const unsigned int xid
, struct cifs_tcon
*tcon
)
502 struct smb_hdr
*smb_buffer
;
505 cifs_dbg(FYI
, "In tree disconnect\n");
507 /* BB: do we need to check this? These should never be NULL. */
508 if ((tcon
->ses
== NULL
) || (tcon
->ses
->server
== NULL
))
512 * No need to return error on this operation if tid invalidated and
513 * closed on server already e.g. due to tcp session crashing. Also,
514 * the tcon is no longer on the list, so no need to take lock before
517 spin_lock(&tcon
->ses
->chan_lock
);
518 if ((tcon
->need_reconnect
) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon
->ses
)) {
519 spin_unlock(&tcon
->ses
->chan_lock
);
522 spin_unlock(&tcon
->ses
->chan_lock
);
524 rc
= small_smb_init(SMB_COM_TREE_DISCONNECT
, 0, tcon
,
525 (void **)&smb_buffer
);
529 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)smb_buffer
, 0);
530 cifs_small_buf_release(smb_buffer
);
532 cifs_dbg(FYI
, "Tree disconnect failed %d\n", rc
);
534 /* No need to return error on this operation if tid invalidated and
535 closed on server already e.g. due to tcp session crashing */
543 * This is a no-op for now. We're not really interested in the reply, but
544 * rather in the fact that the server sent one and that server->lstrp
547 * FIXME: maybe we should consider checking that the reply matches request?
550 cifs_echo_callback(struct mid_q_entry
*mid
)
552 struct TCP_Server_Info
*server
= mid
->callback_data
;
553 struct cifs_credits credits
= { .value
= 1, .instance
= 0 };
556 add_credits(server
, &credits
, CIFS_ECHO_OP
);
560 CIFSSMBEcho(struct TCP_Server_Info
*server
)
565 struct smb_rqst rqst
= { .rq_iov
= iov
,
568 cifs_dbg(FYI
, "In echo request\n");
570 rc
= small_smb_init(SMB_COM_ECHO
, 0, NULL
, (void **)&smb
);
574 if (server
->capabilities
& CAP_UNICODE
)
575 smb
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
577 /* set up echo request */
578 smb
->hdr
.Tid
= 0xffff;
579 smb
->hdr
.WordCount
= 1;
580 put_unaligned_le16(1, &smb
->EchoCount
);
581 put_bcc(1, &smb
->hdr
);
583 inc_rfc1001_len(smb
, 3);
586 iov
[0].iov_base
= smb
;
587 iov
[1].iov_len
= get_rfc1002_length(smb
);
588 iov
[1].iov_base
= (char *)smb
+ 4;
590 rc
= cifs_call_async(server
, &rqst
, NULL
, cifs_echo_callback
, NULL
,
591 server
, CIFS_NON_BLOCKING
| CIFS_ECHO_OP
, NULL
);
593 cifs_dbg(FYI
, "Echo request failed: %d\n", rc
);
595 cifs_small_buf_release(smb
);
601 CIFSSMBLogoff(const unsigned int xid
, struct cifs_ses
*ses
)
603 LOGOFF_ANDX_REQ
*pSMB
;
606 cifs_dbg(FYI
, "In SMBLogoff for session disconnect\n");
609 * BB: do we need to check validity of ses and server? They should
610 * always be valid since we have an active reference. If not, that
611 * should probably be a BUG()
613 if (!ses
|| !ses
->server
)
616 mutex_lock(&ses
->session_mutex
);
617 spin_lock(&ses
->chan_lock
);
618 if (CIFS_ALL_CHANS_NEED_RECONNECT(ses
)) {
619 spin_unlock(&ses
->chan_lock
);
620 goto session_already_dead
; /* no need to send SMBlogoff if uid
621 already closed due to reconnect */
623 spin_unlock(&ses
->chan_lock
);
625 rc
= small_smb_init(SMB_COM_LOGOFF_ANDX
, 2, NULL
, (void **)&pSMB
);
627 mutex_unlock(&ses
->session_mutex
);
631 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
633 if (ses
->server
->sign
)
634 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
636 pSMB
->hdr
.Uid
= ses
->Suid
;
638 pSMB
->AndXCommand
= 0xFF;
639 rc
= SendReceiveNoRsp(xid
, ses
, (char *) pSMB
, 0);
640 cifs_small_buf_release(pSMB
);
641 session_already_dead
:
642 mutex_unlock(&ses
->session_mutex
);
644 /* if session dead then we do not need to do ulogoff,
645 since server closed smb session, no sense reporting
653 CIFSPOSIXDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
,
654 const char *fileName
, __u16 type
,
655 const struct nls_table
*nls_codepage
, int remap
)
657 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
658 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
659 struct unlink_psx_rq
*pRqD
;
662 int bytes_returned
= 0;
663 __u16 params
, param_offset
, offset
, byte_count
;
665 cifs_dbg(FYI
, "In POSIX delete\n");
667 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
672 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
674 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
675 PATH_MAX
, nls_codepage
, remap
);
676 name_len
++; /* trailing null */
679 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
682 params
= 6 + name_len
;
683 pSMB
->MaxParameterCount
= cpu_to_le16(2);
684 pSMB
->MaxDataCount
= 0; /* BB double check this with jra */
685 pSMB
->MaxSetupCount
= 0;
690 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
691 InformationLevel
) - 4;
692 offset
= param_offset
+ params
;
694 /* Setup pointer to Request Data (inode type).
695 * Note that SMB offsets are from the beginning of SMB which is 4 bytes
696 * in, after RFC1001 field
698 pRqD
= (struct unlink_psx_rq
*)((char *)(pSMB
) + offset
+ 4);
699 pRqD
->type
= cpu_to_le16(type
);
700 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
701 pSMB
->DataOffset
= cpu_to_le16(offset
);
702 pSMB
->SetupCount
= 1;
704 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
705 byte_count
= 3 /* pad */ + params
+ sizeof(struct unlink_psx_rq
);
707 pSMB
->DataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
708 pSMB
->TotalDataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
709 pSMB
->ParameterCount
= cpu_to_le16(params
);
710 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
711 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_UNLINK
);
713 inc_rfc1001_len(pSMB
, byte_count
);
714 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
715 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
716 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
718 cifs_dbg(FYI
, "Posix delete returned %d\n", rc
);
719 cifs_buf_release(pSMB
);
721 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
730 CIFSSMBDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
731 struct cifs_sb_info
*cifs_sb
)
733 DELETE_FILE_REQ
*pSMB
= NULL
;
734 DELETE_FILE_RSP
*pSMBr
= NULL
;
738 int remap
= cifs_remap(cifs_sb
);
741 rc
= smb_init(SMB_COM_DELETE
, 1, tcon
, (void **) &pSMB
,
746 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
747 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->fileName
, name
,
748 PATH_MAX
, cifs_sb
->local_nls
,
750 name_len
++; /* trailing null */
753 name_len
= copy_path_name(pSMB
->fileName
, name
);
755 pSMB
->SearchAttributes
=
756 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
);
757 pSMB
->BufferFormat
= 0x04;
758 inc_rfc1001_len(pSMB
, name_len
+ 1);
759 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
760 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
761 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
762 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
764 cifs_dbg(FYI
, "Error in RMFile = %d\n", rc
);
766 cifs_buf_release(pSMB
);
774 CIFSSMBRmDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
775 struct cifs_sb_info
*cifs_sb
)
777 DELETE_DIRECTORY_REQ
*pSMB
= NULL
;
778 DELETE_DIRECTORY_RSP
*pSMBr
= NULL
;
782 int remap
= cifs_remap(cifs_sb
);
784 cifs_dbg(FYI
, "In CIFSSMBRmDir\n");
786 rc
= smb_init(SMB_COM_DELETE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
791 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
792 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
793 PATH_MAX
, cifs_sb
->local_nls
,
795 name_len
++; /* trailing null */
798 name_len
= copy_path_name(pSMB
->DirName
, name
);
801 pSMB
->BufferFormat
= 0x04;
802 inc_rfc1001_len(pSMB
, name_len
+ 1);
803 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
804 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
805 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
806 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_rmdirs
);
808 cifs_dbg(FYI
, "Error in RMDir = %d\n", rc
);
810 cifs_buf_release(pSMB
);
817 CIFSSMBMkDir(const unsigned int xid
, struct inode
*inode
, umode_t mode
,
818 struct cifs_tcon
*tcon
, const char *name
,
819 struct cifs_sb_info
*cifs_sb
)
822 CREATE_DIRECTORY_REQ
*pSMB
= NULL
;
823 CREATE_DIRECTORY_RSP
*pSMBr
= NULL
;
826 int remap
= cifs_remap(cifs_sb
);
828 cifs_dbg(FYI
, "In CIFSSMBMkDir\n");
830 rc
= smb_init(SMB_COM_CREATE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
835 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
836 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
837 PATH_MAX
, cifs_sb
->local_nls
,
839 name_len
++; /* trailing null */
842 name_len
= copy_path_name(pSMB
->DirName
, name
);
845 pSMB
->BufferFormat
= 0x04;
846 inc_rfc1001_len(pSMB
, name_len
+ 1);
847 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
848 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
849 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
850 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_mkdirs
);
852 cifs_dbg(FYI
, "Error in Mkdir = %d\n", rc
);
854 cifs_buf_release(pSMB
);
861 CIFSPOSIXCreate(const unsigned int xid
, struct cifs_tcon
*tcon
,
862 __u32 posix_flags
, __u64 mode
, __u16
*netfid
,
863 FILE_UNIX_BASIC_INFO
*pRetData
, __u32
*pOplock
,
864 const char *name
, const struct nls_table
*nls_codepage
,
867 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
868 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
871 int bytes_returned
= 0;
872 __u16 params
, param_offset
, offset
, byte_count
, count
;
874 OPEN_PSX_RSP
*psx_rsp
;
876 cifs_dbg(FYI
, "In POSIX Create\n");
878 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
883 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
885 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, name
,
886 PATH_MAX
, nls_codepage
, remap
);
887 name_len
++; /* trailing null */
890 name_len
= copy_path_name(pSMB
->FileName
, name
);
893 params
= 6 + name_len
;
894 count
= sizeof(OPEN_PSX_REQ
);
895 pSMB
->MaxParameterCount
= cpu_to_le16(2);
896 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* large enough */
897 pSMB
->MaxSetupCount
= 0;
902 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
903 InformationLevel
) - 4;
904 offset
= param_offset
+ params
;
905 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
906 pdata
= (OPEN_PSX_REQ
*)((char *)(pSMB
) + offset
+ 4);
907 pdata
->Level
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
908 pdata
->Permissions
= cpu_to_le64(mode
);
909 pdata
->PosixOpenFlags
= cpu_to_le32(posix_flags
);
910 pdata
->OpenFlags
= cpu_to_le32(*pOplock
);
911 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
912 pSMB
->DataOffset
= cpu_to_le16(offset
);
913 pSMB
->SetupCount
= 1;
915 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
916 byte_count
= 3 /* pad */ + params
+ count
;
918 pSMB
->DataCount
= cpu_to_le16(count
);
919 pSMB
->ParameterCount
= cpu_to_le16(params
);
920 pSMB
->TotalDataCount
= pSMB
->DataCount
;
921 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
922 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_OPEN
);
924 inc_rfc1001_len(pSMB
, byte_count
);
925 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
926 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
927 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
929 cifs_dbg(FYI
, "Posix create returned %d\n", rc
);
933 cifs_dbg(FYI
, "copying inode info\n");
934 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
936 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)) {
937 rc
= -EIO
; /* bad smb */
941 /* copy return information to pRetData */
942 psx_rsp
= (OPEN_PSX_RSP
*)((char *) &pSMBr
->hdr
.Protocol
943 + le16_to_cpu(pSMBr
->t2
.DataOffset
));
945 *pOplock
= le16_to_cpu(psx_rsp
->OplockFlags
);
947 *netfid
= psx_rsp
->Fid
; /* cifs fid stays in le */
948 /* Let caller know file was created so we can set the mode. */
949 /* Do we care about the CreateAction in any other cases? */
950 if (cpu_to_le32(FILE_CREATE
) == psx_rsp
->CreateAction
)
951 *pOplock
|= CIFS_CREATE_ACTION
;
952 /* check to make sure response data is there */
953 if (psx_rsp
->ReturnedLevel
!= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
)) {
954 pRetData
->Type
= cpu_to_le32(-1); /* unknown */
955 cifs_dbg(NOISY
, "unknown type\n");
957 if (get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)
958 + sizeof(FILE_UNIX_BASIC_INFO
)) {
959 cifs_dbg(VFS
, "Open response data too small\n");
960 pRetData
->Type
= cpu_to_le32(-1);
963 memcpy((char *) pRetData
,
964 (char *)psx_rsp
+ sizeof(OPEN_PSX_RSP
),
965 sizeof(FILE_UNIX_BASIC_INFO
));
969 cifs_buf_release(pSMB
);
971 if (posix_flags
& SMB_O_DIRECTORY
)
972 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixmkdirs
);
974 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixopens
);
982 static __u16
convert_disposition(int disposition
)
986 switch (disposition
) {
988 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
991 ofun
= SMBOPEN_OAPPEND
;
994 ofun
= SMBOPEN_OCREATE
;
997 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OAPPEND
;
1000 ofun
= SMBOPEN_OTRUNC
;
1002 case FILE_OVERWRITE_IF
:
1003 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1006 cifs_dbg(FYI
, "unknown disposition %d\n", disposition
);
1007 ofun
= SMBOPEN_OAPPEND
; /* regular open */
1013 access_flags_to_smbopen_mode(const int access_flags
)
1015 int masked_flags
= access_flags
& (GENERIC_READ
| GENERIC_WRITE
);
1017 if (masked_flags
== GENERIC_READ
)
1018 return SMBOPEN_READ
;
1019 else if (masked_flags
== GENERIC_WRITE
)
1020 return SMBOPEN_WRITE
;
1022 /* just go for read/write */
1023 return SMBOPEN_READWRITE
;
1027 SMBLegacyOpen(const unsigned int xid
, struct cifs_tcon
*tcon
,
1028 const char *fileName
, const int openDisposition
,
1029 const int access_flags
, const int create_options
, __u16
*netfid
,
1030 int *pOplock
, FILE_ALL_INFO
*pfile_info
,
1031 const struct nls_table
*nls_codepage
, int remap
)
1034 OPENX_REQ
*pSMB
= NULL
;
1035 OPENX_RSP
*pSMBr
= NULL
;
1041 rc
= smb_init(SMB_COM_OPEN_ANDX
, 15, tcon
, (void **) &pSMB
,
1046 pSMB
->AndXCommand
= 0xFF; /* none */
1048 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1049 count
= 1; /* account for one byte pad to word boundary */
1051 cifsConvertToUTF16((__le16
*) (pSMB
->fileName
+ 1),
1052 fileName
, PATH_MAX
, nls_codepage
, remap
);
1053 name_len
++; /* trailing null */
1056 count
= 0; /* no pad */
1057 name_len
= copy_path_name(pSMB
->fileName
, fileName
);
1059 if (*pOplock
& REQ_OPLOCK
)
1060 pSMB
->OpenFlags
= cpu_to_le16(REQ_OPLOCK
);
1061 else if (*pOplock
& REQ_BATCHOPLOCK
)
1062 pSMB
->OpenFlags
= cpu_to_le16(REQ_BATCHOPLOCK
);
1064 pSMB
->OpenFlags
|= cpu_to_le16(REQ_MORE_INFO
);
1065 pSMB
->Mode
= cpu_to_le16(access_flags_to_smbopen_mode(access_flags
));
1066 pSMB
->Mode
|= cpu_to_le16(0x40); /* deny none */
1067 /* set file as system file if special file such
1068 as fifo and server expecting SFU style and
1069 no Unix extensions */
1071 if (create_options
& CREATE_OPTION_SPECIAL
)
1072 pSMB
->FileAttributes
= cpu_to_le16(ATTR_SYSTEM
);
1073 else /* BB FIXME BB */
1074 pSMB
->FileAttributes
= cpu_to_le16(0/*ATTR_NORMAL*/);
1076 if (create_options
& CREATE_OPTION_READONLY
)
1077 pSMB
->FileAttributes
|= cpu_to_le16(ATTR_READONLY
);
1080 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1081 CREATE_OPTIONS_MASK); */
1082 /* BB FIXME END BB */
1084 pSMB
->Sattr
= cpu_to_le16(ATTR_HIDDEN
| ATTR_SYSTEM
| ATTR_DIRECTORY
);
1085 pSMB
->OpenFunction
= cpu_to_le16(convert_disposition(openDisposition
));
1087 inc_rfc1001_len(pSMB
, count
);
1089 pSMB
->ByteCount
= cpu_to_le16(count
);
1090 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1091 (struct smb_hdr
*)pSMBr
, &bytes_returned
, 0);
1092 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1094 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1096 /* BB verify if wct == 15 */
1098 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1100 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
1101 /* Let caller know file was created so we can set the mode. */
1102 /* Do we care about the CreateAction in any other cases? */
1104 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1105 *pOplock |= CIFS_CREATE_ACTION; */
1109 pfile_info
->CreationTime
= 0; /* BB convert CreateTime*/
1110 pfile_info
->LastAccessTime
= 0; /* BB fixme */
1111 pfile_info
->LastWriteTime
= 0; /* BB fixme */
1112 pfile_info
->ChangeTime
= 0; /* BB fixme */
1113 pfile_info
->Attributes
=
1114 cpu_to_le32(le16_to_cpu(pSMBr
->FileAttributes
));
1115 /* the file_info buf is endian converted by caller */
1116 pfile_info
->AllocationSize
=
1117 cpu_to_le64(le32_to_cpu(pSMBr
->EndOfFile
));
1118 pfile_info
->EndOfFile
= pfile_info
->AllocationSize
;
1119 pfile_info
->NumberOfLinks
= cpu_to_le32(1);
1120 pfile_info
->DeletePending
= 0;
1124 cifs_buf_release(pSMB
);
1131 CIFS_open(const unsigned int xid
, struct cifs_open_parms
*oparms
, int *oplock
,
1135 OPEN_REQ
*req
= NULL
;
1136 OPEN_RSP
*rsp
= NULL
;
1140 struct cifs_sb_info
*cifs_sb
= oparms
->cifs_sb
;
1141 struct cifs_tcon
*tcon
= oparms
->tcon
;
1142 int remap
= cifs_remap(cifs_sb
);
1143 const struct nls_table
*nls
= cifs_sb
->local_nls
;
1144 int create_options
= oparms
->create_options
;
1145 int desired_access
= oparms
->desired_access
;
1146 int disposition
= oparms
->disposition
;
1147 const char *path
= oparms
->path
;
1150 rc
= smb_init(SMB_COM_NT_CREATE_ANDX
, 24, tcon
, (void **)&req
,
1155 /* no commands go after this */
1156 req
->AndXCommand
= 0xFF;
1158 if (req
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1159 /* account for one byte pad to word boundary */
1161 name_len
= cifsConvertToUTF16((__le16
*)(req
->fileName
+ 1),
1162 path
, PATH_MAX
, nls
, remap
);
1166 req
->NameLength
= cpu_to_le16(name_len
);
1168 /* BB improve check for buffer overruns BB */
1171 name_len
= copy_path_name(req
->fileName
, path
);
1172 req
->NameLength
= cpu_to_le16(name_len
);
1175 if (*oplock
& REQ_OPLOCK
)
1176 req
->OpenFlags
= cpu_to_le32(REQ_OPLOCK
);
1177 else if (*oplock
& REQ_BATCHOPLOCK
)
1178 req
->OpenFlags
= cpu_to_le32(REQ_BATCHOPLOCK
);
1180 req
->DesiredAccess
= cpu_to_le32(desired_access
);
1181 req
->AllocationSize
= 0;
1184 * Set file as system file if special file such as fifo and server
1185 * expecting SFU style and no Unix extensions.
1187 if (create_options
& CREATE_OPTION_SPECIAL
)
1188 req
->FileAttributes
= cpu_to_le32(ATTR_SYSTEM
);
1190 req
->FileAttributes
= cpu_to_le32(ATTR_NORMAL
);
1193 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1194 * sensitive checks for other servers such as Samba.
1196 if (tcon
->ses
->capabilities
& CAP_UNIX
)
1197 req
->FileAttributes
|= cpu_to_le32(ATTR_POSIX_SEMANTICS
);
1199 if (create_options
& CREATE_OPTION_READONLY
)
1200 req
->FileAttributes
|= cpu_to_le32(ATTR_READONLY
);
1202 req
->ShareAccess
= cpu_to_le32(FILE_SHARE_ALL
);
1203 req
->CreateDisposition
= cpu_to_le32(disposition
);
1204 req
->CreateOptions
= cpu_to_le32(create_options
& CREATE_OPTIONS_MASK
);
1206 /* BB Expirement with various impersonation levels and verify */
1207 req
->ImpersonationLevel
= cpu_to_le32(SECURITY_IMPERSONATION
);
1208 req
->SecurityFlags
= SECURITY_CONTEXT_TRACKING
|SECURITY_EFFECTIVE_ONLY
;
1211 inc_rfc1001_len(req
, count
);
1213 req
->ByteCount
= cpu_to_le16(count
);
1214 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*)req
,
1215 (struct smb_hdr
*)rsp
, &bytes_returned
, 0);
1216 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1218 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1219 cifs_buf_release(req
);
1225 /* 1 byte no need to le_to_cpu */
1226 *oplock
= rsp
->OplockLevel
;
1227 /* cifs fid stays in le */
1228 oparms
->fid
->netfid
= rsp
->Fid
;
1229 oparms
->fid
->access
= desired_access
;
1231 /* Let caller know file was created so we can set the mode. */
1232 /* Do we care about the CreateAction in any other cases? */
1233 if (cpu_to_le32(FILE_CREATE
) == rsp
->CreateAction
)
1234 *oplock
|= CIFS_CREATE_ACTION
;
1237 /* copy from CreationTime to Attributes */
1238 memcpy((char *)buf
, (char *)&rsp
->CreationTime
, 36);
1239 /* the file_info buf is endian converted by caller */
1240 buf
->AllocationSize
= rsp
->AllocationSize
;
1241 buf
->EndOfFile
= rsp
->EndOfFile
;
1242 buf
->NumberOfLinks
= cpu_to_le32(1);
1243 buf
->DeletePending
= 0;
1246 cifs_buf_release(req
);
1251 cifs_readv_callback(struct mid_q_entry
*mid
)
1253 struct cifs_readdata
*rdata
= mid
->callback_data
;
1254 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1255 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
1256 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1258 .rq_pages
= rdata
->pages
,
1259 .rq_offset
= rdata
->page_offset
,
1260 .rq_npages
= rdata
->nr_pages
,
1261 .rq_pagesz
= rdata
->pagesz
,
1262 .rq_tailsz
= rdata
->tailsz
};
1263 struct cifs_credits credits
= { .value
= 1, .instance
= 0 };
1265 cifs_dbg(FYI
, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1266 __func__
, mid
->mid
, mid
->mid_state
, rdata
->result
,
1269 switch (mid
->mid_state
) {
1270 case MID_RESPONSE_RECEIVED
:
1271 /* result already set, check signature */
1275 rc
= cifs_verify_signature(&rqst
, server
,
1276 mid
->sequence_number
);
1278 cifs_dbg(VFS
, "SMB signature verification returned error = %d\n",
1281 /* FIXME: should this be counted toward the initiating task? */
1282 task_io_account_read(rdata
->got_bytes
);
1283 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1285 case MID_REQUEST_SUBMITTED
:
1286 case MID_RETRY_NEEDED
:
1287 rdata
->result
= -EAGAIN
;
1288 if (server
->sign
&& rdata
->got_bytes
)
1289 /* reset bytes number since we can not check a sign */
1290 rdata
->got_bytes
= 0;
1291 /* FIXME: should this be counted toward the initiating task? */
1292 task_io_account_read(rdata
->got_bytes
);
1293 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1296 rdata
->result
= -EIO
;
1299 queue_work(cifsiod_wq
, &rdata
->work
);
1301 add_credits(server
, &credits
, 0);
1304 /* cifs_async_readv - send an async write, and set up mid to handle result */
1306 cifs_async_readv(struct cifs_readdata
*rdata
)
1309 READ_REQ
*smb
= NULL
;
1311 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1312 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1315 cifs_dbg(FYI
, "%s: offset=%llu bytes=%u\n",
1316 __func__
, rdata
->offset
, rdata
->bytes
);
1318 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1321 wct
= 10; /* old style read */
1322 if ((rdata
->offset
>> 32) > 0) {
1323 /* can not handle this big offset for old */
1328 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **)&smb
);
1332 smb
->hdr
.Pid
= cpu_to_le16((__u16
)rdata
->pid
);
1333 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(rdata
->pid
>> 16));
1335 smb
->AndXCommand
= 0xFF; /* none */
1336 smb
->Fid
= rdata
->cfile
->fid
.netfid
;
1337 smb
->OffsetLow
= cpu_to_le32(rdata
->offset
& 0xFFFFFFFF);
1339 smb
->OffsetHigh
= cpu_to_le32(rdata
->offset
>> 32);
1341 smb
->MaxCount
= cpu_to_le16(rdata
->bytes
& 0xFFFF);
1342 smb
->MaxCountHigh
= cpu_to_le32(rdata
->bytes
>> 16);
1346 /* old style read */
1347 struct smb_com_readx_req
*smbr
=
1348 (struct smb_com_readx_req
*)smb
;
1349 smbr
->ByteCount
= 0;
1352 /* 4 for RFC1001 length + 1 for BCC */
1353 rdata
->iov
[0].iov_base
= smb
;
1354 rdata
->iov
[0].iov_len
= 4;
1355 rdata
->iov
[1].iov_base
= (char *)smb
+ 4;
1356 rdata
->iov
[1].iov_len
= get_rfc1002_length(smb
);
1358 kref_get(&rdata
->refcount
);
1359 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, cifs_readv_receive
,
1360 cifs_readv_callback
, NULL
, rdata
, 0, NULL
);
1363 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1365 kref_put(&rdata
->refcount
, cifs_readdata_release
);
1367 cifs_small_buf_release(smb
);
1372 CIFSSMBRead(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1373 unsigned int *nbytes
, char **buf
, int *pbuf_type
)
1376 READ_REQ
*pSMB
= NULL
;
1377 READ_RSP
*pSMBr
= NULL
;
1378 char *pReadData
= NULL
;
1380 int resp_buf_type
= 0;
1382 struct kvec rsp_iov
;
1383 __u32 pid
= io_parms
->pid
;
1384 __u16 netfid
= io_parms
->netfid
;
1385 __u64 offset
= io_parms
->offset
;
1386 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1387 unsigned int count
= io_parms
->length
;
1389 cifs_dbg(FYI
, "Reading %d bytes on fid %d\n", count
, netfid
);
1390 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1393 wct
= 10; /* old style read */
1394 if ((offset
>> 32) > 0) {
1395 /* can not handle this big offset for old */
1401 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **) &pSMB
);
1405 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1406 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1408 /* tcon and ses pointer are checked in smb_init */
1409 if (tcon
->ses
->server
== NULL
)
1410 return -ECONNABORTED
;
1412 pSMB
->AndXCommand
= 0xFF; /* none */
1414 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1416 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1418 pSMB
->Remaining
= 0;
1419 pSMB
->MaxCount
= cpu_to_le16(count
& 0xFFFF);
1420 pSMB
->MaxCountHigh
= cpu_to_le32(count
>> 16);
1422 pSMB
->ByteCount
= 0; /* no need to do le conversion since 0 */
1424 /* old style read */
1425 struct smb_com_readx_req
*pSMBW
=
1426 (struct smb_com_readx_req
*)pSMB
;
1427 pSMBW
->ByteCount
= 0;
1430 iov
[0].iov_base
= (char *)pSMB
;
1431 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
1432 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1, &resp_buf_type
,
1433 CIFS_LOG_ERROR
, &rsp_iov
);
1434 cifs_small_buf_release(pSMB
);
1435 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1436 pSMBr
= (READ_RSP
*)rsp_iov
.iov_base
;
1438 cifs_dbg(VFS
, "Send error in read = %d\n", rc
);
1440 int data_length
= le16_to_cpu(pSMBr
->DataLengthHigh
);
1441 data_length
= data_length
<< 16;
1442 data_length
+= le16_to_cpu(pSMBr
->DataLength
);
1443 *nbytes
= data_length
;
1445 /*check that DataLength would not go beyond end of SMB */
1446 if ((data_length
> CIFSMaxBufSize
)
1447 || (data_length
> count
)) {
1448 cifs_dbg(FYI
, "bad length %d for count %d\n",
1449 data_length
, count
);
1453 pReadData
= (char *) (&pSMBr
->hdr
.Protocol
) +
1454 le16_to_cpu(pSMBr
->DataOffset
);
1455 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1456 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1458 }*/ /* can not use copy_to_user when using page cache*/
1460 memcpy(*buf
, pReadData
, data_length
);
1465 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
1466 } else if (resp_buf_type
!= CIFS_NO_BUFFER
) {
1467 /* return buffer to caller to free */
1468 *buf
= rsp_iov
.iov_base
;
1469 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1470 *pbuf_type
= CIFS_SMALL_BUFFER
;
1471 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1472 *pbuf_type
= CIFS_LARGE_BUFFER
;
1473 } /* else no valid buffer on return - leave as null */
1475 /* Note: On -EAGAIN error only caller can retry on handle based calls
1476 since file handle passed in no longer valid */
1482 CIFSSMBWrite(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1483 unsigned int *nbytes
, const char *buf
)
1486 WRITE_REQ
*pSMB
= NULL
;
1487 WRITE_RSP
*pSMBr
= NULL
;
1488 int bytes_returned
, wct
;
1491 __u32 pid
= io_parms
->pid
;
1492 __u16 netfid
= io_parms
->netfid
;
1493 __u64 offset
= io_parms
->offset
;
1494 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1495 unsigned int count
= io_parms
->length
;
1499 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1500 if (tcon
->ses
== NULL
)
1501 return -ECONNABORTED
;
1503 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1507 if ((offset
>> 32) > 0) {
1508 /* can not handle big offset for old srv */
1513 rc
= smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
,
1518 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1519 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1521 /* tcon and ses pointer are checked in smb_init */
1522 if (tcon
->ses
->server
== NULL
)
1523 return -ECONNABORTED
;
1525 pSMB
->AndXCommand
= 0xFF; /* none */
1527 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1529 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1531 pSMB
->Reserved
= 0xFFFFFFFF;
1532 pSMB
->WriteMode
= 0;
1533 pSMB
->Remaining
= 0;
1535 /* Can increase buffer size if buffer is big enough in some cases ie we
1536 can send more if LARGE_WRITE_X capability returned by the server and if
1537 our buffer is big enough or if we convert to iovecs on socket writes
1538 and eliminate the copy to the CIFS buffer */
1539 if (tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
) {
1540 bytes_sent
= min_t(const unsigned int, CIFSMaxBufSize
, count
);
1542 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
)
1546 if (bytes_sent
> count
)
1549 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1551 memcpy(pSMB
->Data
, buf
, bytes_sent
);
1552 else if (count
!= 0) {
1554 cifs_buf_release(pSMB
);
1556 } /* else setting file size with write of zero bytes */
1558 byte_count
= bytes_sent
+ 1; /* pad */
1559 else /* wct == 12 */
1560 byte_count
= bytes_sent
+ 5; /* bigger pad, smaller smb hdr */
1562 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
& 0xFFFF);
1563 pSMB
->DataLengthHigh
= cpu_to_le16(bytes_sent
>> 16);
1564 inc_rfc1001_len(pSMB
, byte_count
);
1567 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1568 else { /* old style write has byte count 4 bytes earlier
1570 struct smb_com_writex_req
*pSMBW
=
1571 (struct smb_com_writex_req
*)pSMB
;
1572 pSMBW
->ByteCount
= cpu_to_le16(byte_count
);
1575 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1576 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1577 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
1579 cifs_dbg(FYI
, "Send error in write = %d\n", rc
);
1581 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
1582 *nbytes
= (*nbytes
) << 16;
1583 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
1586 * Mask off high 16 bits when bytes written as returned by the
1587 * server is greater than bytes requested by the client. Some
1588 * OS/2 servers are known to set incorrect CountHigh values.
1590 if (*nbytes
> count
)
1594 cifs_buf_release(pSMB
);
1596 /* Note: On -EAGAIN error only caller can retry on handle based calls
1597 since file handle passed in no longer valid */
1603 * Check the mid_state and signature on received buffer (if any), and queue the
1604 * workqueue completion task.
1607 cifs_writev_callback(struct mid_q_entry
*mid
)
1609 struct cifs_writedata
*wdata
= mid
->callback_data
;
1610 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
1611 unsigned int written
;
1612 WRITE_RSP
*smb
= (WRITE_RSP
*)mid
->resp_buf
;
1613 struct cifs_credits credits
= { .value
= 1, .instance
= 0 };
1615 switch (mid
->mid_state
) {
1616 case MID_RESPONSE_RECEIVED
:
1617 wdata
->result
= cifs_check_receive(mid
, tcon
->ses
->server
, 0);
1618 if (wdata
->result
!= 0)
1621 written
= le16_to_cpu(smb
->CountHigh
);
1623 written
+= le16_to_cpu(smb
->Count
);
1625 * Mask off high 16 bits when bytes written as returned
1626 * by the server is greater than bytes requested by the
1627 * client. OS/2 servers are known to set incorrect
1630 if (written
> wdata
->bytes
)
1633 if (written
< wdata
->bytes
)
1634 wdata
->result
= -ENOSPC
;
1636 wdata
->bytes
= written
;
1638 case MID_REQUEST_SUBMITTED
:
1639 case MID_RETRY_NEEDED
:
1640 wdata
->result
= -EAGAIN
;
1643 wdata
->result
= -EIO
;
1647 queue_work(cifsiod_wq
, &wdata
->work
);
1649 add_credits(tcon
->ses
->server
, &credits
, 0);
1652 /* cifs_async_writev - send an async write, and set up mid to handle result */
1654 cifs_async_writev(struct cifs_writedata
*wdata
,
1655 void (*release
)(struct kref
*kref
))
1658 WRITE_REQ
*smb
= NULL
;
1660 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
1662 struct smb_rqst rqst
= { };
1664 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
1668 if (wdata
->offset
>> 32 > 0) {
1669 /* can not handle big offset for old srv */
1674 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **)&smb
);
1676 goto async_writev_out
;
1678 smb
->hdr
.Pid
= cpu_to_le16((__u16
)wdata
->pid
);
1679 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(wdata
->pid
>> 16));
1681 smb
->AndXCommand
= 0xFF; /* none */
1682 smb
->Fid
= wdata
->cfile
->fid
.netfid
;
1683 smb
->OffsetLow
= cpu_to_le32(wdata
->offset
& 0xFFFFFFFF);
1685 smb
->OffsetHigh
= cpu_to_le32(wdata
->offset
>> 32);
1686 smb
->Reserved
= 0xFFFFFFFF;
1691 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1693 /* 4 for RFC1001 length + 1 for BCC */
1695 iov
[0].iov_base
= smb
;
1696 iov
[1].iov_len
= get_rfc1002_length(smb
) + 1;
1697 iov
[1].iov_base
= (char *)smb
+ 4;
1701 rqst
.rq_pages
= wdata
->pages
;
1702 rqst
.rq_offset
= wdata
->page_offset
;
1703 rqst
.rq_npages
= wdata
->nr_pages
;
1704 rqst
.rq_pagesz
= wdata
->pagesz
;
1705 rqst
.rq_tailsz
= wdata
->tailsz
;
1707 cifs_dbg(FYI
, "async write at %llu %u bytes\n",
1708 wdata
->offset
, wdata
->bytes
);
1710 smb
->DataLengthLow
= cpu_to_le16(wdata
->bytes
& 0xFFFF);
1711 smb
->DataLengthHigh
= cpu_to_le16(wdata
->bytes
>> 16);
1714 inc_rfc1001_len(&smb
->hdr
, wdata
->bytes
+ 1);
1715 put_bcc(wdata
->bytes
+ 1, &smb
->hdr
);
1718 struct smb_com_writex_req
*smbw
=
1719 (struct smb_com_writex_req
*)smb
;
1720 inc_rfc1001_len(&smbw
->hdr
, wdata
->bytes
+ 5);
1721 put_bcc(wdata
->bytes
+ 5, &smbw
->hdr
);
1722 iov
[1].iov_len
+= 4; /* pad bigger by four bytes */
1725 kref_get(&wdata
->refcount
);
1726 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, NULL
,
1727 cifs_writev_callback
, NULL
, wdata
, 0, NULL
);
1730 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
1732 kref_put(&wdata
->refcount
, release
);
1735 cifs_small_buf_release(smb
);
1740 CIFSSMBWrite2(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1741 unsigned int *nbytes
, struct kvec
*iov
, int n_vec
)
1744 WRITE_REQ
*pSMB
= NULL
;
1747 int resp_buf_type
= 0;
1748 __u32 pid
= io_parms
->pid
;
1749 __u16 netfid
= io_parms
->netfid
;
1750 __u64 offset
= io_parms
->offset
;
1751 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1752 unsigned int count
= io_parms
->length
;
1753 struct kvec rsp_iov
;
1757 cifs_dbg(FYI
, "write2 at %lld %d bytes\n", (long long)offset
, count
);
1759 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
1763 if ((offset
>> 32) > 0) {
1764 /* can not handle big offset for old srv */
1768 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
);
1772 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1773 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1775 /* tcon and ses pointer are checked in smb_init */
1776 if (tcon
->ses
->server
== NULL
)
1777 return -ECONNABORTED
;
1779 pSMB
->AndXCommand
= 0xFF; /* none */
1781 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1783 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1784 pSMB
->Reserved
= 0xFFFFFFFF;
1785 pSMB
->WriteMode
= 0;
1786 pSMB
->Remaining
= 0;
1789 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1791 pSMB
->DataLengthLow
= cpu_to_le16(count
& 0xFFFF);
1792 pSMB
->DataLengthHigh
= cpu_to_le16(count
>> 16);
1793 /* header + 1 byte pad */
1794 smb_hdr_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 1;
1796 inc_rfc1001_len(pSMB
, count
+ 1);
1797 else /* wct == 12 */
1798 inc_rfc1001_len(pSMB
, count
+ 5); /* smb data starts later */
1800 pSMB
->ByteCount
= cpu_to_le16(count
+ 1);
1801 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
1802 struct smb_com_writex_req
*pSMBW
=
1803 (struct smb_com_writex_req
*)pSMB
;
1804 pSMBW
->ByteCount
= cpu_to_le16(count
+ 5);
1806 iov
[0].iov_base
= pSMB
;
1808 iov
[0].iov_len
= smb_hdr_len
+ 4;
1809 else /* wct == 12 pad bigger by four bytes */
1810 iov
[0].iov_len
= smb_hdr_len
+ 8;
1812 rc
= SendReceive2(xid
, tcon
->ses
, iov
, n_vec
+ 1, &resp_buf_type
, 0,
1814 cifs_small_buf_release(pSMB
);
1815 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
1817 cifs_dbg(FYI
, "Send error Write2 = %d\n", rc
);
1818 } else if (resp_buf_type
== 0) {
1819 /* presumably this can not happen, but best to be safe */
1822 WRITE_RSP
*pSMBr
= (WRITE_RSP
*)rsp_iov
.iov_base
;
1823 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
1824 *nbytes
= (*nbytes
) << 16;
1825 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
1828 * Mask off high 16 bits when bytes written as returned by the
1829 * server is greater than bytes requested by the client. OS/2
1830 * servers are known to set incorrect CountHigh values.
1832 if (*nbytes
> count
)
1836 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
1838 /* Note: On -EAGAIN error only caller can retry on handle based calls
1839 since file handle passed in no longer valid */
1844 int cifs_lockv(const unsigned int xid
, struct cifs_tcon
*tcon
,
1845 const __u16 netfid
, const __u8 lock_type
, const __u32 num_unlock
,
1846 const __u32 num_lock
, LOCKING_ANDX_RANGE
*buf
)
1849 LOCK_REQ
*pSMB
= NULL
;
1851 struct kvec rsp_iov
;
1855 cifs_dbg(FYI
, "cifs_lockv num lock %d num unlock %d\n",
1856 num_lock
, num_unlock
);
1858 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
1863 pSMB
->NumberOfLocks
= cpu_to_le16(num_lock
);
1864 pSMB
->NumberOfUnlocks
= cpu_to_le16(num_unlock
);
1865 pSMB
->LockType
= lock_type
;
1866 pSMB
->AndXCommand
= 0xFF; /* none */
1867 pSMB
->Fid
= netfid
; /* netfid stays le */
1869 count
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
1870 inc_rfc1001_len(pSMB
, count
);
1871 pSMB
->ByteCount
= cpu_to_le16(count
);
1873 iov
[0].iov_base
= (char *)pSMB
;
1874 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4 -
1875 (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
1876 iov
[1].iov_base
= (char *)buf
;
1877 iov
[1].iov_len
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
1879 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
1880 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 2, &resp_buf_type
,
1881 CIFS_NO_RSP_BUF
, &rsp_iov
);
1882 cifs_small_buf_release(pSMB
);
1884 cifs_dbg(FYI
, "Send error in cifs_lockv = %d\n", rc
);
1890 CIFSSMBLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
1891 const __u16 smb_file_id
, const __u32 netpid
, const __u64 len
,
1892 const __u64 offset
, const __u32 numUnlock
,
1893 const __u32 numLock
, const __u8 lockType
,
1894 const bool waitFlag
, const __u8 oplock_level
)
1897 LOCK_REQ
*pSMB
= NULL
;
1898 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
1903 cifs_dbg(FYI
, "CIFSSMBLock timeout %d numLock %d\n",
1904 (int)waitFlag
, numLock
);
1905 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
1910 if (lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
1911 /* no response expected */
1912 flags
= CIFS_NO_SRV_RSP
| CIFS_NON_BLOCKING
| CIFS_OBREAK_OP
;
1914 } else if (waitFlag
) {
1915 flags
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
1916 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
1921 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
1922 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
1923 pSMB
->LockType
= lockType
;
1924 pSMB
->OplockLevel
= oplock_level
;
1925 pSMB
->AndXCommand
= 0xFF; /* none */
1926 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
1928 if ((numLock
!= 0) || (numUnlock
!= 0)) {
1929 pSMB
->Locks
[0].Pid
= cpu_to_le16(netpid
);
1930 /* BB where to store pid high? */
1931 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
1932 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
1933 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
1934 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
1935 count
= sizeof(LOCKING_ANDX_RANGE
);
1940 inc_rfc1001_len(pSMB
, count
);
1941 pSMB
->ByteCount
= cpu_to_le16(count
);
1944 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
1945 (struct smb_hdr
*) pSMB
, &bytes_returned
);
1947 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)pSMB
, flags
);
1948 cifs_small_buf_release(pSMB
);
1949 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
1951 cifs_dbg(FYI
, "Send error in Lock = %d\n", rc
);
1953 /* Note: On -EAGAIN error only caller can retry on handle based calls
1954 since file handle passed in no longer valid */
1959 CIFSSMBPosixLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
1960 const __u16 smb_file_id
, const __u32 netpid
,
1961 const loff_t start_offset
, const __u64 len
,
1962 struct file_lock
*pLockData
, const __u16 lock_type
,
1963 const bool waitFlag
)
1965 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
1966 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
1967 struct cifs_posix_lock
*parm_data
;
1970 int bytes_returned
= 0;
1971 int resp_buf_type
= 0;
1972 __u16 params
, param_offset
, offset
, byte_count
, count
;
1974 struct kvec rsp_iov
;
1976 cifs_dbg(FYI
, "Posix Lock\n");
1978 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
1983 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)pSMB
;
1986 pSMB
->MaxSetupCount
= 0;
1989 pSMB
->Reserved2
= 0;
1990 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
1991 offset
= param_offset
+ params
;
1993 count
= sizeof(struct cifs_posix_lock
);
1994 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1995 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
1996 pSMB
->SetupCount
= 1;
1997 pSMB
->Reserved3
= 0;
1999 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
2001 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2002 byte_count
= 3 /* pad */ + params
+ count
;
2003 pSMB
->DataCount
= cpu_to_le16(count
);
2004 pSMB
->ParameterCount
= cpu_to_le16(params
);
2005 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2006 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2007 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2008 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2009 parm_data
= (struct cifs_posix_lock
*)
2010 (((char *)pSMB
) + offset
+ 4);
2012 parm_data
->lock_type
= cpu_to_le16(lock_type
);
2014 timeout
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2015 parm_data
->lock_flags
= cpu_to_le16(1);
2016 pSMB
->Timeout
= cpu_to_le32(-1);
2020 parm_data
->pid
= cpu_to_le32(netpid
);
2021 parm_data
->start
= cpu_to_le64(start_offset
);
2022 parm_data
->length
= cpu_to_le64(len
); /* normalize negative numbers */
2024 pSMB
->DataOffset
= cpu_to_le16(offset
);
2025 pSMB
->Fid
= smb_file_id
;
2026 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_LOCK
);
2027 pSMB
->Reserved4
= 0;
2028 inc_rfc1001_len(pSMB
, byte_count
);
2029 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2031 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2032 (struct smb_hdr
*) pSMBr
, &bytes_returned
);
2034 iov
[0].iov_base
= (char *)pSMB
;
2035 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
2036 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
2037 &resp_buf_type
, timeout
, &rsp_iov
);
2038 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)rsp_iov
.iov_base
;
2040 cifs_small_buf_release(pSMB
);
2043 cifs_dbg(FYI
, "Send error in Posix Lock = %d\n", rc
);
2044 } else if (pLockData
) {
2045 /* lock structure can be returned on get */
2048 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2050 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(*parm_data
)) {
2051 rc
= -EIO
; /* bad smb */
2054 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
2055 data_count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2056 if (data_count
< sizeof(struct cifs_posix_lock
)) {
2060 parm_data
= (struct cifs_posix_lock
*)
2061 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2062 if (parm_data
->lock_type
== cpu_to_le16(CIFS_UNLCK
))
2063 pLockData
->fl_type
= F_UNLCK
;
2065 if (parm_data
->lock_type
==
2066 cpu_to_le16(CIFS_RDLCK
))
2067 pLockData
->fl_type
= F_RDLCK
;
2068 else if (parm_data
->lock_type
==
2069 cpu_to_le16(CIFS_WRLCK
))
2070 pLockData
->fl_type
= F_WRLCK
;
2072 pLockData
->fl_start
= le64_to_cpu(parm_data
->start
);
2073 pLockData
->fl_end
= pLockData
->fl_start
+
2074 (le64_to_cpu(parm_data
->length
) ?
2075 le64_to_cpu(parm_data
->length
) - 1 : 0);
2076 pLockData
->fl_pid
= -le32_to_cpu(parm_data
->pid
);
2081 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2083 /* Note: On -EAGAIN error only caller can retry on handle based calls
2084 since file handle passed in no longer valid */
2091 CIFSSMBClose(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2094 CLOSE_REQ
*pSMB
= NULL
;
2095 cifs_dbg(FYI
, "In CIFSSMBClose\n");
2097 /* do not retry on dead session on close */
2098 rc
= small_smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
);
2104 pSMB
->FileID
= (__u16
) smb_file_id
;
2105 pSMB
->LastWriteTime
= 0xFFFFFFFF;
2106 pSMB
->ByteCount
= 0;
2107 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2108 cifs_small_buf_release(pSMB
);
2109 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_closes
);
2112 /* EINTR is expected when user ctl-c to kill app */
2113 cifs_dbg(VFS
, "Send error in Close = %d\n", rc
);
2117 /* Since session is dead, file will be closed on server already */
2125 CIFSSMBFlush(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2128 FLUSH_REQ
*pSMB
= NULL
;
2129 cifs_dbg(FYI
, "In CIFSSMBFlush\n");
2131 rc
= small_smb_init(SMB_COM_FLUSH
, 1, tcon
, (void **) &pSMB
);
2135 pSMB
->FileID
= (__u16
) smb_file_id
;
2136 pSMB
->ByteCount
= 0;
2137 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2138 cifs_small_buf_release(pSMB
);
2139 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_flushes
);
2141 cifs_dbg(VFS
, "Send error in Flush = %d\n", rc
);
2147 CIFSSMBRename(const unsigned int xid
, struct cifs_tcon
*tcon
,
2148 const char *from_name
, const char *to_name
,
2149 struct cifs_sb_info
*cifs_sb
)
2152 RENAME_REQ
*pSMB
= NULL
;
2153 RENAME_RSP
*pSMBr
= NULL
;
2155 int name_len
, name_len2
;
2157 int remap
= cifs_remap(cifs_sb
);
2159 cifs_dbg(FYI
, "In CIFSSMBRename\n");
2161 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
2166 pSMB
->BufferFormat
= 0x04;
2167 pSMB
->SearchAttributes
=
2168 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2171 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2172 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2173 from_name
, PATH_MAX
,
2174 cifs_sb
->local_nls
, remap
);
2175 name_len
++; /* trailing null */
2177 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2178 /* protocol requires ASCII signature byte on Unicode string */
2179 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2181 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2182 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2184 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2185 name_len2
*= 2; /* convert to bytes */
2187 name_len
= copy_path_name(pSMB
->OldFileName
, from_name
);
2188 name_len2
= copy_path_name(pSMB
->OldFileName
+name_len
+1, to_name
);
2189 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2190 name_len2
++; /* signature byte */
2193 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2194 inc_rfc1001_len(pSMB
, count
);
2195 pSMB
->ByteCount
= cpu_to_le16(count
);
2197 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2198 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2199 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_renames
);
2201 cifs_dbg(FYI
, "Send error in rename = %d\n", rc
);
2203 cifs_buf_release(pSMB
);
2211 int CIFSSMBRenameOpenFile(const unsigned int xid
, struct cifs_tcon
*pTcon
,
2212 int netfid
, const char *target_name
,
2213 const struct nls_table
*nls_codepage
, int remap
)
2215 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2216 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2217 struct set_file_rename
*rename_info
;
2219 char dummy_string
[30];
2221 int bytes_returned
= 0;
2223 __u16 params
, param_offset
, offset
, count
, byte_count
;
2225 cifs_dbg(FYI
, "Rename to File by handle\n");
2226 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
2232 pSMB
->MaxSetupCount
= 0;
2236 pSMB
->Reserved2
= 0;
2237 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2238 offset
= param_offset
+ params
;
2240 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2241 data_offset
= (char *)(pSMB
) + offset
+ 4;
2242 rename_info
= (struct set_file_rename
*) data_offset
;
2243 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2244 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2245 pSMB
->SetupCount
= 1;
2246 pSMB
->Reserved3
= 0;
2247 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2248 byte_count
= 3 /* pad */ + params
;
2249 pSMB
->ParameterCount
= cpu_to_le16(params
);
2250 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2251 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2252 pSMB
->DataOffset
= cpu_to_le16(offset
);
2253 /* construct random name ".cifs_tmp<inodenum><mid>" */
2254 rename_info
->overwrite
= cpu_to_le32(1);
2255 rename_info
->root_fid
= 0;
2256 /* unicode only call */
2257 if (target_name
== NULL
) {
2258 sprintf(dummy_string
, "cifs%x", pSMB
->hdr
.Mid
);
2260 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2261 dummy_string
, 24, nls_codepage
, remap
);
2264 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2265 target_name
, PATH_MAX
, nls_codepage
,
2268 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
2269 count
= sizeof(struct set_file_rename
) + (2 * len_of_str
);
2270 byte_count
+= count
;
2271 pSMB
->DataCount
= cpu_to_le16(count
);
2272 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2274 pSMB
->InformationLevel
=
2275 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
2276 pSMB
->Reserved4
= 0;
2277 inc_rfc1001_len(pSMB
, byte_count
);
2278 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2279 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
2280 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2281 cifs_stats_inc(&pTcon
->stats
.cifs_stats
.num_t2renames
);
2283 cifs_dbg(FYI
, "Send error in Rename (by file handle) = %d\n",
2286 cifs_buf_release(pSMB
);
2288 /* Note: On -EAGAIN error only caller can retry on handle based calls
2289 since file handle passed in no longer valid */
2295 CIFSSMBCopy(const unsigned int xid
, struct cifs_tcon
*tcon
,
2296 const char *fromName
, const __u16 target_tid
, const char *toName
,
2297 const int flags
, const struct nls_table
*nls_codepage
, int remap
)
2300 COPY_REQ
*pSMB
= NULL
;
2301 COPY_RSP
*pSMBr
= NULL
;
2303 int name_len
, name_len2
;
2306 cifs_dbg(FYI
, "In CIFSSMBCopy\n");
2308 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
2313 pSMB
->BufferFormat
= 0x04;
2314 pSMB
->Tid2
= target_tid
;
2316 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
2318 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2319 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2320 fromName
, PATH_MAX
, nls_codepage
,
2322 name_len
++; /* trailing null */
2324 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2325 /* protocol requires ASCII signature byte on Unicode string */
2326 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2328 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2329 toName
, PATH_MAX
, nls_codepage
, remap
);
2330 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2331 name_len2
*= 2; /* convert to bytes */
2333 name_len
= copy_path_name(pSMB
->OldFileName
, fromName
);
2334 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2335 name_len2
= copy_path_name(pSMB
->OldFileName
+name_len
+1, toName
);
2336 name_len2
++; /* signature byte */
2339 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2340 inc_rfc1001_len(pSMB
, count
);
2341 pSMB
->ByteCount
= cpu_to_le16(count
);
2343 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2344 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2346 cifs_dbg(FYI
, "Send error in copy = %d with %d files copied\n",
2347 rc
, le16_to_cpu(pSMBr
->CopyCount
));
2349 cifs_buf_release(pSMB
);
2358 CIFSUnixCreateSymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2359 const char *fromName
, const char *toName
,
2360 const struct nls_table
*nls_codepage
, int remap
)
2362 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2363 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2366 int name_len_target
;
2368 int bytes_returned
= 0;
2369 __u16 params
, param_offset
, offset
, byte_count
;
2371 cifs_dbg(FYI
, "In Symlink Unix style\n");
2373 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2378 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2380 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fromName
,
2381 /* find define for this maxpathcomponent */
2382 PATH_MAX
, nls_codepage
, remap
);
2383 name_len
++; /* trailing null */
2387 name_len
= copy_path_name(pSMB
->FileName
, fromName
);
2389 params
= 6 + name_len
;
2390 pSMB
->MaxSetupCount
= 0;
2394 pSMB
->Reserved2
= 0;
2395 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2396 InformationLevel
) - 4;
2397 offset
= param_offset
+ params
;
2399 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2400 data_offset
= (char *)pSMB
+ offset
+ 4;
2401 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2403 cifsConvertToUTF16((__le16
*) data_offset
, toName
,
2404 /* find define for this maxpathcomponent */
2405 PATH_MAX
, nls_codepage
, remap
);
2406 name_len_target
++; /* trailing null */
2407 name_len_target
*= 2;
2409 name_len_target
= copy_path_name(data_offset
, toName
);
2412 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2413 /* BB find exact max on data count below from sess */
2414 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2415 pSMB
->SetupCount
= 1;
2416 pSMB
->Reserved3
= 0;
2417 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2418 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2419 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2420 pSMB
->ParameterCount
= cpu_to_le16(params
);
2421 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2422 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2423 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2424 pSMB
->DataOffset
= cpu_to_le16(offset
);
2425 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
2426 pSMB
->Reserved4
= 0;
2427 inc_rfc1001_len(pSMB
, byte_count
);
2428 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2429 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2430 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2431 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_symlinks
);
2433 cifs_dbg(FYI
, "Send error in SetPathInfo create symlink = %d\n",
2436 cifs_buf_release(pSMB
);
2439 goto createSymLinkRetry
;
2445 CIFSUnixCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2446 const char *fromName
, const char *toName
,
2447 const struct nls_table
*nls_codepage
, int remap
)
2449 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2450 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2453 int name_len_target
;
2455 int bytes_returned
= 0;
2456 __u16 params
, param_offset
, offset
, byte_count
;
2458 cifs_dbg(FYI
, "In Create Hard link Unix style\n");
2459 createHardLinkRetry
:
2460 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2465 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2466 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->FileName
, toName
,
2467 PATH_MAX
, nls_codepage
, remap
);
2468 name_len
++; /* trailing null */
2472 name_len
= copy_path_name(pSMB
->FileName
, toName
);
2474 params
= 6 + name_len
;
2475 pSMB
->MaxSetupCount
= 0;
2479 pSMB
->Reserved2
= 0;
2480 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2481 InformationLevel
) - 4;
2482 offset
= param_offset
+ params
;
2484 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2485 data_offset
= (char *)pSMB
+ offset
+ 4;
2486 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2488 cifsConvertToUTF16((__le16
*) data_offset
, fromName
,
2489 PATH_MAX
, nls_codepage
, remap
);
2490 name_len_target
++; /* trailing null */
2491 name_len_target
*= 2;
2493 name_len_target
= copy_path_name(data_offset
, fromName
);
2496 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2497 /* BB find exact max on data count below from sess*/
2498 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2499 pSMB
->SetupCount
= 1;
2500 pSMB
->Reserved3
= 0;
2501 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2502 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2503 pSMB
->ParameterCount
= cpu_to_le16(params
);
2504 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2505 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2506 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2507 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2508 pSMB
->DataOffset
= cpu_to_le16(offset
);
2509 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
2510 pSMB
->Reserved4
= 0;
2511 inc_rfc1001_len(pSMB
, byte_count
);
2512 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2513 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2514 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2515 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
2517 cifs_dbg(FYI
, "Send error in SetPathInfo (hard link) = %d\n",
2520 cifs_buf_release(pSMB
);
2522 goto createHardLinkRetry
;
2528 CIFSCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2529 const char *from_name
, const char *to_name
,
2530 struct cifs_sb_info
*cifs_sb
)
2533 NT_RENAME_REQ
*pSMB
= NULL
;
2534 RENAME_RSP
*pSMBr
= NULL
;
2536 int name_len
, name_len2
;
2538 int remap
= cifs_remap(cifs_sb
);
2540 cifs_dbg(FYI
, "In CIFSCreateHardLink\n");
2541 winCreateHardLinkRetry
:
2543 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
2548 pSMB
->SearchAttributes
=
2549 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2551 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
2552 pSMB
->ClusterCount
= 0;
2554 pSMB
->BufferFormat
= 0x04;
2556 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2558 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, from_name
,
2559 PATH_MAX
, cifs_sb
->local_nls
, remap
);
2560 name_len
++; /* trailing null */
2563 /* protocol specifies ASCII buffer format (0x04) for unicode */
2564 pSMB
->OldFileName
[name_len
] = 0x04;
2565 pSMB
->OldFileName
[name_len
+ 1] = 0x00; /* pad */
2567 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2568 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2570 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2571 name_len2
*= 2; /* convert to bytes */
2573 name_len
= copy_path_name(pSMB
->OldFileName
, from_name
);
2574 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2575 name_len2
= copy_path_name(pSMB
->OldFileName
+name_len
+1, to_name
);
2576 name_len2
++; /* signature byte */
2579 count
= 1 /* string type byte */ + name_len
+ name_len2
;
2580 inc_rfc1001_len(pSMB
, count
);
2581 pSMB
->ByteCount
= cpu_to_le16(count
);
2583 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2584 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2585 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
2587 cifs_dbg(FYI
, "Send error in hard link (NT rename) = %d\n", rc
);
2589 cifs_buf_release(pSMB
);
2591 goto winCreateHardLinkRetry
;
2597 CIFSSMBUnixQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2598 const unsigned char *searchName
, char **symlinkinfo
,
2599 const struct nls_table
*nls_codepage
, int remap
)
2601 /* SMB_QUERY_FILE_UNIX_LINK */
2602 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
2603 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
2607 __u16 params
, byte_count
;
2610 cifs_dbg(FYI
, "In QPathSymLinkInfo (Unix) for path %s\n", searchName
);
2613 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2618 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2620 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
2621 searchName
, PATH_MAX
, nls_codepage
,
2623 name_len
++; /* trailing null */
2626 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
2629 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
2630 pSMB
->TotalDataCount
= 0;
2631 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2632 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
2633 pSMB
->MaxSetupCount
= 0;
2637 pSMB
->Reserved2
= 0;
2638 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
2639 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
2640 pSMB
->DataCount
= 0;
2641 pSMB
->DataOffset
= 0;
2642 pSMB
->SetupCount
= 1;
2643 pSMB
->Reserved3
= 0;
2644 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
2645 byte_count
= params
+ 1 /* pad */ ;
2646 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
2647 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
2648 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
2649 pSMB
->Reserved4
= 0;
2650 inc_rfc1001_len(pSMB
, byte_count
);
2651 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2653 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2654 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2656 cifs_dbg(FYI
, "Send error in QuerySymLinkInfo = %d\n", rc
);
2658 /* decode response */
2660 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2661 /* BB also check enough total bytes returned */
2662 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
2666 u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2668 data_start
= ((char *) &pSMBr
->hdr
.Protocol
) +
2669 le16_to_cpu(pSMBr
->t2
.DataOffset
);
2671 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
2676 /* BB FIXME investigate remapping reserved chars here */
2677 *symlinkinfo
= cifs_strndup_from_utf16(data_start
,
2678 count
, is_unicode
, nls_codepage
);
2683 cifs_buf_release(pSMB
);
2685 goto querySymLinkRetry
;
2690 * Recent Windows versions now create symlinks more frequently
2691 * and they use the "reparse point" mechanism below. We can of course
2692 * do symlinks nicely to Samba and other servers which support the
2693 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
2694 * "MF" symlinks optionally, but for recent Windows we really need to
2695 * reenable the code below and fix the cifs_symlink callers to handle this.
2696 * In the interim this code has been moved to its own config option so
2697 * it is not compiled in by default until callers fixed up and more tested.
2700 CIFSSMBQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2701 __u16 fid
, char **symlinkinfo
,
2702 const struct nls_table
*nls_codepage
)
2706 struct smb_com_transaction_ioctl_req
*pSMB
;
2707 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
2709 unsigned int sub_len
;
2711 struct reparse_symlink_data
*reparse_buf
;
2712 struct reparse_posix_data
*posix_buf
;
2713 __u32 data_offset
, data_count
;
2716 cifs_dbg(FYI
, "In Windows reparse style QueryLink for fid %u\n", fid
);
2717 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
2722 pSMB
->TotalParameterCount
= 0 ;
2723 pSMB
->TotalDataCount
= 0;
2724 pSMB
->MaxParameterCount
= cpu_to_le32(2);
2725 /* BB find exact data count max from sess structure BB */
2726 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
2727 pSMB
->MaxSetupCount
= 4;
2729 pSMB
->ParameterOffset
= 0;
2730 pSMB
->DataCount
= 0;
2731 pSMB
->DataOffset
= 0;
2732 pSMB
->SetupCount
= 4;
2733 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
2734 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
2735 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
2736 pSMB
->IsFsctl
= 1; /* FSCTL */
2737 pSMB
->IsRootFlag
= 0;
2738 pSMB
->Fid
= fid
; /* file handle always le */
2739 pSMB
->ByteCount
= 0;
2741 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2742 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2744 cifs_dbg(FYI
, "Send error in QueryReparseLinkInfo = %d\n", rc
);
2748 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
2749 data_count
= le32_to_cpu(pSMBr
->DataCount
);
2750 if (get_bcc(&pSMBr
->hdr
) < 2 || data_offset
> 512) {
2751 /* BB also check enough total bytes returned */
2752 rc
= -EIO
; /* bad smb */
2755 if (!data_count
|| (data_count
> 2048)) {
2757 cifs_dbg(FYI
, "Invalid return data count on get reparse info ioctl\n");
2760 end_of_smb
= 2 + get_bcc(&pSMBr
->hdr
) + (char *)&pSMBr
->ByteCount
;
2761 reparse_buf
= (struct reparse_symlink_data
*)
2762 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2763 if ((char *)reparse_buf
>= end_of_smb
) {
2767 if (reparse_buf
->ReparseTag
== cpu_to_le32(IO_REPARSE_TAG_NFS
)) {
2768 cifs_dbg(FYI
, "NFS style reparse tag\n");
2769 posix_buf
= (struct reparse_posix_data
*)reparse_buf
;
2771 if (posix_buf
->InodeType
!= cpu_to_le64(NFS_SPECFILE_LNK
)) {
2772 cifs_dbg(FYI
, "unsupported file type 0x%llx\n",
2773 le64_to_cpu(posix_buf
->InodeType
));
2778 sub_len
= le16_to_cpu(reparse_buf
->ReparseDataLength
);
2779 if (posix_buf
->PathBuffer
+ sub_len
> end_of_smb
) {
2780 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
2784 *symlinkinfo
= cifs_strndup_from_utf16(posix_buf
->PathBuffer
,
2785 sub_len
, is_unicode
, nls_codepage
);
2787 } else if (reparse_buf
->ReparseTag
!=
2788 cpu_to_le32(IO_REPARSE_TAG_SYMLINK
)) {
2793 /* Reparse tag is NTFS symlink */
2794 sub_start
= le16_to_cpu(reparse_buf
->SubstituteNameOffset
) +
2795 reparse_buf
->PathBuffer
;
2796 sub_len
= le16_to_cpu(reparse_buf
->SubstituteNameLength
);
2797 if (sub_start
+ sub_len
> end_of_smb
) {
2798 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
2802 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
2807 /* BB FIXME investigate remapping reserved chars here */
2808 *symlinkinfo
= cifs_strndup_from_utf16(sub_start
, sub_len
, is_unicode
,
2813 cifs_buf_release(pSMB
);
2816 * Note: On -EAGAIN error only caller can retry on handle based calls
2817 * since file handle passed in no longer valid.
2823 CIFSSMB_set_compression(const unsigned int xid
, struct cifs_tcon
*tcon
,
2828 struct smb_com_transaction_compr_ioctl_req
*pSMB
;
2829 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
2831 cifs_dbg(FYI
, "Set compression for %u\n", fid
);
2832 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
2837 pSMB
->compression_state
= cpu_to_le16(COMPRESSION_FORMAT_DEFAULT
);
2839 pSMB
->TotalParameterCount
= 0;
2840 pSMB
->TotalDataCount
= cpu_to_le32(2);
2841 pSMB
->MaxParameterCount
= 0;
2842 pSMB
->MaxDataCount
= 0;
2843 pSMB
->MaxSetupCount
= 4;
2845 pSMB
->ParameterOffset
= 0;
2846 pSMB
->DataCount
= cpu_to_le32(2);
2848 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req
,
2849 compression_state
) - 4); /* 84 */
2850 pSMB
->SetupCount
= 4;
2851 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
2852 pSMB
->ParameterCount
= 0;
2853 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_SET_COMPRESSION
);
2854 pSMB
->IsFsctl
= 1; /* FSCTL */
2855 pSMB
->IsRootFlag
= 0;
2856 pSMB
->Fid
= fid
; /* file handle always le */
2857 /* 3 byte pad, followed by 2 byte compress state */
2858 pSMB
->ByteCount
= cpu_to_le16(5);
2859 inc_rfc1001_len(pSMB
, 5);
2861 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2862 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2864 cifs_dbg(FYI
, "Send error in SetCompression = %d\n", rc
);
2866 cifs_buf_release(pSMB
);
2869 * Note: On -EAGAIN error only caller can retry on handle based calls
2870 * since file handle passed in no longer valid.
2876 #ifdef CONFIG_CIFS_POSIX
2878 #ifdef CONFIG_FS_POSIX_ACL
2880 * cifs_init_posix_acl - convert ACL from cifs to POSIX ACL format
2881 * @ace: POSIX ACL entry to store converted ACL into
2882 * @cifs_ace: ACL in cifs format
2884 * Convert an Access Control Entry from wire format to local POSIX xattr
2887 * Note that the @cifs_uid member is used to store both {g,u}id_t.
2889 static void cifs_init_posix_acl(struct posix_acl_entry
*ace
,
2890 struct cifs_posix_ace
*cifs_ace
)
2892 /* u8 cifs fields do not need le conversion */
2893 ace
->e_perm
= cifs_ace
->cifs_e_perm
;
2894 ace
->e_tag
= cifs_ace
->cifs_e_tag
;
2896 switch (ace
->e_tag
) {
2898 ace
->e_uid
= make_kuid(&init_user_ns
,
2899 le64_to_cpu(cifs_ace
->cifs_uid
));
2902 ace
->e_gid
= make_kgid(&init_user_ns
,
2903 le64_to_cpu(cifs_ace
->cifs_uid
));
2910 * cifs_to_posix_acl - copy cifs ACL format to POSIX ACL format
2911 * @acl: ACLs returned in POSIX ACL format
2912 * @src: ACLs in cifs format
2913 * @acl_type: type of POSIX ACL requested
2914 * @size_of_data_area: size of SMB we got
2916 * This function converts ACLs from cifs format to POSIX ACL format.
2917 * If @acl is NULL then the size of the buffer required to store POSIX ACLs in
2918 * their uapi format is returned.
2920 static int cifs_to_posix_acl(struct posix_acl
**acl
, char *src
,
2921 const int acl_type
, const int size_of_data_area
)
2925 struct cifs_posix_ace
*pACE
;
2926 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)src
;
2927 struct posix_acl
*kacl
= NULL
;
2928 struct posix_acl_entry
*pa
, *pe
;
2930 if (le16_to_cpu(cifs_acl
->version
) != CIFS_ACL_VERSION
)
2933 if (acl_type
== ACL_TYPE_ACCESS
) {
2934 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
2935 pACE
= &cifs_acl
->ace_array
[0];
2936 size
= sizeof(struct cifs_posix_acl
);
2937 size
+= sizeof(struct cifs_posix_ace
) * count
;
2938 /* check if we would go beyond end of SMB */
2939 if (size_of_data_area
< size
) {
2940 cifs_dbg(FYI
, "bad CIFS POSIX ACL size %d vs. %d\n",
2941 size_of_data_area
, size
);
2944 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
2945 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
2946 size
= sizeof(struct cifs_posix_acl
);
2947 size
+= sizeof(struct cifs_posix_ace
) * count
;
2948 /* skip past access ACEs to get to default ACEs */
2949 pACE
= &cifs_acl
->ace_array
[count
];
2950 count
= le16_to_cpu(cifs_acl
->default_entry_count
);
2951 size
+= sizeof(struct cifs_posix_ace
) * count
;
2952 /* check if we would go beyond end of SMB */
2953 if (size_of_data_area
< size
)
2960 /* Allocate number of POSIX ACLs to store in VFS format. */
2961 kacl
= posix_acl_alloc(count
, GFP_NOFS
);
2965 FOREACH_ACL_ENTRY(pa
, kacl
, pe
) {
2966 cifs_init_posix_acl(pa
, pACE
);
2975 * cifs_init_ace - convert ACL entry from POSIX ACL to cifs format
2976 * @cifs_ace: the cifs ACL entry to store into
2977 * @local_ace: the POSIX ACL entry to convert
2979 static void cifs_init_ace(struct cifs_posix_ace
*cifs_ace
,
2980 const struct posix_acl_entry
*local_ace
)
2982 cifs_ace
->cifs_e_perm
= local_ace
->e_perm
;
2983 cifs_ace
->cifs_e_tag
= local_ace
->e_tag
;
2985 switch (local_ace
->e_tag
) {
2987 cifs_ace
->cifs_uid
=
2988 cpu_to_le64(from_kuid(&init_user_ns
, local_ace
->e_uid
));
2991 cifs_ace
->cifs_uid
=
2992 cpu_to_le64(from_kgid(&init_user_ns
, local_ace
->e_gid
));
2995 cifs_ace
->cifs_uid
= cpu_to_le64(-1);
3000 * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format
3001 * @parm_data: ACLs in cifs format to conver to
3002 * @acl: ACLs in POSIX ACL format to convert from
3003 * @acl_type: the type of POSIX ACLs stored in @acl
3005 * Return: the number cifs ACL entries after conversion
3007 static __u16
posix_acl_to_cifs(char *parm_data
, const struct posix_acl
*acl
,
3011 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)parm_data
;
3012 const struct posix_acl_entry
*pa
, *pe
;
3016 if ((acl
== NULL
) || (cifs_acl
== NULL
))
3019 count
= acl
->a_count
;
3020 cifs_dbg(FYI
, "setting acl with %d entries\n", count
);
3023 * Note that the uapi POSIX ACL version is verified by the VFS and is
3024 * independent of the cifs ACL version. Changing the POSIX ACL version
3025 * is a uapi change and if it's changed we will pass down the POSIX ACL
3026 * version in struct posix_acl from the VFS. For now there's really
3027 * only one that all filesystems know how to deal with.
3029 cifs_acl
->version
= cpu_to_le16(1);
3030 if (acl_type
== ACL_TYPE_ACCESS
) {
3031 cifs_acl
->access_entry_count
= cpu_to_le16(count
);
3032 cifs_acl
->default_entry_count
= cpu_to_le16(0xFFFF);
3033 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3034 cifs_acl
->default_entry_count
= cpu_to_le16(count
);
3035 cifs_acl
->access_entry_count
= cpu_to_le16(0xFFFF);
3037 cifs_dbg(FYI
, "unknown ACL type %d\n", acl_type
);
3040 FOREACH_ACL_ENTRY(pa
, acl
, pe
) {
3041 cifs_init_ace(&cifs_acl
->ace_array
[i
++], pa
);
3044 rc
= (__u16
)(count
* sizeof(struct cifs_posix_ace
));
3045 rc
+= sizeof(struct cifs_posix_acl
);
3046 /* BB add check to make sure ACL does not overflow SMB */
3051 int cifs_do_get_acl(const unsigned int xid
, struct cifs_tcon
*tcon
,
3052 const unsigned char *searchName
, struct posix_acl
**acl
,
3053 const int acl_type
, const struct nls_table
*nls_codepage
,
3056 /* SMB_QUERY_POSIX_ACL */
3057 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3058 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3062 __u16 params
, byte_count
;
3064 cifs_dbg(FYI
, "In GetPosixACL (Unix) for path %s\n", searchName
);
3067 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3072 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3074 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3075 searchName
, PATH_MAX
, nls_codepage
,
3077 name_len
++; /* trailing null */
3079 pSMB
->FileName
[name_len
] = 0;
3080 pSMB
->FileName
[name_len
+1] = 0;
3082 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
3085 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3086 pSMB
->TotalDataCount
= 0;
3087 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3088 /* BB find exact max data count below from sess structure BB */
3089 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3090 pSMB
->MaxSetupCount
= 0;
3094 pSMB
->Reserved2
= 0;
3095 pSMB
->ParameterOffset
= cpu_to_le16(
3096 offsetof(struct smb_com_transaction2_qpi_req
,
3097 InformationLevel
) - 4);
3098 pSMB
->DataCount
= 0;
3099 pSMB
->DataOffset
= 0;
3100 pSMB
->SetupCount
= 1;
3101 pSMB
->Reserved3
= 0;
3102 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3103 byte_count
= params
+ 1 /* pad */ ;
3104 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3105 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3106 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_ACL
);
3107 pSMB
->Reserved4
= 0;
3108 inc_rfc1001_len(pSMB
, byte_count
);
3109 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3111 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3112 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3113 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3115 cifs_dbg(FYI
, "Send error in Query POSIX ACL = %d\n", rc
);
3117 /* decode response */
3119 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3120 /* BB also check enough total bytes returned */
3121 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3122 rc
= -EIO
; /* bad smb */
3124 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3125 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3126 rc
= cifs_to_posix_acl(acl
,
3127 (char *)&pSMBr
->hdr
.Protocol
+data_offset
,
3131 cifs_buf_release(pSMB
);
3133 * The else branch after SendReceive() doesn't return EAGAIN so if we
3134 * allocated @acl in cifs_to_posix_acl() we are guaranteed to return
3135 * here and don't leak POSIX ACLs.
3142 int cifs_do_set_acl(const unsigned int xid
, struct cifs_tcon
*tcon
,
3143 const unsigned char *fileName
, const struct posix_acl
*acl
,
3144 const int acl_type
, const struct nls_table
*nls_codepage
,
3147 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3148 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3152 int bytes_returned
= 0;
3153 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
3155 cifs_dbg(FYI
, "In SetPosixACL (Unix) for path %s\n", fileName
);
3157 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3161 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3163 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
3164 PATH_MAX
, nls_codepage
, remap
);
3165 name_len
++; /* trailing null */
3168 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
3170 params
= 6 + name_len
;
3171 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3172 /* BB find max SMB size from sess */
3173 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3174 pSMB
->MaxSetupCount
= 0;
3178 pSMB
->Reserved2
= 0;
3179 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3180 InformationLevel
) - 4;
3181 offset
= param_offset
+ params
;
3182 parm_data
= ((char *) &pSMB
->hdr
.Protocol
) + offset
;
3183 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3185 /* convert to on the wire format for POSIX ACL */
3186 data_count
= posix_acl_to_cifs(parm_data
, acl
, acl_type
);
3188 if (data_count
== 0) {
3190 goto setACLerrorExit
;
3192 pSMB
->DataOffset
= cpu_to_le16(offset
);
3193 pSMB
->SetupCount
= 1;
3194 pSMB
->Reserved3
= 0;
3195 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3196 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_ACL
);
3197 byte_count
= 3 /* pad */ + params
+ data_count
;
3198 pSMB
->DataCount
= cpu_to_le16(data_count
);
3199 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3200 pSMB
->ParameterCount
= cpu_to_le16(params
);
3201 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3202 pSMB
->Reserved4
= 0;
3203 inc_rfc1001_len(pSMB
, byte_count
);
3204 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3205 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3206 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3208 cifs_dbg(FYI
, "Set POSIX ACL returned %d\n", rc
);
3211 cifs_buf_release(pSMB
);
3217 int cifs_do_get_acl(const unsigned int xid
, struct cifs_tcon
*tcon
,
3218 const unsigned char *searchName
, struct posix_acl
**acl
,
3219 const int acl_type
, const struct nls_table
*nls_codepage
,
3225 int cifs_do_set_acl(const unsigned int xid
, struct cifs_tcon
*tcon
,
3226 const unsigned char *fileName
, const struct posix_acl
*acl
,
3227 const int acl_type
, const struct nls_table
*nls_codepage
,
3232 #endif /* CONFIG_FS_POSIX_ACL */
3235 CIFSGetExtAttr(const unsigned int xid
, struct cifs_tcon
*tcon
,
3236 const int netfid
, __u64
*pExtAttrBits
, __u64
*pMask
)
3239 struct smb_t2_qfi_req
*pSMB
= NULL
;
3240 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3242 __u16 params
, byte_count
;
3244 cifs_dbg(FYI
, "In GetExtAttr\n");
3249 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3254 params
= 2 /* level */ + 2 /* fid */;
3255 pSMB
->t2
.TotalDataCount
= 0;
3256 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3257 /* BB find exact max data count below from sess structure BB */
3258 pSMB
->t2
.MaxDataCount
= cpu_to_le16(4000);
3259 pSMB
->t2
.MaxSetupCount
= 0;
3260 pSMB
->t2
.Reserved
= 0;
3262 pSMB
->t2
.Timeout
= 0;
3263 pSMB
->t2
.Reserved2
= 0;
3264 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3266 pSMB
->t2
.DataCount
= 0;
3267 pSMB
->t2
.DataOffset
= 0;
3268 pSMB
->t2
.SetupCount
= 1;
3269 pSMB
->t2
.Reserved3
= 0;
3270 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3271 byte_count
= params
+ 1 /* pad */ ;
3272 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3273 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3274 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_ATTR_FLAGS
);
3277 inc_rfc1001_len(pSMB
, byte_count
);
3278 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3280 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3281 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3283 cifs_dbg(FYI
, "error %d in GetExtAttr\n", rc
);
3285 /* decode response */
3286 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3287 /* BB also check enough total bytes returned */
3288 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3289 /* If rc should we check for EOPNOSUPP and
3290 disable the srvino flag? or in caller? */
3291 rc
= -EIO
; /* bad smb */
3293 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3294 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3295 struct file_chattr_info
*pfinfo
;
3298 cifs_dbg(FYI
, "Invalid size ret in GetExtAttr\n");
3302 pfinfo
= (struct file_chattr_info
*)
3303 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
3304 *pExtAttrBits
= le64_to_cpu(pfinfo
->mode
);
3305 *pMask
= le64_to_cpu(pfinfo
->mask
);
3309 cifs_buf_release(pSMB
);
3311 goto GetExtAttrRetry
;
3315 #endif /* CONFIG_POSIX */
3318 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3319 * all NT TRANSACTS that we init here have total parm and data under about 400
3320 * bytes (to fit in small cifs buffer size), which is the case so far, it
3321 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3322 * returned setup area) and MaxParameterCount (returned parms size) must be set
3326 smb_init_nttransact(const __u16 sub_command
, const int setup_count
,
3327 const int parm_len
, struct cifs_tcon
*tcon
,
3332 struct smb_com_ntransact_req
*pSMB
;
3334 rc
= small_smb_init(SMB_COM_NT_TRANSACT
, 19 + setup_count
, tcon
,
3338 *ret_buf
= (void *)pSMB
;
3340 pSMB
->TotalParameterCount
= cpu_to_le32(parm_len
);
3341 pSMB
->TotalDataCount
= 0;
3342 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3343 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3344 pSMB
->DataCount
= pSMB
->TotalDataCount
;
3345 temp_offset
= offsetof(struct smb_com_ntransact_req
, Parms
) +
3346 (setup_count
* 2) - 4 /* for rfc1001 length itself */;
3347 pSMB
->ParameterOffset
= cpu_to_le32(temp_offset
);
3348 pSMB
->DataOffset
= cpu_to_le32(temp_offset
+ parm_len
);
3349 pSMB
->SetupCount
= setup_count
; /* no need to le convert byte fields */
3350 pSMB
->SubCommand
= cpu_to_le16(sub_command
);
3355 validate_ntransact(char *buf
, char **ppparm
, char **ppdata
,
3356 __u32
*pparmlen
, __u32
*pdatalen
)
3359 __u32 data_count
, data_offset
, parm_count
, parm_offset
;
3360 struct smb_com_ntransact_rsp
*pSMBr
;
3369 pSMBr
= (struct smb_com_ntransact_rsp
*)buf
;
3371 bcc
= get_bcc(&pSMBr
->hdr
);
3372 end_of_smb
= 2 /* sizeof byte count */ + bcc
+
3373 (char *)&pSMBr
->ByteCount
;
3375 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3376 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3377 parm_offset
= le32_to_cpu(pSMBr
->ParameterOffset
);
3378 parm_count
= le32_to_cpu(pSMBr
->ParameterCount
);
3380 *ppparm
= (char *)&pSMBr
->hdr
.Protocol
+ parm_offset
;
3381 *ppdata
= (char *)&pSMBr
->hdr
.Protocol
+ data_offset
;
3383 /* should we also check that parm and data areas do not overlap? */
3384 if (*ppparm
> end_of_smb
) {
3385 cifs_dbg(FYI
, "parms start after end of smb\n");
3387 } else if (parm_count
+ *ppparm
> end_of_smb
) {
3388 cifs_dbg(FYI
, "parm end after end of smb\n");
3390 } else if (*ppdata
> end_of_smb
) {
3391 cifs_dbg(FYI
, "data starts after end of smb\n");
3393 } else if (data_count
+ *ppdata
> end_of_smb
) {
3394 cifs_dbg(FYI
, "data %p + count %d (%p) past smb end %p start %p\n",
3395 *ppdata
, data_count
, (data_count
+ *ppdata
),
3398 } else if (parm_count
+ data_count
> bcc
) {
3399 cifs_dbg(FYI
, "parm count and data count larger than SMB\n");
3402 *pdatalen
= data_count
;
3403 *pparmlen
= parm_count
;
3407 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3409 CIFSSMBGetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3410 struct cifs_ntsd
**acl_inf
, __u32
*pbuflen
)
3414 QUERY_SEC_DESC_REQ
*pSMB
;
3416 struct kvec rsp_iov
;
3418 cifs_dbg(FYI
, "GetCifsACL\n");
3423 rc
= smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC
, 0,
3424 8 /* parm len */, tcon
, (void **) &pSMB
);
3428 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3429 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3430 pSMB
->MaxSetupCount
= 0;
3431 pSMB
->Fid
= fid
; /* file handle always le */
3432 pSMB
->AclFlags
= cpu_to_le32(CIFS_ACL_OWNER
| CIFS_ACL_GROUP
|
3434 pSMB
->ByteCount
= cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3435 inc_rfc1001_len(pSMB
, 11);
3436 iov
[0].iov_base
= (char *)pSMB
;
3437 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
3439 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovec */, &buf_type
,
3441 cifs_small_buf_release(pSMB
);
3442 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3444 cifs_dbg(FYI
, "Send error in QuerySecDesc = %d\n", rc
);
3445 } else { /* decode response */
3449 struct smb_com_ntransact_rsp
*pSMBr
;
3452 /* validate_nttransact */
3453 rc
= validate_ntransact(rsp_iov
.iov_base
, (char **)&parm
,
3454 &pdata
, &parm_len
, pbuflen
);
3457 pSMBr
= (struct smb_com_ntransact_rsp
*)rsp_iov
.iov_base
;
3459 cifs_dbg(FYI
, "smb %p parm %p data %p\n",
3460 pSMBr
, parm
, *acl_inf
);
3462 if (le32_to_cpu(pSMBr
->ParameterCount
) != 4) {
3463 rc
= -EIO
; /* bad smb */
3468 /* BB check that data area is minimum length and as big as acl_len */
3470 acl_len
= le32_to_cpu(*parm
);
3471 if (acl_len
!= *pbuflen
) {
3472 cifs_dbg(VFS
, "acl length %d does not match %d\n",
3474 if (*pbuflen
> acl_len
)
3478 /* check if buffer is big enough for the acl
3479 header followed by the smallest SID */
3480 if ((*pbuflen
< sizeof(struct cifs_ntsd
) + 8) ||
3481 (*pbuflen
>= 64 * 1024)) {
3482 cifs_dbg(VFS
, "bad acl length %d\n", *pbuflen
);
3486 *acl_inf
= kmemdup(pdata
, *pbuflen
, GFP_KERNEL
);
3487 if (*acl_inf
== NULL
) {
3494 free_rsp_buf(buf_type
, rsp_iov
.iov_base
);
3499 CIFSSMBSetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3500 struct cifs_ntsd
*pntsd
, __u32 acllen
, int aclflag
)
3502 __u16 byte_count
, param_count
, data_count
, param_offset
, data_offset
;
3504 int bytes_returned
= 0;
3505 SET_SEC_DESC_REQ
*pSMB
= NULL
;
3509 rc
= smb_init(SMB_COM_NT_TRANSACT
, 19, tcon
, (void **) &pSMB
, &pSMBr
);
3513 pSMB
->MaxSetupCount
= 0;
3517 param_offset
= offsetof(struct smb_com_transaction_ssec_req
, Fid
) - 4;
3518 data_count
= acllen
;
3519 data_offset
= param_offset
+ param_count
;
3520 byte_count
= 3 /* pad */ + param_count
;
3522 pSMB
->DataCount
= cpu_to_le32(data_count
);
3523 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3524 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3525 pSMB
->MaxDataCount
= cpu_to_le32(16384);
3526 pSMB
->ParameterCount
= cpu_to_le32(param_count
);
3527 pSMB
->ParameterOffset
= cpu_to_le32(param_offset
);
3528 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3529 pSMB
->DataOffset
= cpu_to_le32(data_offset
);
3530 pSMB
->SetupCount
= 0;
3531 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC
);
3532 pSMB
->ByteCount
= cpu_to_le16(byte_count
+data_count
);
3534 pSMB
->Fid
= fid
; /* file handle always le */
3535 pSMB
->Reserved2
= 0;
3536 pSMB
->AclFlags
= cpu_to_le32(aclflag
);
3538 if (pntsd
&& acllen
) {
3539 memcpy((char *)pSMBr
+ offsetof(struct smb_hdr
, Protocol
) +
3540 data_offset
, pntsd
, acllen
);
3541 inc_rfc1001_len(pSMB
, byte_count
+ data_count
);
3543 inc_rfc1001_len(pSMB
, byte_count
);
3545 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3546 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3548 cifs_dbg(FYI
, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3549 bytes_returned
, rc
);
3551 cifs_dbg(FYI
, "Set CIFS ACL returned %d\n", rc
);
3552 cifs_buf_release(pSMB
);
3555 goto setCifsAclRetry
;
3561 /* Legacy Query Path Information call for lookup to old servers such
3564 SMBQueryInformation(const unsigned int xid
, struct cifs_tcon
*tcon
,
3565 const char *search_name
, FILE_ALL_INFO
*data
,
3566 const struct nls_table
*nls_codepage
, int remap
)
3568 QUERY_INFORMATION_REQ
*pSMB
;
3569 QUERY_INFORMATION_RSP
*pSMBr
;
3574 cifs_dbg(FYI
, "In SMBQPath path %s\n", search_name
);
3576 rc
= smb_init(SMB_COM_QUERY_INFORMATION
, 0, tcon
, (void **) &pSMB
,
3581 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3583 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3584 search_name
, PATH_MAX
, nls_codepage
,
3586 name_len
++; /* trailing null */
3589 name_len
= copy_path_name(pSMB
->FileName
, search_name
);
3591 pSMB
->BufferFormat
= 0x04;
3592 name_len
++; /* account for buffer type byte */
3593 inc_rfc1001_len(pSMB
, (__u16
)name_len
);
3594 pSMB
->ByteCount
= cpu_to_le16(name_len
);
3596 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3597 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3599 cifs_dbg(FYI
, "Send error in QueryInfo = %d\n", rc
);
3601 struct timespec64 ts
;
3602 __u32 time
= le32_to_cpu(pSMBr
->last_write_time
);
3604 /* decode response */
3605 /* BB FIXME - add time zone adjustment BB */
3606 memset(data
, 0, sizeof(FILE_ALL_INFO
));
3609 /* decode time fields */
3610 data
->ChangeTime
= cpu_to_le64(cifs_UnixTimeToNT(ts
));
3611 data
->LastWriteTime
= data
->ChangeTime
;
3612 data
->LastAccessTime
= 0;
3613 data
->AllocationSize
=
3614 cpu_to_le64(le32_to_cpu(pSMBr
->size
));
3615 data
->EndOfFile
= data
->AllocationSize
;
3617 cpu_to_le32(le16_to_cpu(pSMBr
->attr
));
3619 rc
= -EIO
; /* bad buffer passed in */
3621 cifs_buf_release(pSMB
);
3630 CIFSSMBQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
3631 u16 netfid
, FILE_ALL_INFO
*pFindData
)
3633 struct smb_t2_qfi_req
*pSMB
= NULL
;
3634 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3637 __u16 params
, byte_count
;
3640 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3645 params
= 2 /* level */ + 2 /* fid */;
3646 pSMB
->t2
.TotalDataCount
= 0;
3647 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3648 /* BB find exact max data count below from sess structure BB */
3649 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3650 pSMB
->t2
.MaxSetupCount
= 0;
3651 pSMB
->t2
.Reserved
= 0;
3653 pSMB
->t2
.Timeout
= 0;
3654 pSMB
->t2
.Reserved2
= 0;
3655 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3657 pSMB
->t2
.DataCount
= 0;
3658 pSMB
->t2
.DataOffset
= 0;
3659 pSMB
->t2
.SetupCount
= 1;
3660 pSMB
->t2
.Reserved3
= 0;
3661 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3662 byte_count
= params
+ 1 /* pad */ ;
3663 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3664 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3665 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
3668 inc_rfc1001_len(pSMB
, byte_count
);
3669 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3671 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3672 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3674 cifs_dbg(FYI
, "Send error in QFileInfo = %d\n", rc
);
3675 } else { /* decode response */
3676 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3678 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
3680 else if (get_bcc(&pSMBr
->hdr
) < 40)
3681 rc
= -EIO
; /* bad smb */
3682 else if (pFindData
) {
3683 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3684 memcpy((char *) pFindData
,
3685 (char *) &pSMBr
->hdr
.Protocol
+
3686 data_offset
, sizeof(FILE_ALL_INFO
));
3690 cifs_buf_release(pSMB
);
3692 goto QFileInfoRetry
;
3698 CIFSSMBQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
3699 const char *search_name
, FILE_ALL_INFO
*data
,
3700 int legacy
/* old style infolevel */,
3701 const struct nls_table
*nls_codepage
, int remap
)
3703 /* level 263 SMB_QUERY_FILE_ALL_INFO */
3704 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3705 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3709 __u16 params
, byte_count
;
3711 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3713 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3718 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3720 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, search_name
,
3721 PATH_MAX
, nls_codepage
, remap
);
3722 name_len
++; /* trailing null */
3725 name_len
= copy_path_name(pSMB
->FileName
, search_name
);
3728 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
3729 pSMB
->TotalDataCount
= 0;
3730 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3731 /* BB find exact max SMB PDU from sess structure BB */
3732 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3733 pSMB
->MaxSetupCount
= 0;
3737 pSMB
->Reserved2
= 0;
3738 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3739 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3740 pSMB
->DataCount
= 0;
3741 pSMB
->DataOffset
= 0;
3742 pSMB
->SetupCount
= 1;
3743 pSMB
->Reserved3
= 0;
3744 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3745 byte_count
= params
+ 1 /* pad */ ;
3746 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3747 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3749 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
3751 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
3752 pSMB
->Reserved4
= 0;
3753 inc_rfc1001_len(pSMB
, byte_count
);
3754 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3756 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3757 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3759 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
3760 } else { /* decode response */
3761 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3763 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
3765 else if (!legacy
&& get_bcc(&pSMBr
->hdr
) < 40)
3766 rc
= -EIO
; /* bad smb */
3767 else if (legacy
&& get_bcc(&pSMBr
->hdr
) < 24)
3768 rc
= -EIO
; /* 24 or 26 expected but we do not read
3772 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3775 * On legacy responses we do not read the last field,
3776 * EAsize, fortunately since it varies by subdialect and
3777 * also note it differs on Set vs Get, ie two bytes or 4
3778 * bytes depending but we don't care here.
3781 size
= sizeof(FILE_INFO_STANDARD
);
3783 size
= sizeof(FILE_ALL_INFO
);
3784 memcpy((char *) data
, (char *) &pSMBr
->hdr
.Protocol
+
3789 cifs_buf_release(pSMB
);
3791 goto QPathInfoRetry
;
3797 CIFSSMBUnixQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
3798 u16 netfid
, FILE_UNIX_BASIC_INFO
*pFindData
)
3800 struct smb_t2_qfi_req
*pSMB
= NULL
;
3801 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3804 __u16 params
, byte_count
;
3807 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3812 params
= 2 /* level */ + 2 /* fid */;
3813 pSMB
->t2
.TotalDataCount
= 0;
3814 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3815 /* BB find exact max data count below from sess structure BB */
3816 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3817 pSMB
->t2
.MaxSetupCount
= 0;
3818 pSMB
->t2
.Reserved
= 0;
3820 pSMB
->t2
.Timeout
= 0;
3821 pSMB
->t2
.Reserved2
= 0;
3822 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3824 pSMB
->t2
.DataCount
= 0;
3825 pSMB
->t2
.DataOffset
= 0;
3826 pSMB
->t2
.SetupCount
= 1;
3827 pSMB
->t2
.Reserved3
= 0;
3828 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3829 byte_count
= params
+ 1 /* pad */ ;
3830 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3831 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3832 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
3835 inc_rfc1001_len(pSMB
, byte_count
);
3836 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3838 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3839 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3841 cifs_dbg(FYI
, "Send error in UnixQFileInfo = %d\n", rc
);
3842 } else { /* decode response */
3843 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3845 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
3846 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3847 rc
= -EIO
; /* bad smb */
3849 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3850 memcpy((char *) pFindData
,
3851 (char *) &pSMBr
->hdr
.Protocol
+
3853 sizeof(FILE_UNIX_BASIC_INFO
));
3857 cifs_buf_release(pSMB
);
3859 goto UnixQFileInfoRetry
;
3865 CIFSSMBUnixQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
3866 const unsigned char *searchName
,
3867 FILE_UNIX_BASIC_INFO
*pFindData
,
3868 const struct nls_table
*nls_codepage
, int remap
)
3870 /* SMB_QUERY_FILE_UNIX_BASIC */
3871 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3872 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3874 int bytes_returned
= 0;
3876 __u16 params
, byte_count
;
3878 cifs_dbg(FYI
, "In QPathInfo (Unix) the path %s\n", searchName
);
3880 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3885 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3887 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
3888 PATH_MAX
, nls_codepage
, remap
);
3889 name_len
++; /* trailing null */
3892 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
3895 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
3896 pSMB
->TotalDataCount
= 0;
3897 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3898 /* BB find exact max SMB PDU from sess structure BB */
3899 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3900 pSMB
->MaxSetupCount
= 0;
3904 pSMB
->Reserved2
= 0;
3905 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3906 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3907 pSMB
->DataCount
= 0;
3908 pSMB
->DataOffset
= 0;
3909 pSMB
->SetupCount
= 1;
3910 pSMB
->Reserved3
= 0;
3911 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3912 byte_count
= params
+ 1 /* pad */ ;
3913 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3914 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3915 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
3916 pSMB
->Reserved4
= 0;
3917 inc_rfc1001_len(pSMB
, byte_count
);
3918 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3920 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3921 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3923 cifs_dbg(FYI
, "Send error in UnixQPathInfo = %d\n", rc
);
3924 } else { /* decode response */
3925 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3927 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
3928 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3929 rc
= -EIO
; /* bad smb */
3931 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3932 memcpy((char *) pFindData
,
3933 (char *) &pSMBr
->hdr
.Protocol
+
3935 sizeof(FILE_UNIX_BASIC_INFO
));
3938 cifs_buf_release(pSMB
);
3940 goto UnixQPathInfoRetry
;
3945 /* xid, tcon, searchName and codepage are input parms, rest are returned */
3947 CIFSFindFirst(const unsigned int xid
, struct cifs_tcon
*tcon
,
3948 const char *searchName
, struct cifs_sb_info
*cifs_sb
,
3949 __u16
*pnetfid
, __u16 search_flags
,
3950 struct cifs_search_info
*psrch_inf
, bool msearch
)
3952 /* level 257 SMB_ */
3953 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
3954 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
3955 T2_FFIRST_RSP_PARMS
*parms
;
3957 int bytes_returned
= 0;
3958 int name_len
, remap
;
3959 __u16 params
, byte_count
;
3960 struct nls_table
*nls_codepage
;
3962 cifs_dbg(FYI
, "In FindFirst for %s\n", searchName
);
3965 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3970 nls_codepage
= cifs_sb
->local_nls
;
3971 remap
= cifs_remap(cifs_sb
);
3973 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3975 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
3976 PATH_MAX
, nls_codepage
, remap
);
3977 /* We can not add the asterik earlier in case
3978 it got remapped to 0xF03A as if it were part of the
3979 directory name instead of a wildcard */
3982 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
3983 pSMB
->FileName
[name_len
+1] = 0;
3984 pSMB
->FileName
[name_len
+2] = '*';
3985 pSMB
->FileName
[name_len
+3] = 0;
3986 name_len
+= 4; /* now the trailing null */
3987 /* null terminate just in case */
3988 pSMB
->FileName
[name_len
] = 0;
3989 pSMB
->FileName
[name_len
+1] = 0;
3993 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
3995 if (WARN_ON_ONCE(name_len
> PATH_MAX
-2))
3996 name_len
= PATH_MAX
-2;
3997 /* overwrite nul byte */
3998 pSMB
->FileName
[name_len
-1] = CIFS_DIR_SEP(cifs_sb
);
3999 pSMB
->FileName
[name_len
] = '*';
4000 pSMB
->FileName
[name_len
+1] = 0;
4005 params
= 12 + name_len
/* includes null */ ;
4006 pSMB
->TotalDataCount
= 0; /* no EAs */
4007 pSMB
->MaxParameterCount
= cpu_to_le16(10);
4008 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4009 pSMB
->MaxSetupCount
= 0;
4013 pSMB
->Reserved2
= 0;
4014 byte_count
= params
+ 1 /* pad */ ;
4015 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4016 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4017 pSMB
->ParameterOffset
= cpu_to_le16(
4018 offsetof(struct smb_com_transaction2_ffirst_req
, SearchAttributes
)
4020 pSMB
->DataCount
= 0;
4021 pSMB
->DataOffset
= 0;
4022 pSMB
->SetupCount
= 1; /* one byte, no need to make endian neutral */
4023 pSMB
->Reserved3
= 0;
4024 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
4025 pSMB
->SearchAttributes
=
4026 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
4028 pSMB
->SearchCount
= cpu_to_le16(CIFSMaxBufSize
/sizeof(FILE_UNIX_INFO
));
4029 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4030 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4032 /* BB what should we set StorageType to? Does it matter? BB */
4033 pSMB
->SearchStorageType
= 0;
4034 inc_rfc1001_len(pSMB
, byte_count
);
4035 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4037 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4038 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4039 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_ffirst
);
4041 if (rc
) {/* BB add logic to retry regular search if Unix search
4042 rejected unexpectedly by server */
4043 /* BB Add code to handle unsupported level rc */
4044 cifs_dbg(FYI
, "Error in FindFirst = %d\n", rc
);
4046 cifs_buf_release(pSMB
);
4048 /* BB eventually could optimize out free and realloc of buf */
4051 goto findFirstRetry
;
4052 } else { /* decode response */
4053 /* BB remember to free buffer if error BB */
4054 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4058 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4059 psrch_inf
->unicode
= true;
4061 psrch_inf
->unicode
= false;
4063 psrch_inf
->ntwrk_buf_start
= (char *)pSMBr
;
4064 psrch_inf
->smallBuf
= false;
4065 psrch_inf
->srch_entries_start
=
4066 (char *) &pSMBr
->hdr
.Protocol
+
4067 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4068 parms
= (T2_FFIRST_RSP_PARMS
*)((char *) &pSMBr
->hdr
.Protocol
+
4069 le16_to_cpu(pSMBr
->t2
.ParameterOffset
));
4071 if (parms
->EndofSearch
)
4072 psrch_inf
->endOfSearch
= true;
4074 psrch_inf
->endOfSearch
= false;
4076 psrch_inf
->entries_in_buffer
=
4077 le16_to_cpu(parms
->SearchCount
);
4078 psrch_inf
->index_of_last_entry
= 2 /* skip . and .. */ +
4079 psrch_inf
->entries_in_buffer
;
4080 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4081 if (CIFSMaxBufSize
< lnoff
) {
4082 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4083 psrch_inf
->last_entry
= NULL
;
4087 psrch_inf
->last_entry
= psrch_inf
->srch_entries_start
+
4091 *pnetfid
= parms
->SearchHandle
;
4093 cifs_buf_release(pSMB
);
4100 int CIFSFindNext(const unsigned int xid
, struct cifs_tcon
*tcon
,
4101 __u16 searchHandle
, __u16 search_flags
,
4102 struct cifs_search_info
*psrch_inf
)
4104 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
4105 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
4106 T2_FNEXT_RSP_PARMS
*parms
;
4107 char *response_data
;
4110 unsigned int name_len
;
4111 __u16 params
, byte_count
;
4113 cifs_dbg(FYI
, "In FindNext\n");
4115 if (psrch_inf
->endOfSearch
)
4118 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4123 params
= 14; /* includes 2 bytes of null string, converted to LE below*/
4125 pSMB
->TotalDataCount
= 0; /* no EAs */
4126 pSMB
->MaxParameterCount
= cpu_to_le16(8);
4127 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4128 pSMB
->MaxSetupCount
= 0;
4132 pSMB
->Reserved2
= 0;
4133 pSMB
->ParameterOffset
= cpu_to_le16(
4134 offsetof(struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
4135 pSMB
->DataCount
= 0;
4136 pSMB
->DataOffset
= 0;
4137 pSMB
->SetupCount
= 1;
4138 pSMB
->Reserved3
= 0;
4139 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
4140 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
4142 cpu_to_le16(CIFSMaxBufSize
/ sizeof(FILE_UNIX_INFO
));
4143 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4144 pSMB
->ResumeKey
= psrch_inf
->resume_key
;
4145 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4147 name_len
= psrch_inf
->resume_name_len
;
4149 if (name_len
< PATH_MAX
) {
4150 memcpy(pSMB
->ResumeFileName
, psrch_inf
->presume_name
, name_len
);
4151 byte_count
+= name_len
;
4152 /* 14 byte parm len above enough for 2 byte null terminator */
4153 pSMB
->ResumeFileName
[name_len
] = 0;
4154 pSMB
->ResumeFileName
[name_len
+1] = 0;
4157 goto FNext2_err_exit
;
4159 byte_count
= params
+ 1 /* pad */ ;
4160 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4161 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4162 inc_rfc1001_len(pSMB
, byte_count
);
4163 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4165 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4166 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4167 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fnext
);
4170 psrch_inf
->endOfSearch
= true;
4171 cifs_buf_release(pSMB
);
4172 rc
= 0; /* search probably was closed at end of search*/
4174 cifs_dbg(FYI
, "FindNext returned = %d\n", rc
);
4175 } else { /* decode response */
4176 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4181 /* BB fixme add lock for file (srch_info) struct here */
4182 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4183 psrch_inf
->unicode
= true;
4185 psrch_inf
->unicode
= false;
4186 response_data
= (char *) &pSMBr
->hdr
.Protocol
+
4187 le16_to_cpu(pSMBr
->t2
.ParameterOffset
);
4188 parms
= (T2_FNEXT_RSP_PARMS
*)response_data
;
4189 response_data
= (char *)&pSMBr
->hdr
.Protocol
+
4190 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4191 if (psrch_inf
->smallBuf
)
4192 cifs_small_buf_release(
4193 psrch_inf
->ntwrk_buf_start
);
4195 cifs_buf_release(psrch_inf
->ntwrk_buf_start
);
4196 psrch_inf
->srch_entries_start
= response_data
;
4197 psrch_inf
->ntwrk_buf_start
= (char *)pSMB
;
4198 psrch_inf
->smallBuf
= false;
4199 if (parms
->EndofSearch
)
4200 psrch_inf
->endOfSearch
= true;
4202 psrch_inf
->endOfSearch
= false;
4203 psrch_inf
->entries_in_buffer
=
4204 le16_to_cpu(parms
->SearchCount
);
4205 psrch_inf
->index_of_last_entry
+=
4206 psrch_inf
->entries_in_buffer
;
4207 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4208 if (CIFSMaxBufSize
< lnoff
) {
4209 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4210 psrch_inf
->last_entry
= NULL
;
4213 psrch_inf
->last_entry
=
4214 psrch_inf
->srch_entries_start
+ lnoff
;
4216 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4217 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4219 /* BB fixme add unlock here */
4224 /* BB On error, should we leave previous search buf (and count and
4225 last entry fields) intact or free the previous one? */
4227 /* Note: On -EAGAIN error only caller can retry on handle based calls
4228 since file handle passed in no longer valid */
4231 cifs_buf_release(pSMB
);
4236 CIFSFindClose(const unsigned int xid
, struct cifs_tcon
*tcon
,
4237 const __u16 searchHandle
)
4240 FINDCLOSE_REQ
*pSMB
= NULL
;
4242 cifs_dbg(FYI
, "In CIFSSMBFindClose\n");
4243 rc
= small_smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **)&pSMB
);
4245 /* no sense returning error if session restarted
4246 as file handle has been closed */
4252 pSMB
->FileID
= searchHandle
;
4253 pSMB
->ByteCount
= 0;
4254 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
4255 cifs_small_buf_release(pSMB
);
4257 cifs_dbg(VFS
, "Send error in FindClose = %d\n", rc
);
4259 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fclose
);
4261 /* Since session is dead, search handle closed on server already */
4269 CIFSGetSrvInodeNumber(const unsigned int xid
, struct cifs_tcon
*tcon
,
4270 const char *search_name
, __u64
*inode_number
,
4271 const struct nls_table
*nls_codepage
, int remap
)
4274 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4275 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4276 int name_len
, bytes_returned
;
4277 __u16 params
, byte_count
;
4279 cifs_dbg(FYI
, "In GetSrvInodeNum for %s\n", search_name
);
4283 GetInodeNumberRetry
:
4284 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4289 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4291 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4292 search_name
, PATH_MAX
, nls_codepage
,
4294 name_len
++; /* trailing null */
4297 name_len
= copy_path_name(pSMB
->FileName
, search_name
);
4300 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
4301 pSMB
->TotalDataCount
= 0;
4302 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4303 /* BB find exact max data count below from sess structure BB */
4304 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4305 pSMB
->MaxSetupCount
= 0;
4309 pSMB
->Reserved2
= 0;
4310 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4311 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4312 pSMB
->DataCount
= 0;
4313 pSMB
->DataOffset
= 0;
4314 pSMB
->SetupCount
= 1;
4315 pSMB
->Reserved3
= 0;
4316 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4317 byte_count
= params
+ 1 /* pad */ ;
4318 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4319 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4320 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO
);
4321 pSMB
->Reserved4
= 0;
4322 inc_rfc1001_len(pSMB
, byte_count
);
4323 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4325 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4326 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4328 cifs_dbg(FYI
, "error %d in QueryInternalInfo\n", rc
);
4330 /* decode response */
4331 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4332 /* BB also check enough total bytes returned */
4333 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
4334 /* If rc should we check for EOPNOSUPP and
4335 disable the srvino flag? or in caller? */
4336 rc
= -EIO
; /* bad smb */
4338 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4339 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
4340 struct file_internal_info
*pfinfo
;
4341 /* BB Do we need a cast or hash here ? */
4343 cifs_dbg(FYI
, "Invalid size ret in QryIntrnlInf\n");
4345 goto GetInodeNumOut
;
4347 pfinfo
= (struct file_internal_info
*)
4348 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
4349 *inode_number
= le64_to_cpu(pfinfo
->UniqueId
);
4353 cifs_buf_release(pSMB
);
4355 goto GetInodeNumberRetry
;
4360 CIFSGetDFSRefer(const unsigned int xid
, struct cifs_ses
*ses
,
4361 const char *search_name
, struct dfs_info3_param
**target_nodes
,
4362 unsigned int *num_of_nodes
,
4363 const struct nls_table
*nls_codepage
, int remap
)
4365 /* TRANS2_GET_DFS_REFERRAL */
4366 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
4367 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
4371 __u16 params
, byte_count
;
4373 *target_nodes
= NULL
;
4375 cifs_dbg(FYI
, "In GetDFSRefer the path %s\n", search_name
);
4376 if (ses
== NULL
|| ses
->tcon_ipc
== NULL
)
4380 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, ses
->tcon_ipc
, (void **) &pSMB
,
4385 /* server pointer checked in called function,
4386 but should never be null here anyway */
4387 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
4388 pSMB
->hdr
.Tid
= ses
->tcon_ipc
->tid
;
4389 pSMB
->hdr
.Uid
= ses
->Suid
;
4390 if (ses
->capabilities
& CAP_STATUS32
)
4391 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
4392 if (ses
->capabilities
& CAP_DFS
)
4393 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
4395 if (ses
->capabilities
& CAP_UNICODE
) {
4396 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
4398 cifsConvertToUTF16((__le16
*) pSMB
->RequestFileName
,
4399 search_name
, PATH_MAX
, nls_codepage
,
4401 name_len
++; /* trailing null */
4403 } else { /* BB improve the check for buffer overruns BB */
4404 name_len
= copy_path_name(pSMB
->RequestFileName
, search_name
);
4407 if (ses
->server
->sign
)
4408 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
4410 pSMB
->hdr
.Uid
= ses
->Suid
;
4412 params
= 2 /* level */ + name_len
/*includes null */ ;
4413 pSMB
->TotalDataCount
= 0;
4414 pSMB
->DataCount
= 0;
4415 pSMB
->DataOffset
= 0;
4416 pSMB
->MaxParameterCount
= 0;
4417 /* BB find exact max SMB PDU from sess structure BB */
4418 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4419 pSMB
->MaxSetupCount
= 0;
4423 pSMB
->Reserved2
= 0;
4424 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4425 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
4426 pSMB
->SetupCount
= 1;
4427 pSMB
->Reserved3
= 0;
4428 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
4429 byte_count
= params
+ 3 /* pad */ ;
4430 pSMB
->ParameterCount
= cpu_to_le16(params
);
4431 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4432 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
4433 inc_rfc1001_len(pSMB
, byte_count
);
4434 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4436 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
4437 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4439 cifs_dbg(FYI
, "Send error in GetDFSRefer = %d\n", rc
);
4442 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4444 /* BB Also check if enough total bytes returned? */
4445 if (rc
|| get_bcc(&pSMBr
->hdr
) < 17) {
4446 rc
= -EIO
; /* bad smb */
4450 cifs_dbg(FYI
, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4451 get_bcc(&pSMBr
->hdr
), le16_to_cpu(pSMBr
->t2
.DataOffset
));
4453 /* parse returned result into more usable form */
4454 rc
= parse_dfs_referrals(&pSMBr
->dfs_data
,
4455 le16_to_cpu(pSMBr
->t2
.DataCount
),
4456 num_of_nodes
, target_nodes
, nls_codepage
,
4458 (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) != 0);
4461 cifs_buf_release(pSMB
);
4469 /* Query File System Info such as free space to old servers such as Win 9x */
4471 SMBOldQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4472 struct kstatfs
*FSData
)
4474 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4475 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4476 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4477 FILE_SYSTEM_ALLOC_INFO
*response_data
;
4479 int bytes_returned
= 0;
4480 __u16 params
, byte_count
;
4482 cifs_dbg(FYI
, "OldQFSInfo\n");
4484 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4489 params
= 2; /* level */
4490 pSMB
->TotalDataCount
= 0;
4491 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4492 pSMB
->MaxDataCount
= cpu_to_le16(1000);
4493 pSMB
->MaxSetupCount
= 0;
4497 pSMB
->Reserved2
= 0;
4498 byte_count
= params
+ 1 /* pad */ ;
4499 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4500 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4501 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4502 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
4503 pSMB
->DataCount
= 0;
4504 pSMB
->DataOffset
= 0;
4505 pSMB
->SetupCount
= 1;
4506 pSMB
->Reserved3
= 0;
4507 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
4508 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_ALLOCATION
);
4509 inc_rfc1001_len(pSMB
, byte_count
);
4510 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4512 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4513 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4515 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
4516 } else { /* decode response */
4517 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4519 if (rc
|| get_bcc(&pSMBr
->hdr
) < 18)
4520 rc
= -EIO
; /* bad smb */
4522 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4523 cifs_dbg(FYI
, "qfsinf resp BCC: %d Offset %d\n",
4524 get_bcc(&pSMBr
->hdr
), data_offset
);
4526 response_data
= (FILE_SYSTEM_ALLOC_INFO
*)
4527 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
4529 le16_to_cpu(response_data
->BytesPerSector
) *
4530 le32_to_cpu(response_data
->
4531 SectorsPerAllocationUnit
);
4533 * much prefer larger but if server doesn't report
4534 * a valid size than 4K is a reasonable minimum
4536 if (FSData
->f_bsize
< 512)
4537 FSData
->f_bsize
= 4096;
4540 le32_to_cpu(response_data
->TotalAllocationUnits
);
4541 FSData
->f_bfree
= FSData
->f_bavail
=
4542 le32_to_cpu(response_data
->FreeAllocationUnits
);
4543 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
4544 (unsigned long long)FSData
->f_blocks
,
4545 (unsigned long long)FSData
->f_bfree
,
4549 cifs_buf_release(pSMB
);
4552 goto oldQFSInfoRetry
;
4558 CIFSSMBQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4559 struct kstatfs
*FSData
)
4561 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4562 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4563 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4564 FILE_SYSTEM_INFO
*response_data
;
4566 int bytes_returned
= 0;
4567 __u16 params
, byte_count
;
4569 cifs_dbg(FYI
, "In QFSInfo\n");
4571 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4576 params
= 2; /* level */
4577 pSMB
->TotalDataCount
= 0;
4578 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4579 pSMB
->MaxDataCount
= cpu_to_le16(1000);
4580 pSMB
->MaxSetupCount
= 0;
4584 pSMB
->Reserved2
= 0;
4585 byte_count
= params
+ 1 /* pad */ ;
4586 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4587 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4588 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4589 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
4590 pSMB
->DataCount
= 0;
4591 pSMB
->DataOffset
= 0;
4592 pSMB
->SetupCount
= 1;
4593 pSMB
->Reserved3
= 0;
4594 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
4595 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
4596 inc_rfc1001_len(pSMB
, byte_count
);
4597 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4599 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4600 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4602 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
4603 } else { /* decode response */
4604 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4606 if (rc
|| get_bcc(&pSMBr
->hdr
) < 24)
4607 rc
= -EIO
; /* bad smb */
4609 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4613 *) (((char *) &pSMBr
->hdr
.Protocol
) +
4616 le32_to_cpu(response_data
->BytesPerSector
) *
4617 le32_to_cpu(response_data
->
4618 SectorsPerAllocationUnit
);
4620 * much prefer larger but if server doesn't report
4621 * a valid size than 4K is a reasonable minimum
4623 if (FSData
->f_bsize
< 512)
4624 FSData
->f_bsize
= 4096;
4627 le64_to_cpu(response_data
->TotalAllocationUnits
);
4628 FSData
->f_bfree
= FSData
->f_bavail
=
4629 le64_to_cpu(response_data
->FreeAllocationUnits
);
4630 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
4631 (unsigned long long)FSData
->f_blocks
,
4632 (unsigned long long)FSData
->f_bfree
,
4636 cifs_buf_release(pSMB
);
4645 CIFSSMBQFSAttributeInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
4647 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
4648 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4649 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4650 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
4652 int bytes_returned
= 0;
4653 __u16 params
, byte_count
;
4655 cifs_dbg(FYI
, "In QFSAttributeInfo\n");
4657 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4662 params
= 2; /* level */
4663 pSMB
->TotalDataCount
= 0;
4664 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4665 /* BB find exact max SMB PDU from sess structure BB */
4666 pSMB
->MaxDataCount
= cpu_to_le16(1000);
4667 pSMB
->MaxSetupCount
= 0;
4671 pSMB
->Reserved2
= 0;
4672 byte_count
= params
+ 1 /* pad */ ;
4673 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4674 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4675 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4676 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
4677 pSMB
->DataCount
= 0;
4678 pSMB
->DataOffset
= 0;
4679 pSMB
->SetupCount
= 1;
4680 pSMB
->Reserved3
= 0;
4681 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
4682 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
4683 inc_rfc1001_len(pSMB
, byte_count
);
4684 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4686 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4687 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4689 cifs_dbg(VFS
, "Send error in QFSAttributeInfo = %d\n", rc
);
4690 } else { /* decode response */
4691 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4693 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
4694 /* BB also check if enough bytes returned */
4695 rc
= -EIO
; /* bad smb */
4697 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4699 (FILE_SYSTEM_ATTRIBUTE_INFO
4700 *) (((char *) &pSMBr
->hdr
.Protocol
) +
4702 memcpy(&tcon
->fsAttrInfo
, response_data
,
4703 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO
));
4706 cifs_buf_release(pSMB
);
4709 goto QFSAttributeRetry
;
4715 CIFSSMBQFSDeviceInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
4717 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
4718 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4719 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4720 FILE_SYSTEM_DEVICE_INFO
*response_data
;
4722 int bytes_returned
= 0;
4723 __u16 params
, byte_count
;
4725 cifs_dbg(FYI
, "In QFSDeviceInfo\n");
4727 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4732 params
= 2; /* level */
4733 pSMB
->TotalDataCount
= 0;
4734 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4735 /* BB find exact max SMB PDU from sess structure BB */
4736 pSMB
->MaxDataCount
= cpu_to_le16(1000);
4737 pSMB
->MaxSetupCount
= 0;
4741 pSMB
->Reserved2
= 0;
4742 byte_count
= params
+ 1 /* pad */ ;
4743 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4744 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4745 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4746 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
4748 pSMB
->DataCount
= 0;
4749 pSMB
->DataOffset
= 0;
4750 pSMB
->SetupCount
= 1;
4751 pSMB
->Reserved3
= 0;
4752 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
4753 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
4754 inc_rfc1001_len(pSMB
, byte_count
);
4755 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4757 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4758 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4760 cifs_dbg(FYI
, "Send error in QFSDeviceInfo = %d\n", rc
);
4761 } else { /* decode response */
4762 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4764 if (rc
|| get_bcc(&pSMBr
->hdr
) <
4765 sizeof(FILE_SYSTEM_DEVICE_INFO
))
4766 rc
= -EIO
; /* bad smb */
4768 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4770 (FILE_SYSTEM_DEVICE_INFO
*)
4771 (((char *) &pSMBr
->hdr
.Protocol
) +
4773 memcpy(&tcon
->fsDevInfo
, response_data
,
4774 sizeof(FILE_SYSTEM_DEVICE_INFO
));
4777 cifs_buf_release(pSMB
);
4780 goto QFSDeviceRetry
;
4786 CIFSSMBQFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
4788 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
4789 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4790 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4791 FILE_SYSTEM_UNIX_INFO
*response_data
;
4793 int bytes_returned
= 0;
4794 __u16 params
, byte_count
;
4796 cifs_dbg(FYI
, "In QFSUnixInfo\n");
4798 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
4799 (void **) &pSMB
, (void **) &pSMBr
);
4803 params
= 2; /* level */
4804 pSMB
->TotalDataCount
= 0;
4805 pSMB
->DataCount
= 0;
4806 pSMB
->DataOffset
= 0;
4807 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4808 /* BB find exact max SMB PDU from sess structure BB */
4809 pSMB
->MaxDataCount
= cpu_to_le16(100);
4810 pSMB
->MaxSetupCount
= 0;
4814 pSMB
->Reserved2
= 0;
4815 byte_count
= params
+ 1 /* pad */ ;
4816 pSMB
->ParameterCount
= cpu_to_le16(params
);
4817 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4818 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
4819 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
4820 pSMB
->SetupCount
= 1;
4821 pSMB
->Reserved3
= 0;
4822 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
4823 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
4824 inc_rfc1001_len(pSMB
, byte_count
);
4825 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4827 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4828 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4830 cifs_dbg(VFS
, "Send error in QFSUnixInfo = %d\n", rc
);
4831 } else { /* decode response */
4832 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4834 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
4835 rc
= -EIO
; /* bad smb */
4837 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4839 (FILE_SYSTEM_UNIX_INFO
4840 *) (((char *) &pSMBr
->hdr
.Protocol
) +
4842 memcpy(&tcon
->fsUnixInfo
, response_data
,
4843 sizeof(FILE_SYSTEM_UNIX_INFO
));
4846 cifs_buf_release(pSMB
);
4856 CIFSSMBSetFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
, __u64 cap
)
4858 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
4859 TRANSACTION2_SETFSI_REQ
*pSMB
= NULL
;
4860 TRANSACTION2_SETFSI_RSP
*pSMBr
= NULL
;
4862 int bytes_returned
= 0;
4863 __u16 params
, param_offset
, offset
, byte_count
;
4865 cifs_dbg(FYI
, "In SETFSUnixInfo\n");
4867 /* BB switch to small buf init to save memory */
4868 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
4869 (void **) &pSMB
, (void **) &pSMBr
);
4873 params
= 4; /* 2 bytes zero followed by info level. */
4874 pSMB
->MaxSetupCount
= 0;
4878 pSMB
->Reserved2
= 0;
4879 param_offset
= offsetof(struct smb_com_transaction2_setfsi_req
, FileNum
)
4881 offset
= param_offset
+ params
;
4883 pSMB
->MaxParameterCount
= cpu_to_le16(4);
4884 /* BB find exact max SMB PDU from sess structure BB */
4885 pSMB
->MaxDataCount
= cpu_to_le16(100);
4886 pSMB
->SetupCount
= 1;
4887 pSMB
->Reserved3
= 0;
4888 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FS_INFORMATION
);
4889 byte_count
= 1 /* pad */ + params
+ 12;
4891 pSMB
->DataCount
= cpu_to_le16(12);
4892 pSMB
->ParameterCount
= cpu_to_le16(params
);
4893 pSMB
->TotalDataCount
= pSMB
->DataCount
;
4894 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4895 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
4896 pSMB
->DataOffset
= cpu_to_le16(offset
);
4900 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_CIFS_UNIX_INFO
);
4903 pSMB
->ClientUnixMajor
= cpu_to_le16(CIFS_UNIX_MAJOR_VERSION
);
4904 pSMB
->ClientUnixMinor
= cpu_to_le16(CIFS_UNIX_MINOR_VERSION
);
4905 pSMB
->ClientUnixCap
= cpu_to_le64(cap
);
4907 inc_rfc1001_len(pSMB
, byte_count
);
4908 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4910 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4911 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4913 cifs_dbg(VFS
, "Send error in SETFSUnixInfo = %d\n", rc
);
4914 } else { /* decode response */
4915 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4917 rc
= -EIO
; /* bad smb */
4919 cifs_buf_release(pSMB
);
4922 goto SETFSUnixRetry
;
4930 CIFSSMBQFSPosixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4931 struct kstatfs
*FSData
)
4933 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
4934 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4935 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4936 FILE_SYSTEM_POSIX_INFO
*response_data
;
4938 int bytes_returned
= 0;
4939 __u16 params
, byte_count
;
4941 cifs_dbg(FYI
, "In QFSPosixInfo\n");
4943 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4948 params
= 2; /* level */
4949 pSMB
->TotalDataCount
= 0;
4950 pSMB
->DataCount
= 0;
4951 pSMB
->DataOffset
= 0;
4952 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4953 /* BB find exact max SMB PDU from sess structure BB */
4954 pSMB
->MaxDataCount
= cpu_to_le16(100);
4955 pSMB
->MaxSetupCount
= 0;
4959 pSMB
->Reserved2
= 0;
4960 byte_count
= params
+ 1 /* pad */ ;
4961 pSMB
->ParameterCount
= cpu_to_le16(params
);
4962 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4963 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
4964 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
4965 pSMB
->SetupCount
= 1;
4966 pSMB
->Reserved3
= 0;
4967 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
4968 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_FS_INFO
);
4969 inc_rfc1001_len(pSMB
, byte_count
);
4970 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4972 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4973 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4975 cifs_dbg(FYI
, "Send error in QFSUnixInfo = %d\n", rc
);
4976 } else { /* decode response */
4977 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4979 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
4980 rc
= -EIO
; /* bad smb */
4982 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4984 (FILE_SYSTEM_POSIX_INFO
4985 *) (((char *) &pSMBr
->hdr
.Protocol
) +
4988 le32_to_cpu(response_data
->BlockSize
);
4990 * much prefer larger but if server doesn't report
4991 * a valid size than 4K is a reasonable minimum
4993 if (FSData
->f_bsize
< 512)
4994 FSData
->f_bsize
= 4096;
4997 le64_to_cpu(response_data
->TotalBlocks
);
4999 le64_to_cpu(response_data
->BlocksAvail
);
5000 if (response_data
->UserBlocksAvail
== cpu_to_le64(-1)) {
5001 FSData
->f_bavail
= FSData
->f_bfree
;
5004 le64_to_cpu(response_data
->UserBlocksAvail
);
5006 if (response_data
->TotalFileNodes
!= cpu_to_le64(-1))
5008 le64_to_cpu(response_data
->TotalFileNodes
);
5009 if (response_data
->FreeFileNodes
!= cpu_to_le64(-1))
5011 le64_to_cpu(response_data
->FreeFileNodes
);
5014 cifs_buf_release(pSMB
);
5024 * We can not use write of zero bytes trick to set file size due to need for
5025 * large file support. Also note that this SetPathInfo is preferred to
5026 * SetFileInfo based method in next routine which is only needed to work around
5027 * a sharing violation bugin Samba which this routine can run into.
5030 CIFSSMBSetEOF(const unsigned int xid
, struct cifs_tcon
*tcon
,
5031 const char *file_name
, __u64 size
, struct cifs_sb_info
*cifs_sb
,
5032 bool set_allocation
)
5034 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5035 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5036 struct file_end_of_file_info
*parm_data
;
5039 int bytes_returned
= 0;
5040 int remap
= cifs_remap(cifs_sb
);
5042 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
5044 cifs_dbg(FYI
, "In SetEOF\n");
5046 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5051 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5053 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5054 PATH_MAX
, cifs_sb
->local_nls
, remap
);
5055 name_len
++; /* trailing null */
5058 name_len
= copy_path_name(pSMB
->FileName
, file_name
);
5060 params
= 6 + name_len
;
5061 data_count
= sizeof(struct file_end_of_file_info
);
5062 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5063 pSMB
->MaxDataCount
= cpu_to_le16(4100);
5064 pSMB
->MaxSetupCount
= 0;
5068 pSMB
->Reserved2
= 0;
5069 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5070 InformationLevel
) - 4;
5071 offset
= param_offset
+ params
;
5072 if (set_allocation
) {
5073 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5074 pSMB
->InformationLevel
=
5075 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5077 pSMB
->InformationLevel
=
5078 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5079 } else /* Set File Size */ {
5080 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5081 pSMB
->InformationLevel
=
5082 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5084 pSMB
->InformationLevel
=
5085 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5089 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
5091 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5092 pSMB
->DataOffset
= cpu_to_le16(offset
);
5093 pSMB
->SetupCount
= 1;
5094 pSMB
->Reserved3
= 0;
5095 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5096 byte_count
= 3 /* pad */ + params
+ data_count
;
5097 pSMB
->DataCount
= cpu_to_le16(data_count
);
5098 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5099 pSMB
->ParameterCount
= cpu_to_le16(params
);
5100 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5101 pSMB
->Reserved4
= 0;
5102 inc_rfc1001_len(pSMB
, byte_count
);
5103 parm_data
->FileSize
= cpu_to_le64(size
);
5104 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5105 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5106 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5108 cifs_dbg(FYI
, "SetPathInfo (file size) returned %d\n", rc
);
5110 cifs_buf_release(pSMB
);
5119 CIFSSMBSetFileSize(const unsigned int xid
, struct cifs_tcon
*tcon
,
5120 struct cifsFileInfo
*cfile
, __u64 size
, bool set_allocation
)
5122 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5123 struct file_end_of_file_info
*parm_data
;
5125 __u16 params
, param_offset
, offset
, byte_count
, count
;
5127 cifs_dbg(FYI
, "SetFileSize (via SetFileInfo) %lld\n",
5129 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5134 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)cfile
->pid
);
5135 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(cfile
->pid
>> 16));
5138 pSMB
->MaxSetupCount
= 0;
5142 pSMB
->Reserved2
= 0;
5143 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5144 offset
= param_offset
+ params
;
5146 count
= sizeof(struct file_end_of_file_info
);
5147 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5148 /* BB find exact max SMB PDU from sess structure BB */
5149 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5150 pSMB
->SetupCount
= 1;
5151 pSMB
->Reserved3
= 0;
5152 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5153 byte_count
= 3 /* pad */ + params
+ count
;
5154 pSMB
->DataCount
= cpu_to_le16(count
);
5155 pSMB
->ParameterCount
= cpu_to_le16(params
);
5156 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5157 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5158 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5159 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5161 (struct file_end_of_file_info
*)(((char *)pSMB
) + offset
+ 4);
5162 pSMB
->DataOffset
= cpu_to_le16(offset
);
5163 parm_data
->FileSize
= cpu_to_le64(size
);
5164 pSMB
->Fid
= cfile
->fid
.netfid
;
5165 if (set_allocation
) {
5166 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5167 pSMB
->InformationLevel
=
5168 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5170 pSMB
->InformationLevel
=
5171 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5172 } else /* Set File Size */ {
5173 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5174 pSMB
->InformationLevel
=
5175 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5177 pSMB
->InformationLevel
=
5178 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5180 pSMB
->Reserved4
= 0;
5181 inc_rfc1001_len(pSMB
, byte_count
);
5182 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5183 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5184 cifs_small_buf_release(pSMB
);
5186 cifs_dbg(FYI
, "Send error in SetFileInfo (SetFileSize) = %d\n",
5190 /* Note: On -EAGAIN error only caller can retry on handle based calls
5191 since file handle passed in no longer valid */
5196 /* Some legacy servers such as NT4 require that the file times be set on
5197 an open handle, rather than by pathname - this is awkward due to
5198 potential access conflicts on the open, but it is unavoidable for these
5199 old servers since the only other choice is to go from 100 nanosecond DCE
5200 time and resort to the original setpathinfo level which takes the ancient
5201 DOS time format with 2 second granularity */
5203 CIFSSMBSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5204 const FILE_BASIC_INFO
*data
, __u16 fid
, __u32 pid_of_opener
)
5206 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5209 __u16 params
, param_offset
, offset
, byte_count
, count
;
5211 cifs_dbg(FYI
, "Set Times (via SetFileInfo)\n");
5212 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5217 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5218 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5221 pSMB
->MaxSetupCount
= 0;
5225 pSMB
->Reserved2
= 0;
5226 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5227 offset
= param_offset
+ params
;
5229 data_offset
= (char *)pSMB
+
5230 offsetof(struct smb_hdr
, Protocol
) + offset
;
5232 count
= sizeof(FILE_BASIC_INFO
);
5233 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5234 /* BB find max SMB PDU from sess */
5235 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5236 pSMB
->SetupCount
= 1;
5237 pSMB
->Reserved3
= 0;
5238 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5239 byte_count
= 3 /* pad */ + params
+ count
;
5240 pSMB
->DataCount
= cpu_to_le16(count
);
5241 pSMB
->ParameterCount
= cpu_to_le16(params
);
5242 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5243 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5244 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5245 pSMB
->DataOffset
= cpu_to_le16(offset
);
5247 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5248 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5250 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5251 pSMB
->Reserved4
= 0;
5252 inc_rfc1001_len(pSMB
, byte_count
);
5253 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5254 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5255 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5256 cifs_small_buf_release(pSMB
);
5258 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5261 /* Note: On -EAGAIN error only caller can retry on handle based calls
5262 since file handle passed in no longer valid */
5268 CIFSSMBSetFileDisposition(const unsigned int xid
, struct cifs_tcon
*tcon
,
5269 bool delete_file
, __u16 fid
, __u32 pid_of_opener
)
5271 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5274 __u16 params
, param_offset
, offset
, byte_count
, count
;
5276 cifs_dbg(FYI
, "Set File Disposition (via SetFileInfo)\n");
5277 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5282 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5283 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5286 pSMB
->MaxSetupCount
= 0;
5290 pSMB
->Reserved2
= 0;
5291 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5292 offset
= param_offset
+ params
;
5294 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5295 data_offset
= (char *)(pSMB
) + offset
+ 4;
5298 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5299 /* BB find max SMB PDU from sess */
5300 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5301 pSMB
->SetupCount
= 1;
5302 pSMB
->Reserved3
= 0;
5303 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5304 byte_count
= 3 /* pad */ + params
+ count
;
5305 pSMB
->DataCount
= cpu_to_le16(count
);
5306 pSMB
->ParameterCount
= cpu_to_le16(params
);
5307 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5308 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5309 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5310 pSMB
->DataOffset
= cpu_to_le16(offset
);
5312 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO
);
5313 pSMB
->Reserved4
= 0;
5314 inc_rfc1001_len(pSMB
, byte_count
);
5315 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5316 *data_offset
= delete_file
? 1 : 0;
5317 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5318 cifs_small_buf_release(pSMB
);
5320 cifs_dbg(FYI
, "Send error in SetFileDisposition = %d\n", rc
);
5326 CIFSSMBSetPathInfoFB(const unsigned int xid
, struct cifs_tcon
*tcon
,
5327 const char *fileName
, const FILE_BASIC_INFO
*data
,
5328 const struct nls_table
*nls_codepage
,
5329 struct cifs_sb_info
*cifs_sb
)
5332 struct cifs_open_parms oparms
;
5333 struct cifs_fid fid
;
5336 oparms
= (struct cifs_open_parms
) {
5339 .desired_access
= GENERIC_WRITE
,
5340 .create_options
= cifs_create_options(cifs_sb
, 0),
5341 .disposition
= FILE_OPEN
,
5346 rc
= CIFS_open(xid
, &oparms
, &oplock
, NULL
);
5350 rc
= CIFSSMBSetFileInfo(xid
, tcon
, data
, fid
.netfid
, current
->tgid
);
5351 CIFSSMBClose(xid
, tcon
, fid
.netfid
);
5358 CIFSSMBSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5359 const char *fileName
, const FILE_BASIC_INFO
*data
,
5360 const struct nls_table
*nls_codepage
,
5361 struct cifs_sb_info
*cifs_sb
)
5363 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5364 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5367 int bytes_returned
= 0;
5369 __u16 params
, param_offset
, offset
, byte_count
, count
;
5370 int remap
= cifs_remap(cifs_sb
);
5372 cifs_dbg(FYI
, "In SetTimes\n");
5375 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5380 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5382 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5383 PATH_MAX
, nls_codepage
, remap
);
5384 name_len
++; /* trailing null */
5387 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
5390 params
= 6 + name_len
;
5391 count
= sizeof(FILE_BASIC_INFO
);
5392 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5393 /* BB find max SMB PDU from sess structure BB */
5394 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5395 pSMB
->MaxSetupCount
= 0;
5399 pSMB
->Reserved2
= 0;
5400 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5401 InformationLevel
) - 4;
5402 offset
= param_offset
+ params
;
5403 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5404 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5405 pSMB
->DataOffset
= cpu_to_le16(offset
);
5406 pSMB
->SetupCount
= 1;
5407 pSMB
->Reserved3
= 0;
5408 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5409 byte_count
= 3 /* pad */ + params
+ count
;
5411 pSMB
->DataCount
= cpu_to_le16(count
);
5412 pSMB
->ParameterCount
= cpu_to_le16(params
);
5413 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5414 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5415 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5416 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5418 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5419 pSMB
->Reserved4
= 0;
5420 inc_rfc1001_len(pSMB
, byte_count
);
5421 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5422 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5423 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5424 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5426 cifs_dbg(FYI
, "SetPathInfo (times) returned %d\n", rc
);
5428 cifs_buf_release(pSMB
);
5433 if (rc
== -EOPNOTSUPP
)
5434 return CIFSSMBSetPathInfoFB(xid
, tcon
, fileName
, data
,
5435 nls_codepage
, cifs_sb
);
5441 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO
*data_offset
,
5442 const struct cifs_unix_set_info_args
*args
)
5444 u64 uid
= NO_CHANGE_64
, gid
= NO_CHANGE_64
;
5445 u64 mode
= args
->mode
;
5447 if (uid_valid(args
->uid
))
5448 uid
= from_kuid(&init_user_ns
, args
->uid
);
5449 if (gid_valid(args
->gid
))
5450 gid
= from_kgid(&init_user_ns
, args
->gid
);
5453 * Samba server ignores set of file size to zero due to bugs in some
5454 * older clients, but we should be precise - we use SetFileSize to
5455 * set file size and do not want to truncate file size to zero
5456 * accidentally as happened on one Samba server beta by putting
5457 * zero instead of -1 here
5459 data_offset
->EndOfFile
= cpu_to_le64(NO_CHANGE_64
);
5460 data_offset
->NumOfBytes
= cpu_to_le64(NO_CHANGE_64
);
5461 data_offset
->LastStatusChange
= cpu_to_le64(args
->ctime
);
5462 data_offset
->LastAccessTime
= cpu_to_le64(args
->atime
);
5463 data_offset
->LastModificationTime
= cpu_to_le64(args
->mtime
);
5464 data_offset
->Uid
= cpu_to_le64(uid
);
5465 data_offset
->Gid
= cpu_to_le64(gid
);
5466 /* better to leave device as zero when it is */
5467 data_offset
->DevMajor
= cpu_to_le64(MAJOR(args
->device
));
5468 data_offset
->DevMinor
= cpu_to_le64(MINOR(args
->device
));
5469 data_offset
->Permissions
= cpu_to_le64(mode
);
5472 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
5473 else if (S_ISDIR(mode
))
5474 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
5475 else if (S_ISLNK(mode
))
5476 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
5477 else if (S_ISCHR(mode
))
5478 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
5479 else if (S_ISBLK(mode
))
5480 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
5481 else if (S_ISFIFO(mode
))
5482 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
5483 else if (S_ISSOCK(mode
))
5484 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
5488 CIFSSMBUnixSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5489 const struct cifs_unix_set_info_args
*args
,
5490 u16 fid
, u32 pid_of_opener
)
5492 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5495 u16 params
, param_offset
, offset
, byte_count
, count
;
5497 cifs_dbg(FYI
, "Set Unix Info (via SetFileInfo)\n");
5498 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5503 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5504 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5507 pSMB
->MaxSetupCount
= 0;
5511 pSMB
->Reserved2
= 0;
5512 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5513 offset
= param_offset
+ params
;
5515 data_offset
= (char *)pSMB
+
5516 offsetof(struct smb_hdr
, Protocol
) + offset
;
5518 count
= sizeof(FILE_UNIX_BASIC_INFO
);
5520 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5521 /* BB find max SMB PDU from sess */
5522 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5523 pSMB
->SetupCount
= 1;
5524 pSMB
->Reserved3
= 0;
5525 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5526 byte_count
= 3 /* pad */ + params
+ count
;
5527 pSMB
->DataCount
= cpu_to_le16(count
);
5528 pSMB
->ParameterCount
= cpu_to_le16(params
);
5529 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5530 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5531 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5532 pSMB
->DataOffset
= cpu_to_le16(offset
);
5534 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
5535 pSMB
->Reserved4
= 0;
5536 inc_rfc1001_len(pSMB
, byte_count
);
5537 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5539 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO
*)data_offset
, args
);
5541 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5542 cifs_small_buf_release(pSMB
);
5544 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5547 /* Note: On -EAGAIN error only caller can retry on handle based calls
5548 since file handle passed in no longer valid */
5554 CIFSSMBUnixSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5555 const char *file_name
,
5556 const struct cifs_unix_set_info_args
*args
,
5557 const struct nls_table
*nls_codepage
, int remap
)
5559 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5560 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5563 int bytes_returned
= 0;
5564 FILE_UNIX_BASIC_INFO
*data_offset
;
5565 __u16 params
, param_offset
, offset
, count
, byte_count
;
5567 cifs_dbg(FYI
, "In SetUID/GID/Mode\n");
5569 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5574 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5576 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5577 PATH_MAX
, nls_codepage
, remap
);
5578 name_len
++; /* trailing null */
5581 name_len
= copy_path_name(pSMB
->FileName
, file_name
);
5584 params
= 6 + name_len
;
5585 count
= sizeof(FILE_UNIX_BASIC_INFO
);
5586 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5587 /* BB find max SMB PDU from sess structure BB */
5588 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5589 pSMB
->MaxSetupCount
= 0;
5593 pSMB
->Reserved2
= 0;
5594 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5595 InformationLevel
) - 4;
5596 offset
= param_offset
+ params
;
5597 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5598 data_offset
= (FILE_UNIX_BASIC_INFO
*)((char *) pSMB
+ offset
+ 4);
5599 memset(data_offset
, 0, count
);
5600 pSMB
->DataOffset
= cpu_to_le16(offset
);
5601 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5602 pSMB
->SetupCount
= 1;
5603 pSMB
->Reserved3
= 0;
5604 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5605 byte_count
= 3 /* pad */ + params
+ count
;
5606 pSMB
->ParameterCount
= cpu_to_le16(params
);
5607 pSMB
->DataCount
= cpu_to_le16(count
);
5608 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5609 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5610 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
5611 pSMB
->Reserved4
= 0;
5612 inc_rfc1001_len(pSMB
, byte_count
);
5614 cifs_fill_unix_set_info(data_offset
, args
);
5616 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5617 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5618 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5620 cifs_dbg(FYI
, "SetPathInfo (perms) returned %d\n", rc
);
5622 cifs_buf_release(pSMB
);
5628 #ifdef CONFIG_CIFS_XATTR
5630 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
5631 * function used by listxattr and getxattr type calls. When ea_name is set,
5632 * it looks for that attribute name and stuffs that value into the EAData
5633 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
5634 * buffer. In both cases, the return value is either the length of the
5635 * resulting data or a negative error code. If EAData is a NULL pointer then
5636 * the data isn't copied to it, but the length is returned.
5639 CIFSSMBQAllEAs(const unsigned int xid
, struct cifs_tcon
*tcon
,
5640 const unsigned char *searchName
, const unsigned char *ea_name
,
5641 char *EAData
, size_t buf_size
,
5642 struct cifs_sb_info
*cifs_sb
)
5644 /* BB assumes one setup word */
5645 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
5646 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
5647 int remap
= cifs_remap(cifs_sb
);
5648 struct nls_table
*nls_codepage
= cifs_sb
->local_nls
;
5652 struct fealist
*ea_response_data
;
5653 struct fea
*temp_fea
;
5656 __u16 params
, byte_count
, data_offset
;
5657 unsigned int ea_name_len
= ea_name
? strlen(ea_name
) : 0;
5659 cifs_dbg(FYI
, "In Query All EAs path %s\n", searchName
);
5661 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5666 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5668 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
5669 PATH_MAX
, nls_codepage
, remap
);
5670 list_len
++; /* trailing null */
5673 list_len
= copy_path_name(pSMB
->FileName
, searchName
);
5676 params
= 2 /* level */ + 4 /* reserved */ + list_len
/* includes NUL */;
5677 pSMB
->TotalDataCount
= 0;
5678 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5679 /* BB find exact max SMB PDU from sess structure BB */
5680 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
5681 pSMB
->MaxSetupCount
= 0;
5685 pSMB
->Reserved2
= 0;
5686 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5687 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
5688 pSMB
->DataCount
= 0;
5689 pSMB
->DataOffset
= 0;
5690 pSMB
->SetupCount
= 1;
5691 pSMB
->Reserved3
= 0;
5692 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
5693 byte_count
= params
+ 1 /* pad */ ;
5694 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5695 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5696 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
5697 pSMB
->Reserved4
= 0;
5698 inc_rfc1001_len(pSMB
, byte_count
);
5699 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5701 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5702 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5704 cifs_dbg(FYI
, "Send error in QueryAllEAs = %d\n", rc
);
5709 /* BB also check enough total bytes returned */
5710 /* BB we need to improve the validity checking
5711 of these trans2 responses */
5713 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5714 if (rc
|| get_bcc(&pSMBr
->hdr
) < 4) {
5715 rc
= -EIO
; /* bad smb */
5719 /* check that length of list is not more than bcc */
5720 /* check that each entry does not go beyond length
5722 /* check that each element of each entry does not
5723 go beyond end of list */
5724 /* validate_trans2_offsets() */
5725 /* BB check if start of smb + data_offset > &bcc+ bcc */
5727 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5728 ea_response_data
= (struct fealist
*)
5729 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
5731 list_len
= le32_to_cpu(ea_response_data
->list_len
);
5732 cifs_dbg(FYI
, "ea length %d\n", list_len
);
5733 if (list_len
<= 8) {
5734 cifs_dbg(FYI
, "empty EA list returned from server\n");
5735 /* didn't find the named attribute */
5741 /* make sure list_len doesn't go past end of SMB */
5742 end_of_smb
= (char *)pByteArea(&pSMBr
->hdr
) + get_bcc(&pSMBr
->hdr
);
5743 if ((char *)ea_response_data
+ list_len
> end_of_smb
) {
5744 cifs_dbg(FYI
, "EA list appears to go beyond SMB\n");
5749 /* account for ea list len */
5751 temp_fea
= ea_response_data
->list
;
5752 temp_ptr
= (char *)temp_fea
;
5753 while (list_len
> 0) {
5754 unsigned int name_len
;
5759 /* make sure we can read name_len and value_len */
5761 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
5766 name_len
= temp_fea
->name_len
;
5767 value_len
= le16_to_cpu(temp_fea
->value_len
);
5768 list_len
-= name_len
+ 1 + value_len
;
5770 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
5776 if (ea_name_len
== name_len
&&
5777 memcmp(ea_name
, temp_ptr
, name_len
) == 0) {
5778 temp_ptr
+= name_len
+ 1;
5782 if ((size_t)value_len
> buf_size
) {
5786 memcpy(EAData
, temp_ptr
, value_len
);
5790 /* account for prefix user. and trailing null */
5791 rc
+= (5 + 1 + name_len
);
5792 if (rc
< (int) buf_size
) {
5793 memcpy(EAData
, "user.", 5);
5795 memcpy(EAData
, temp_ptr
, name_len
);
5797 /* null terminate name */
5800 } else if (buf_size
== 0) {
5801 /* skip copy - calc size only */
5803 /* stop before overrun buffer */
5808 temp_ptr
+= name_len
+ 1 + value_len
;
5809 temp_fea
= (struct fea
*)temp_ptr
;
5812 /* didn't find the named attribute */
5817 cifs_buf_release(pSMB
);
5825 CIFSSMBSetEA(const unsigned int xid
, struct cifs_tcon
*tcon
,
5826 const char *fileName
, const char *ea_name
, const void *ea_value
,
5827 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
,
5828 struct cifs_sb_info
*cifs_sb
)
5830 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5831 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5832 struct fealist
*parm_data
;
5835 int bytes_returned
= 0;
5836 __u16 params
, param_offset
, byte_count
, offset
, count
;
5837 int remap
= cifs_remap(cifs_sb
);
5839 cifs_dbg(FYI
, "In SetEA\n");
5841 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5846 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5848 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5849 PATH_MAX
, nls_codepage
, remap
);
5850 name_len
++; /* trailing null */
5853 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
5856 params
= 6 + name_len
;
5858 /* done calculating parms using name_len of file name,
5859 now use name_len to calculate length of ea name
5860 we are going to create in the inode xattrs */
5861 if (ea_name
== NULL
)
5864 name_len
= strnlen(ea_name
, 255);
5866 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
;
5867 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5868 /* BB find max SMB PDU from sess */
5869 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5870 pSMB
->MaxSetupCount
= 0;
5874 pSMB
->Reserved2
= 0;
5875 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5876 InformationLevel
) - 4;
5877 offset
= param_offset
+ params
;
5878 pSMB
->InformationLevel
=
5879 cpu_to_le16(SMB_SET_FILE_EA
);
5881 parm_data
= (void *)pSMB
+ offsetof(struct smb_hdr
, Protocol
) + offset
;
5882 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5883 pSMB
->DataOffset
= cpu_to_le16(offset
);
5884 pSMB
->SetupCount
= 1;
5885 pSMB
->Reserved3
= 0;
5886 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5887 byte_count
= 3 /* pad */ + params
+ count
;
5888 pSMB
->DataCount
= cpu_to_le16(count
);
5889 parm_data
->list_len
= cpu_to_le32(count
);
5890 parm_data
->list
[0].EA_flags
= 0;
5891 /* we checked above that name len is less than 255 */
5892 parm_data
->list
[0].name_len
= (__u8
)name_len
;
5893 /* EA names are always ASCII */
5895 strncpy(parm_data
->list
[0].name
, ea_name
, name_len
);
5896 parm_data
->list
[0].name
[name_len
] = 0;
5897 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
5898 /* caller ensures that ea_value_len is less than 64K but
5899 we need to ensure that it fits within the smb */
5901 /*BB add length check to see if it would fit in
5902 negotiated SMB buffer size BB */
5903 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
5905 memcpy(parm_data
->list
[0].name
+name_len
+1,
5906 ea_value
, ea_value_len
);
5908 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5909 pSMB
->ParameterCount
= cpu_to_le16(params
);
5910 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5911 pSMB
->Reserved4
= 0;
5912 inc_rfc1001_len(pSMB
, byte_count
);
5913 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5914 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5915 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5917 cifs_dbg(FYI
, "SetPathInfo (EA) returned %d\n", rc
);
5919 cifs_buf_release(pSMB
);