4 * Copyright (C) International Business Machines Corp., 2002,2010
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Contains the routines for constructing the SMB PDUs themselves
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
25 /* These are mostly routines that operate on a pathname, or on a tree id */
26 /* (mounted volume), but there are eight handle based routines which must be */
27 /* treated slightly differently for reconnection purposes since we never */
28 /* want to reuse a stale file handle and only the caller knows the file info */
31 #include <linux/kernel.h>
32 #include <linux/vfs.h>
33 #include <linux/slab.h>
34 #include <linux/posix_acl_xattr.h>
35 #include <linux/pagemap.h>
36 #include <linux/swap.h>
37 #include <linux/task_io_accounting_ops.h>
38 #include <linux/uaccess.h>
42 #include "cifsproto.h"
43 #include "cifs_unicode.h"
44 #include "cifs_debug.h"
45 #include "smb2proto.h"
47 #include "smbdirect.h"
48 #ifdef CONFIG_CIFS_DFS_UPCALL
49 #include "dfs_cache.h"
52 #ifdef CONFIG_CIFS_POSIX
57 #ifdef CONFIG_CIFS_WEAK_PW_HASH
58 {LANMAN_PROT
, "\2LM1.2X002"},
59 {LANMAN2_PROT
, "\2LANMAN2.1"},
60 #endif /* weak password hashing for legacy clients */
61 {CIFS_PROT
, "\2NT LM 0.12"},
62 {POSIX_PROT
, "\2POSIX 2"},
70 #ifdef CONFIG_CIFS_WEAK_PW_HASH
71 {LANMAN_PROT
, "\2LM1.2X002"},
72 {LANMAN2_PROT
, "\2LANMAN2.1"},
73 #endif /* weak password hashing for legacy clients */
74 {CIFS_PROT
, "\2NT LM 0.12"},
79 /* define the number of elements in the cifs dialect array */
80 #ifdef CONFIG_CIFS_POSIX
81 #ifdef CONFIG_CIFS_WEAK_PW_HASH
82 #define CIFS_NUM_PROT 4
84 #define CIFS_NUM_PROT 2
85 #endif /* CIFS_WEAK_PW_HASH */
87 #ifdef CONFIG_CIFS_WEAK_PW_HASH
88 #define CIFS_NUM_PROT 3
90 #define CIFS_NUM_PROT 1
91 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
92 #endif /* CIFS_POSIX */
95 * Mark as invalid, all open files on tree connections since they
96 * were closed when session to server was lost.
99 cifs_mark_open_files_invalid(struct cifs_tcon
*tcon
)
101 struct cifsFileInfo
*open_file
= NULL
;
102 struct list_head
*tmp
;
103 struct list_head
*tmp1
;
105 /* list all files open on tree connection and mark them invalid */
106 spin_lock(&tcon
->open_file_lock
);
107 list_for_each_safe(tmp
, tmp1
, &tcon
->openFileList
) {
108 open_file
= list_entry(tmp
, struct cifsFileInfo
, tlist
);
109 open_file
->invalidHandle
= true;
110 open_file
->oplock_break_cancelled
= true;
112 spin_unlock(&tcon
->open_file_lock
);
114 mutex_lock(&tcon
->crfid
.fid_mutex
);
115 tcon
->crfid
.is_valid
= false;
116 /* cached handle is not valid, so SMB2_CLOSE won't be sent below */
117 close_shroot_lease_locked(&tcon
->crfid
);
118 memset(tcon
->crfid
.fid
, 0, sizeof(struct cifs_fid
));
119 mutex_unlock(&tcon
->crfid
.fid_mutex
);
122 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
127 #ifdef CONFIG_CIFS_DFS_UPCALL
128 static int __cifs_reconnect_tcon(const struct nls_table
*nlsc
,
129 struct cifs_tcon
*tcon
)
132 struct dfs_cache_tgt_list tl
;
133 struct dfs_cache_tgt_iterator
*it
= NULL
;
135 const char *tcp_host
;
137 const char *dfs_host
;
140 tree
= kzalloc(MAX_TREE_SIZE
, GFP_KERNEL
);
145 scnprintf(tree
, MAX_TREE_SIZE
, "\\\\%s\\IPC$",
146 tcon
->ses
->server
->hostname
);
147 rc
= CIFSTCon(0, tcon
->ses
, tree
, tcon
, nlsc
);
151 if (!tcon
->dfs_path
) {
152 rc
= CIFSTCon(0, tcon
->ses
, tcon
->treeName
, tcon
, nlsc
);
156 rc
= dfs_cache_noreq_find(tcon
->dfs_path
+ 1, NULL
, &tl
);
160 extract_unc_hostname(tcon
->ses
->server
->hostname
, &tcp_host
,
163 for (it
= dfs_cache_get_tgt_iterator(&tl
); it
;
164 it
= dfs_cache_get_next_tgt(&tl
, it
)) {
165 const char *share
, *prefix
;
166 size_t share_len
, prefix_len
;
168 rc
= dfs_cache_get_tgt_share(it
, &share
, &share_len
, &prefix
,
171 cifs_dbg(VFS
, "%s: failed to parse target share %d\n",
176 extract_unc_hostname(share
, &dfs_host
, &dfs_host_len
);
178 if (dfs_host_len
!= tcp_host_len
179 || strncasecmp(dfs_host
, tcp_host
, dfs_host_len
) != 0) {
180 cifs_dbg(FYI
, "%s: skipping %.*s, doesn't match %.*s",
182 (int)dfs_host_len
, dfs_host
,
183 (int)tcp_host_len
, tcp_host
);
187 scnprintf(tree
, MAX_TREE_SIZE
, "\\%.*s", (int)share_len
, share
);
189 rc
= CIFSTCon(0, tcon
->ses
, tree
, tcon
, nlsc
);
191 rc
= update_super_prepath(tcon
, prefix
, prefix_len
);
200 rc
= dfs_cache_noreq_update_tgthint(tcon
->dfs_path
+ 1,
205 dfs_cache_free_tgts(&tl
);
211 static inline int __cifs_reconnect_tcon(const struct nls_table
*nlsc
,
212 struct cifs_tcon
*tcon
)
214 return CIFSTCon(0, tcon
->ses
, tcon
->treeName
, tcon
, nlsc
);
218 /* reconnect the socket, tcon, and smb session if needed */
220 cifs_reconnect_tcon(struct cifs_tcon
*tcon
, int smb_command
)
223 struct cifs_ses
*ses
;
224 struct TCP_Server_Info
*server
;
225 struct nls_table
*nls_codepage
;
229 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
230 * tcp and smb session status done differently for those three - in the
237 server
= ses
->server
;
240 * only tree disconnect, open, and write, (and ulogoff which does not
241 * have tcon) are allowed as we start force umount
243 if (tcon
->tidStatus
== CifsExiting
) {
244 if (smb_command
!= SMB_COM_WRITE_ANDX
&&
245 smb_command
!= SMB_COM_OPEN_ANDX
&&
246 smb_command
!= SMB_COM_TREE_DISCONNECT
) {
247 cifs_dbg(FYI
, "can not send cmd %d while umounting\n",
253 retries
= server
->nr_targets
;
256 * Give demultiplex thread up to 10 seconds to each target available for
257 * reconnect -- should be greater than cifs socket timeout which is 7
260 while (server
->tcpStatus
== CifsNeedReconnect
) {
261 rc
= wait_event_interruptible_timeout(server
->response_q
,
262 (server
->tcpStatus
!= CifsNeedReconnect
),
265 cifs_dbg(FYI
, "%s: aborting reconnect due to a received"
266 " signal by the process\n", __func__
);
270 /* are we still trying to reconnect? */
271 if (server
->tcpStatus
!= CifsNeedReconnect
)
274 if (retries
&& --retries
)
278 * on "soft" mounts we wait once. Hard mounts keep
279 * retrying until process is killed or server comes
283 cifs_dbg(FYI
, "gave up waiting on reconnect in smb_init\n");
286 retries
= server
->nr_targets
;
289 if (!ses
->need_reconnect
&& !tcon
->need_reconnect
)
292 nls_codepage
= load_nls_default();
295 * need to prevent multiple threads trying to simultaneously
296 * reconnect the same SMB session
298 mutex_lock(&ses
->session_mutex
);
301 * Recheck after acquire mutex. If another thread is negotiating
302 * and the server never sends an answer the socket will be closed
303 * and tcpStatus set to reconnect.
305 if (server
->tcpStatus
== CifsNeedReconnect
) {
307 mutex_unlock(&ses
->session_mutex
);
311 rc
= cifs_negotiate_protocol(0, ses
);
312 if (rc
== 0 && ses
->need_reconnect
)
313 rc
= cifs_setup_session(0, ses
, nls_codepage
);
315 /* do we need to reconnect tcon? */
316 if (rc
|| !tcon
->need_reconnect
) {
317 mutex_unlock(&ses
->session_mutex
);
321 cifs_mark_open_files_invalid(tcon
);
322 rc
= __cifs_reconnect_tcon(nls_codepage
, tcon
);
323 mutex_unlock(&ses
->session_mutex
);
324 cifs_dbg(FYI
, "reconnect tcon rc = %d\n", rc
);
327 printk_once(KERN_WARNING
"reconnect tcon failed rc = %d\n", rc
);
331 atomic_inc(&tconInfoReconnectCount
);
333 /* tell server Unix caps we support */
335 reset_cifs_unix_caps(0, tcon
, NULL
, NULL
);
338 * Removed call to reopen open files here. It is safer (and faster) to
339 * reopen files one at a time as needed in read and write.
341 * FIXME: what about file locks? don't we need to reclaim them ASAP?
346 * Check if handle based operation so we know whether we can continue
347 * or not without returning to caller to reset file handle
349 switch (smb_command
) {
350 case SMB_COM_READ_ANDX
:
351 case SMB_COM_WRITE_ANDX
:
353 case SMB_COM_FIND_CLOSE2
:
354 case SMB_COM_LOCKING_ANDX
:
358 unload_nls(nls_codepage
);
362 /* Allocate and return pointer to an SMB request buffer, and set basic
363 SMB information in the SMB header. If the return code is zero, this
364 function must have filled in request_buf pointer */
366 small_smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
371 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
375 *request_buf
= cifs_small_buf_get();
376 if (*request_buf
== NULL
) {
377 /* BB should we add a retry in here if not a writepage? */
381 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
,
385 cifs_stats_inc(&tcon
->num_smbs_sent
);
391 small_smb_init_no_tc(const int smb_command
, const int wct
,
392 struct cifs_ses
*ses
, void **request_buf
)
395 struct smb_hdr
*buffer
;
397 rc
= small_smb_init(smb_command
, wct
, NULL
, request_buf
);
401 buffer
= (struct smb_hdr
*)*request_buf
;
402 buffer
->Mid
= get_next_mid(ses
->server
);
403 if (ses
->capabilities
& CAP_UNICODE
)
404 buffer
->Flags2
|= SMBFLG2_UNICODE
;
405 if (ses
->capabilities
& CAP_STATUS32
)
406 buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
408 /* uid, tid can stay at zero as set in header assemble */
410 /* BB add support for turning on the signing when
411 this function is used after 1st of session setup requests */
416 /* If the return code is zero, this function must fill in request_buf pointer */
418 __smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
419 void **request_buf
, void **response_buf
)
421 *request_buf
= cifs_buf_get();
422 if (*request_buf
== NULL
) {
423 /* BB should we add a retry in here if not a writepage? */
426 /* Although the original thought was we needed the response buf for */
427 /* potential retries of smb operations it turns out we can determine */
428 /* from the mid flags when the request buffer can be resent without */
429 /* having to use a second distinct buffer for the response */
431 *response_buf
= *request_buf
;
433 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
, tcon
,
437 cifs_stats_inc(&tcon
->num_smbs_sent
);
442 /* If the return code is zero, this function must fill in request_buf pointer */
444 smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
445 void **request_buf
, void **response_buf
)
449 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
453 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
457 smb_init_no_reconnect(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
458 void **request_buf
, void **response_buf
)
460 if (tcon
->ses
->need_reconnect
|| tcon
->need_reconnect
)
463 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
466 static int validate_t2(struct smb_t2_rsp
*pSMB
)
468 unsigned int total_size
;
470 /* check for plausible wct */
471 if (pSMB
->hdr
.WordCount
< 10)
474 /* check for parm and data offset going beyond end of smb */
475 if (get_unaligned_le16(&pSMB
->t2_rsp
.ParameterOffset
) > 1024 ||
476 get_unaligned_le16(&pSMB
->t2_rsp
.DataOffset
) > 1024)
479 total_size
= get_unaligned_le16(&pSMB
->t2_rsp
.ParameterCount
);
480 if (total_size
>= 512)
483 /* check that bcc is at least as big as parms + data, and that it is
484 * less than negotiated smb buffer
486 total_size
+= get_unaligned_le16(&pSMB
->t2_rsp
.DataCount
);
487 if (total_size
> get_bcc(&pSMB
->hdr
) ||
488 total_size
>= CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
)
493 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB
,
494 sizeof(struct smb_t2_rsp
) + 16);
499 decode_ext_sec_blob(struct cifs_ses
*ses
, NEGOTIATE_RSP
*pSMBr
)
503 char *guid
= pSMBr
->u
.extended_response
.GUID
;
504 struct TCP_Server_Info
*server
= ses
->server
;
506 count
= get_bcc(&pSMBr
->hdr
);
507 if (count
< SMB1_CLIENT_GUID_SIZE
)
510 spin_lock(&cifs_tcp_ses_lock
);
511 if (server
->srv_count
> 1) {
512 spin_unlock(&cifs_tcp_ses_lock
);
513 if (memcmp(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
) != 0) {
514 cifs_dbg(FYI
, "server UID changed\n");
515 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
518 spin_unlock(&cifs_tcp_ses_lock
);
519 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
522 if (count
== SMB1_CLIENT_GUID_SIZE
) {
523 server
->sec_ntlmssp
= true;
525 count
-= SMB1_CLIENT_GUID_SIZE
;
526 rc
= decode_negTokenInit(
527 pSMBr
->u
.extended_response
.SecurityBlob
, count
, server
);
536 cifs_enable_signing(struct TCP_Server_Info
*server
, bool mnt_sign_required
)
538 bool srv_sign_required
= server
->sec_mode
& server
->vals
->signing_required
;
539 bool srv_sign_enabled
= server
->sec_mode
& server
->vals
->signing_enabled
;
540 bool mnt_sign_enabled
= global_secflags
& CIFSSEC_MAY_SIGN
;
543 * Is signing required by mnt options? If not then check
544 * global_secflags to see if it is there.
546 if (!mnt_sign_required
)
547 mnt_sign_required
= ((global_secflags
& CIFSSEC_MUST_SIGN
) ==
551 * If signing is required then it's automatically enabled too,
552 * otherwise, check to see if the secflags allow it.
554 mnt_sign_enabled
= mnt_sign_required
? mnt_sign_required
:
555 (global_secflags
& CIFSSEC_MAY_SIGN
);
557 /* If server requires signing, does client allow it? */
558 if (srv_sign_required
) {
559 if (!mnt_sign_enabled
) {
560 cifs_dbg(VFS
, "Server requires signing, but it's disabled in SecurityFlags!");
566 /* If client requires signing, does server allow it? */
567 if (mnt_sign_required
) {
568 if (!srv_sign_enabled
) {
569 cifs_dbg(VFS
, "Server does not support signing!");
575 if (cifs_rdma_enabled(server
) && server
->sign
)
576 cifs_dbg(VFS
, "Signing is enabled, and RDMA read/write will be disabled");
581 #ifdef CONFIG_CIFS_WEAK_PW_HASH
583 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
586 struct lanman_neg_rsp
*rsp
= (struct lanman_neg_rsp
*)pSMBr
;
588 if (server
->dialect
!= LANMAN_PROT
&& server
->dialect
!= LANMAN2_PROT
)
591 server
->sec_mode
= le16_to_cpu(rsp
->SecurityMode
);
592 server
->maxReq
= min_t(unsigned int,
593 le16_to_cpu(rsp
->MaxMpxCount
),
595 set_credits(server
, server
->maxReq
);
596 server
->maxBuf
= le16_to_cpu(rsp
->MaxBufSize
);
597 /* even though we do not use raw we might as well set this
598 accurately, in case we ever find a need for it */
599 if ((le16_to_cpu(rsp
->RawMode
) & RAW_ENABLE
) == RAW_ENABLE
) {
600 server
->max_rw
= 0xFF00;
601 server
->capabilities
= CAP_MPX_MODE
| CAP_RAW_MODE
;
603 server
->max_rw
= 0;/* do not need to use raw anyway */
604 server
->capabilities
= CAP_MPX_MODE
;
606 tmp
= (__s16
)le16_to_cpu(rsp
->ServerTimeZone
);
608 /* OS/2 often does not set timezone therefore
609 * we must use server time to calc time zone.
610 * Could deviate slightly from the right zone.
611 * Smallest defined timezone difference is 15 minutes
612 * (i.e. Nepal). Rounding up/down is done to match
615 int val
, seconds
, remain
, result
;
616 struct timespec64 ts
;
617 time64_t utc
= ktime_get_real_seconds();
618 ts
= cnvrtDosUnixTm(rsp
->SrvTime
.Date
,
619 rsp
->SrvTime
.Time
, 0);
620 cifs_dbg(FYI
, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n",
623 val
= (int)(utc
- ts
.tv_sec
);
625 result
= (seconds
/ MIN_TZ_ADJ
) * MIN_TZ_ADJ
;
626 remain
= seconds
% MIN_TZ_ADJ
;
627 if (remain
>= (MIN_TZ_ADJ
/ 2))
628 result
+= MIN_TZ_ADJ
;
631 server
->timeAdj
= result
;
633 server
->timeAdj
= (int)tmp
;
634 server
->timeAdj
*= 60; /* also in seconds */
636 cifs_dbg(FYI
, "server->timeAdj: %d seconds\n", server
->timeAdj
);
639 /* BB get server time for time conversions and add
640 code to use it and timezone since this is not UTC */
642 if (rsp
->EncryptionKeyLength
==
643 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE
)) {
644 memcpy(server
->cryptkey
, rsp
->EncryptionKey
,
645 CIFS_CRYPTO_KEY_SIZE
);
646 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
647 return -EIO
; /* need cryptkey unless plain text */
650 cifs_dbg(FYI
, "LANMAN negotiated\n");
655 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
657 cifs_dbg(VFS
, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
663 should_set_ext_sec_flag(enum securityEnum sectype
)
670 if (global_secflags
&
671 (CIFSSEC_MAY_KRB5
| CIFSSEC_MAY_NTLMSSP
))
680 CIFSSMBNegotiate(const unsigned int xid
, struct cifs_ses
*ses
)
683 NEGOTIATE_RSP
*pSMBr
;
687 struct TCP_Server_Info
*server
= ses
->server
;
691 WARN(1, "%s: server is NULL!\n", __func__
);
695 rc
= smb_init(SMB_COM_NEGOTIATE
, 0, NULL
/* no tcon yet */ ,
696 (void **) &pSMB
, (void **) &pSMBr
);
700 pSMB
->hdr
.Mid
= get_next_mid(server
);
701 pSMB
->hdr
.Flags2
|= (SMBFLG2_UNICODE
| SMBFLG2_ERR_STATUS
);
703 if (should_set_ext_sec_flag(ses
->sectype
)) {
704 cifs_dbg(FYI
, "Requesting extended security.");
705 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
710 * We know that all the name entries in the protocols array
711 * are short (< 16 bytes anyway) and are NUL terminated.
713 for (i
= 0; i
< CIFS_NUM_PROT
; i
++) {
714 size_t len
= strlen(protocols
[i
].name
) + 1;
716 memcpy(pSMB
->DialectsArray
+count
, protocols
[i
].name
, len
);
719 inc_rfc1001_len(pSMB
, count
);
720 pSMB
->ByteCount
= cpu_to_le16(count
);
722 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
723 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
727 server
->dialect
= le16_to_cpu(pSMBr
->DialectIndex
);
728 cifs_dbg(FYI
, "Dialect: %d\n", server
->dialect
);
729 /* Check wct = 1 error case */
730 if ((pSMBr
->hdr
.WordCount
< 13) || (server
->dialect
== BAD_PROT
)) {
731 /* core returns wct = 1, but we do not ask for core - otherwise
732 small wct just comes when dialect index is -1 indicating we
733 could not negotiate a common dialect */
736 } else if (pSMBr
->hdr
.WordCount
== 13) {
737 server
->negflavor
= CIFS_NEGFLAVOR_LANMAN
;
738 rc
= decode_lanman_negprot_rsp(server
, pSMBr
);
740 } else if (pSMBr
->hdr
.WordCount
!= 17) {
745 /* else wct == 17, NTLM or better */
747 server
->sec_mode
= pSMBr
->SecurityMode
;
748 if ((server
->sec_mode
& SECMODE_USER
) == 0)
749 cifs_dbg(FYI
, "share mode security\n");
751 /* one byte, so no need to convert this or EncryptionKeyLen from
753 server
->maxReq
= min_t(unsigned int, le16_to_cpu(pSMBr
->MaxMpxCount
),
755 set_credits(server
, server
->maxReq
);
756 /* probably no need to store and check maxvcs */
757 server
->maxBuf
= le32_to_cpu(pSMBr
->MaxBufferSize
);
758 server
->max_rw
= le32_to_cpu(pSMBr
->MaxRawSize
);
759 cifs_dbg(NOISY
, "Max buf = %d\n", ses
->server
->maxBuf
);
760 server
->capabilities
= le32_to_cpu(pSMBr
->Capabilities
);
761 server
->timeAdj
= (int)(__s16
)le16_to_cpu(pSMBr
->ServerTimeZone
);
762 server
->timeAdj
*= 60;
764 if (pSMBr
->EncryptionKeyLength
== CIFS_CRYPTO_KEY_SIZE
) {
765 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
766 memcpy(ses
->server
->cryptkey
, pSMBr
->u
.EncryptionKey
,
767 CIFS_CRYPTO_KEY_SIZE
);
768 } else if (pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
||
769 server
->capabilities
& CAP_EXTENDED_SECURITY
) {
770 server
->negflavor
= CIFS_NEGFLAVOR_EXTENDED
;
771 rc
= decode_ext_sec_blob(ses
, pSMBr
);
772 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
773 rc
= -EIO
; /* no crypt key only if plain text pwd */
775 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
776 server
->capabilities
&= ~CAP_EXTENDED_SECURITY
;
781 rc
= cifs_enable_signing(server
, ses
->sign
);
783 cifs_buf_release(pSMB
);
785 cifs_dbg(FYI
, "negprot rc %d\n", rc
);
790 CIFSSMBTDis(const unsigned int xid
, struct cifs_tcon
*tcon
)
792 struct smb_hdr
*smb_buffer
;
795 cifs_dbg(FYI
, "In tree disconnect\n");
797 /* BB: do we need to check this? These should never be NULL. */
798 if ((tcon
->ses
== NULL
) || (tcon
->ses
->server
== NULL
))
802 * No need to return error on this operation if tid invalidated and
803 * closed on server already e.g. due to tcp session crashing. Also,
804 * the tcon is no longer on the list, so no need to take lock before
807 if ((tcon
->need_reconnect
) || (tcon
->ses
->need_reconnect
))
810 rc
= small_smb_init(SMB_COM_TREE_DISCONNECT
, 0, tcon
,
811 (void **)&smb_buffer
);
815 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)smb_buffer
, 0);
816 cifs_small_buf_release(smb_buffer
);
818 cifs_dbg(FYI
, "Tree disconnect failed %d\n", rc
);
820 /* No need to return error on this operation if tid invalidated and
821 closed on server already e.g. due to tcp session crashing */
829 * This is a no-op for now. We're not really interested in the reply, but
830 * rather in the fact that the server sent one and that server->lstrp
833 * FIXME: maybe we should consider checking that the reply matches request?
836 cifs_echo_callback(struct mid_q_entry
*mid
)
838 struct TCP_Server_Info
*server
= mid
->callback_data
;
839 struct cifs_credits credits
= { .value
= 1, .instance
= 0 };
841 DeleteMidQEntry(mid
);
842 add_credits(server
, &credits
, CIFS_ECHO_OP
);
846 CIFSSMBEcho(struct TCP_Server_Info
*server
)
851 struct smb_rqst rqst
= { .rq_iov
= iov
,
854 cifs_dbg(FYI
, "In echo request\n");
856 rc
= small_smb_init(SMB_COM_ECHO
, 0, NULL
, (void **)&smb
);
860 if (server
->capabilities
& CAP_UNICODE
)
861 smb
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
863 /* set up echo request */
864 smb
->hdr
.Tid
= 0xffff;
865 smb
->hdr
.WordCount
= 1;
866 put_unaligned_le16(1, &smb
->EchoCount
);
867 put_bcc(1, &smb
->hdr
);
869 inc_rfc1001_len(smb
, 3);
872 iov
[0].iov_base
= smb
;
873 iov
[1].iov_len
= get_rfc1002_length(smb
);
874 iov
[1].iov_base
= (char *)smb
+ 4;
876 rc
= cifs_call_async(server
, &rqst
, NULL
, cifs_echo_callback
, NULL
,
877 server
, CIFS_NON_BLOCKING
| CIFS_ECHO_OP
, NULL
);
879 cifs_dbg(FYI
, "Echo request failed: %d\n", rc
);
881 cifs_small_buf_release(smb
);
887 CIFSSMBLogoff(const unsigned int xid
, struct cifs_ses
*ses
)
889 LOGOFF_ANDX_REQ
*pSMB
;
892 cifs_dbg(FYI
, "In SMBLogoff for session disconnect\n");
895 * BB: do we need to check validity of ses and server? They should
896 * always be valid since we have an active reference. If not, that
897 * should probably be a BUG()
899 if (!ses
|| !ses
->server
)
902 mutex_lock(&ses
->session_mutex
);
903 if (ses
->need_reconnect
)
904 goto session_already_dead
; /* no need to send SMBlogoff if uid
905 already closed due to reconnect */
906 rc
= small_smb_init(SMB_COM_LOGOFF_ANDX
, 2, NULL
, (void **)&pSMB
);
908 mutex_unlock(&ses
->session_mutex
);
912 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
914 if (ses
->server
->sign
)
915 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
917 pSMB
->hdr
.Uid
= ses
->Suid
;
919 pSMB
->AndXCommand
= 0xFF;
920 rc
= SendReceiveNoRsp(xid
, ses
, (char *) pSMB
, 0);
921 cifs_small_buf_release(pSMB
);
922 session_already_dead
:
923 mutex_unlock(&ses
->session_mutex
);
925 /* if session dead then we do not need to do ulogoff,
926 since server closed smb session, no sense reporting
934 CIFSPOSIXDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
,
935 const char *fileName
, __u16 type
,
936 const struct nls_table
*nls_codepage
, int remap
)
938 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
939 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
940 struct unlink_psx_rq
*pRqD
;
943 int bytes_returned
= 0;
944 __u16 params
, param_offset
, offset
, byte_count
;
946 cifs_dbg(FYI
, "In POSIX delete\n");
948 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
953 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
955 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
956 PATH_MAX
, nls_codepage
, remap
);
957 name_len
++; /* trailing null */
960 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
963 params
= 6 + name_len
;
964 pSMB
->MaxParameterCount
= cpu_to_le16(2);
965 pSMB
->MaxDataCount
= 0; /* BB double check this with jra */
966 pSMB
->MaxSetupCount
= 0;
971 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
972 InformationLevel
) - 4;
973 offset
= param_offset
+ params
;
975 /* Setup pointer to Request Data (inode type) */
976 pRqD
= (struct unlink_psx_rq
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
977 pRqD
->type
= cpu_to_le16(type
);
978 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
979 pSMB
->DataOffset
= cpu_to_le16(offset
);
980 pSMB
->SetupCount
= 1;
982 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
983 byte_count
= 3 /* pad */ + params
+ sizeof(struct unlink_psx_rq
);
985 pSMB
->DataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
986 pSMB
->TotalDataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
987 pSMB
->ParameterCount
= cpu_to_le16(params
);
988 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
989 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_UNLINK
);
991 inc_rfc1001_len(pSMB
, byte_count
);
992 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
993 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
994 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
996 cifs_dbg(FYI
, "Posix delete returned %d\n", rc
);
997 cifs_buf_release(pSMB
);
999 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
1008 CIFSSMBDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
1009 struct cifs_sb_info
*cifs_sb
)
1011 DELETE_FILE_REQ
*pSMB
= NULL
;
1012 DELETE_FILE_RSP
*pSMBr
= NULL
;
1016 int remap
= cifs_remap(cifs_sb
);
1019 rc
= smb_init(SMB_COM_DELETE
, 1, tcon
, (void **) &pSMB
,
1024 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1025 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->fileName
, name
,
1026 PATH_MAX
, cifs_sb
->local_nls
,
1028 name_len
++; /* trailing null */
1031 name_len
= copy_path_name(pSMB
->fileName
, name
);
1033 pSMB
->SearchAttributes
=
1034 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
);
1035 pSMB
->BufferFormat
= 0x04;
1036 inc_rfc1001_len(pSMB
, name_len
+ 1);
1037 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1038 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1039 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1040 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
1042 cifs_dbg(FYI
, "Error in RMFile = %d\n", rc
);
1044 cifs_buf_release(pSMB
);
1052 CIFSSMBRmDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
1053 struct cifs_sb_info
*cifs_sb
)
1055 DELETE_DIRECTORY_REQ
*pSMB
= NULL
;
1056 DELETE_DIRECTORY_RSP
*pSMBr
= NULL
;
1060 int remap
= cifs_remap(cifs_sb
);
1062 cifs_dbg(FYI
, "In CIFSSMBRmDir\n");
1064 rc
= smb_init(SMB_COM_DELETE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
1069 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1070 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
1071 PATH_MAX
, cifs_sb
->local_nls
,
1073 name_len
++; /* trailing null */
1076 name_len
= copy_path_name(pSMB
->DirName
, name
);
1079 pSMB
->BufferFormat
= 0x04;
1080 inc_rfc1001_len(pSMB
, name_len
+ 1);
1081 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1082 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1083 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1084 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_rmdirs
);
1086 cifs_dbg(FYI
, "Error in RMDir = %d\n", rc
);
1088 cifs_buf_release(pSMB
);
1095 CIFSSMBMkDir(const unsigned int xid
, struct inode
*inode
, umode_t mode
,
1096 struct cifs_tcon
*tcon
, const char *name
,
1097 struct cifs_sb_info
*cifs_sb
)
1100 CREATE_DIRECTORY_REQ
*pSMB
= NULL
;
1101 CREATE_DIRECTORY_RSP
*pSMBr
= NULL
;
1104 int remap
= cifs_remap(cifs_sb
);
1106 cifs_dbg(FYI
, "In CIFSSMBMkDir\n");
1108 rc
= smb_init(SMB_COM_CREATE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
1113 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1114 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
1115 PATH_MAX
, cifs_sb
->local_nls
,
1117 name_len
++; /* trailing null */
1120 name_len
= copy_path_name(pSMB
->DirName
, name
);
1123 pSMB
->BufferFormat
= 0x04;
1124 inc_rfc1001_len(pSMB
, name_len
+ 1);
1125 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1126 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1127 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1128 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_mkdirs
);
1130 cifs_dbg(FYI
, "Error in Mkdir = %d\n", rc
);
1132 cifs_buf_release(pSMB
);
1139 CIFSPOSIXCreate(const unsigned int xid
, struct cifs_tcon
*tcon
,
1140 __u32 posix_flags
, __u64 mode
, __u16
*netfid
,
1141 FILE_UNIX_BASIC_INFO
*pRetData
, __u32
*pOplock
,
1142 const char *name
, const struct nls_table
*nls_codepage
,
1145 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
1146 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
1149 int bytes_returned
= 0;
1150 __u16 params
, param_offset
, offset
, byte_count
, count
;
1151 OPEN_PSX_REQ
*pdata
;
1152 OPEN_PSX_RSP
*psx_rsp
;
1154 cifs_dbg(FYI
, "In POSIX Create\n");
1156 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1161 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1163 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, name
,
1164 PATH_MAX
, nls_codepage
, remap
);
1165 name_len
++; /* trailing null */
1168 name_len
= copy_path_name(pSMB
->FileName
, name
);
1171 params
= 6 + name_len
;
1172 count
= sizeof(OPEN_PSX_REQ
);
1173 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1174 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* large enough */
1175 pSMB
->MaxSetupCount
= 0;
1179 pSMB
->Reserved2
= 0;
1180 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
1181 InformationLevel
) - 4;
1182 offset
= param_offset
+ params
;
1183 pdata
= (OPEN_PSX_REQ
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
1184 pdata
->Level
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
1185 pdata
->Permissions
= cpu_to_le64(mode
);
1186 pdata
->PosixOpenFlags
= cpu_to_le32(posix_flags
);
1187 pdata
->OpenFlags
= cpu_to_le32(*pOplock
);
1188 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
1189 pSMB
->DataOffset
= cpu_to_le16(offset
);
1190 pSMB
->SetupCount
= 1;
1191 pSMB
->Reserved3
= 0;
1192 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
1193 byte_count
= 3 /* pad */ + params
+ count
;
1195 pSMB
->DataCount
= cpu_to_le16(count
);
1196 pSMB
->ParameterCount
= cpu_to_le16(params
);
1197 pSMB
->TotalDataCount
= pSMB
->DataCount
;
1198 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1199 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_OPEN
);
1200 pSMB
->Reserved4
= 0;
1201 inc_rfc1001_len(pSMB
, byte_count
);
1202 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1203 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1204 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1206 cifs_dbg(FYI
, "Posix create returned %d\n", rc
);
1207 goto psx_create_err
;
1210 cifs_dbg(FYI
, "copying inode info\n");
1211 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
1213 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)) {
1214 rc
= -EIO
; /* bad smb */
1215 goto psx_create_err
;
1218 /* copy return information to pRetData */
1219 psx_rsp
= (OPEN_PSX_RSP
*)((char *) &pSMBr
->hdr
.Protocol
1220 + le16_to_cpu(pSMBr
->t2
.DataOffset
));
1222 *pOplock
= le16_to_cpu(psx_rsp
->OplockFlags
);
1224 *netfid
= psx_rsp
->Fid
; /* cifs fid stays in le */
1225 /* Let caller know file was created so we can set the mode. */
1226 /* Do we care about the CreateAction in any other cases? */
1227 if (cpu_to_le32(FILE_CREATE
) == psx_rsp
->CreateAction
)
1228 *pOplock
|= CIFS_CREATE_ACTION
;
1229 /* check to make sure response data is there */
1230 if (psx_rsp
->ReturnedLevel
!= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
)) {
1231 pRetData
->Type
= cpu_to_le32(-1); /* unknown */
1232 cifs_dbg(NOISY
, "unknown type\n");
1234 if (get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)
1235 + sizeof(FILE_UNIX_BASIC_INFO
)) {
1236 cifs_dbg(VFS
, "Open response data too small\n");
1237 pRetData
->Type
= cpu_to_le32(-1);
1238 goto psx_create_err
;
1240 memcpy((char *) pRetData
,
1241 (char *)psx_rsp
+ sizeof(OPEN_PSX_RSP
),
1242 sizeof(FILE_UNIX_BASIC_INFO
));
1246 cifs_buf_release(pSMB
);
1248 if (posix_flags
& SMB_O_DIRECTORY
)
1249 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixmkdirs
);
1251 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixopens
);
1259 static __u16
convert_disposition(int disposition
)
1263 switch (disposition
) {
1264 case FILE_SUPERSEDE
:
1265 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1268 ofun
= SMBOPEN_OAPPEND
;
1271 ofun
= SMBOPEN_OCREATE
;
1274 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OAPPEND
;
1276 case FILE_OVERWRITE
:
1277 ofun
= SMBOPEN_OTRUNC
;
1279 case FILE_OVERWRITE_IF
:
1280 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1283 cifs_dbg(FYI
, "unknown disposition %d\n", disposition
);
1284 ofun
= SMBOPEN_OAPPEND
; /* regular open */
1290 access_flags_to_smbopen_mode(const int access_flags
)
1292 int masked_flags
= access_flags
& (GENERIC_READ
| GENERIC_WRITE
);
1294 if (masked_flags
== GENERIC_READ
)
1295 return SMBOPEN_READ
;
1296 else if (masked_flags
== GENERIC_WRITE
)
1297 return SMBOPEN_WRITE
;
1299 /* just go for read/write */
1300 return SMBOPEN_READWRITE
;
1304 SMBLegacyOpen(const unsigned int xid
, struct cifs_tcon
*tcon
,
1305 const char *fileName
, const int openDisposition
,
1306 const int access_flags
, const int create_options
, __u16
*netfid
,
1307 int *pOplock
, FILE_ALL_INFO
*pfile_info
,
1308 const struct nls_table
*nls_codepage
, int remap
)
1311 OPENX_REQ
*pSMB
= NULL
;
1312 OPENX_RSP
*pSMBr
= NULL
;
1318 rc
= smb_init(SMB_COM_OPEN_ANDX
, 15, tcon
, (void **) &pSMB
,
1323 pSMB
->AndXCommand
= 0xFF; /* none */
1325 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1326 count
= 1; /* account for one byte pad to word boundary */
1328 cifsConvertToUTF16((__le16
*) (pSMB
->fileName
+ 1),
1329 fileName
, PATH_MAX
, nls_codepage
, remap
);
1330 name_len
++; /* trailing null */
1333 count
= 0; /* no pad */
1334 name_len
= copy_path_name(pSMB
->fileName
, fileName
);
1336 if (*pOplock
& REQ_OPLOCK
)
1337 pSMB
->OpenFlags
= cpu_to_le16(REQ_OPLOCK
);
1338 else if (*pOplock
& REQ_BATCHOPLOCK
)
1339 pSMB
->OpenFlags
= cpu_to_le16(REQ_BATCHOPLOCK
);
1341 pSMB
->OpenFlags
|= cpu_to_le16(REQ_MORE_INFO
);
1342 pSMB
->Mode
= cpu_to_le16(access_flags_to_smbopen_mode(access_flags
));
1343 pSMB
->Mode
|= cpu_to_le16(0x40); /* deny none */
1344 /* set file as system file if special file such
1345 as fifo and server expecting SFU style and
1346 no Unix extensions */
1348 if (create_options
& CREATE_OPTION_SPECIAL
)
1349 pSMB
->FileAttributes
= cpu_to_le16(ATTR_SYSTEM
);
1350 else /* BB FIXME BB */
1351 pSMB
->FileAttributes
= cpu_to_le16(0/*ATTR_NORMAL*/);
1353 if (create_options
& CREATE_OPTION_READONLY
)
1354 pSMB
->FileAttributes
|= cpu_to_le16(ATTR_READONLY
);
1357 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1358 CREATE_OPTIONS_MASK); */
1359 /* BB FIXME END BB */
1361 pSMB
->Sattr
= cpu_to_le16(ATTR_HIDDEN
| ATTR_SYSTEM
| ATTR_DIRECTORY
);
1362 pSMB
->OpenFunction
= cpu_to_le16(convert_disposition(openDisposition
));
1364 inc_rfc1001_len(pSMB
, count
);
1366 pSMB
->ByteCount
= cpu_to_le16(count
);
1367 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1368 (struct smb_hdr
*)pSMBr
, &bytes_returned
, 0);
1369 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1371 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1373 /* BB verify if wct == 15 */
1375 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1377 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
1378 /* Let caller know file was created so we can set the mode. */
1379 /* Do we care about the CreateAction in any other cases? */
1381 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1382 *pOplock |= CIFS_CREATE_ACTION; */
1386 pfile_info
->CreationTime
= 0; /* BB convert CreateTime*/
1387 pfile_info
->LastAccessTime
= 0; /* BB fixme */
1388 pfile_info
->LastWriteTime
= 0; /* BB fixme */
1389 pfile_info
->ChangeTime
= 0; /* BB fixme */
1390 pfile_info
->Attributes
=
1391 cpu_to_le32(le16_to_cpu(pSMBr
->FileAttributes
));
1392 /* the file_info buf is endian converted by caller */
1393 pfile_info
->AllocationSize
=
1394 cpu_to_le64(le32_to_cpu(pSMBr
->EndOfFile
));
1395 pfile_info
->EndOfFile
= pfile_info
->AllocationSize
;
1396 pfile_info
->NumberOfLinks
= cpu_to_le32(1);
1397 pfile_info
->DeletePending
= 0;
1401 cifs_buf_release(pSMB
);
1408 CIFS_open(const unsigned int xid
, struct cifs_open_parms
*oparms
, int *oplock
,
1412 OPEN_REQ
*req
= NULL
;
1413 OPEN_RSP
*rsp
= NULL
;
1417 struct cifs_sb_info
*cifs_sb
= oparms
->cifs_sb
;
1418 struct cifs_tcon
*tcon
= oparms
->tcon
;
1419 int remap
= cifs_remap(cifs_sb
);
1420 const struct nls_table
*nls
= cifs_sb
->local_nls
;
1421 int create_options
= oparms
->create_options
;
1422 int desired_access
= oparms
->desired_access
;
1423 int disposition
= oparms
->disposition
;
1424 const char *path
= oparms
->path
;
1427 rc
= smb_init(SMB_COM_NT_CREATE_ANDX
, 24, tcon
, (void **)&req
,
1432 /* no commands go after this */
1433 req
->AndXCommand
= 0xFF;
1435 if (req
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1436 /* account for one byte pad to word boundary */
1438 name_len
= cifsConvertToUTF16((__le16
*)(req
->fileName
+ 1),
1439 path
, PATH_MAX
, nls
, remap
);
1443 req
->NameLength
= cpu_to_le16(name_len
);
1445 /* BB improve check for buffer overruns BB */
1448 name_len
= copy_path_name(req
->fileName
, path
);
1449 req
->NameLength
= cpu_to_le16(name_len
);
1452 if (*oplock
& REQ_OPLOCK
)
1453 req
->OpenFlags
= cpu_to_le32(REQ_OPLOCK
);
1454 else if (*oplock
& REQ_BATCHOPLOCK
)
1455 req
->OpenFlags
= cpu_to_le32(REQ_BATCHOPLOCK
);
1457 req
->DesiredAccess
= cpu_to_le32(desired_access
);
1458 req
->AllocationSize
= 0;
1461 * Set file as system file if special file such as fifo and server
1462 * expecting SFU style and no Unix extensions.
1464 if (create_options
& CREATE_OPTION_SPECIAL
)
1465 req
->FileAttributes
= cpu_to_le32(ATTR_SYSTEM
);
1467 req
->FileAttributes
= cpu_to_le32(ATTR_NORMAL
);
1470 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1471 * sensitive checks for other servers such as Samba.
1473 if (tcon
->ses
->capabilities
& CAP_UNIX
)
1474 req
->FileAttributes
|= cpu_to_le32(ATTR_POSIX_SEMANTICS
);
1476 if (create_options
& CREATE_OPTION_READONLY
)
1477 req
->FileAttributes
|= cpu_to_le32(ATTR_READONLY
);
1479 req
->ShareAccess
= cpu_to_le32(FILE_SHARE_ALL
);
1480 req
->CreateDisposition
= cpu_to_le32(disposition
);
1481 req
->CreateOptions
= cpu_to_le32(create_options
& CREATE_OPTIONS_MASK
);
1483 /* BB Expirement with various impersonation levels and verify */
1484 req
->ImpersonationLevel
= cpu_to_le32(SECURITY_IMPERSONATION
);
1485 req
->SecurityFlags
= SECURITY_CONTEXT_TRACKING
|SECURITY_EFFECTIVE_ONLY
;
1488 inc_rfc1001_len(req
, count
);
1490 req
->ByteCount
= cpu_to_le16(count
);
1491 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*)req
,
1492 (struct smb_hdr
*)rsp
, &bytes_returned
, 0);
1493 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1495 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1496 cifs_buf_release(req
);
1502 /* 1 byte no need to le_to_cpu */
1503 *oplock
= rsp
->OplockLevel
;
1504 /* cifs fid stays in le */
1505 oparms
->fid
->netfid
= rsp
->Fid
;
1506 oparms
->fid
->access
= desired_access
;
1508 /* Let caller know file was created so we can set the mode. */
1509 /* Do we care about the CreateAction in any other cases? */
1510 if (cpu_to_le32(FILE_CREATE
) == rsp
->CreateAction
)
1511 *oplock
|= CIFS_CREATE_ACTION
;
1514 /* copy from CreationTime to Attributes */
1515 memcpy((char *)buf
, (char *)&rsp
->CreationTime
, 36);
1516 /* the file_info buf is endian converted by caller */
1517 buf
->AllocationSize
= rsp
->AllocationSize
;
1518 buf
->EndOfFile
= rsp
->EndOfFile
;
1519 buf
->NumberOfLinks
= cpu_to_le32(1);
1520 buf
->DeletePending
= 0;
1523 cifs_buf_release(req
);
1528 * Discard any remaining data in the current SMB. To do this, we borrow the
1532 cifs_discard_remaining_data(struct TCP_Server_Info
*server
)
1534 unsigned int rfclen
= server
->pdu_size
;
1535 int remaining
= rfclen
+ server
->vals
->header_preamble_size
-
1538 while (remaining
> 0) {
1541 length
= cifs_read_from_socket(server
, server
->bigbuf
,
1542 min_t(unsigned int, remaining
,
1543 CIFSMaxBufSize
+ MAX_HEADER_SIZE(server
)));
1546 server
->total_read
+= length
;
1547 remaining
-= length
;
1554 __cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
,
1559 length
= cifs_discard_remaining_data(server
);
1560 dequeue_mid(mid
, malformed
);
1561 mid
->resp_buf
= server
->smallbuf
;
1562 server
->smallbuf
= NULL
;
1567 cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1569 struct cifs_readdata
*rdata
= mid
->callback_data
;
1571 return __cifs_readv_discard(server
, mid
, rdata
->result
);
1575 cifs_readv_receive(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1578 unsigned int data_offset
, data_len
;
1579 struct cifs_readdata
*rdata
= mid
->callback_data
;
1580 char *buf
= server
->smallbuf
;
1581 unsigned int buflen
= server
->pdu_size
+
1582 server
->vals
->header_preamble_size
;
1583 bool use_rdma_mr
= false;
1585 cifs_dbg(FYI
, "%s: mid=%llu offset=%llu bytes=%u\n",
1586 __func__
, mid
->mid
, rdata
->offset
, rdata
->bytes
);
1589 * read the rest of READ_RSP header (sans Data array), or whatever we
1590 * can if there's not enough data. At this point, we've read down to
1593 len
= min_t(unsigned int, buflen
, server
->vals
->read_rsp_size
) -
1594 HEADER_SIZE(server
) + 1;
1596 length
= cifs_read_from_socket(server
,
1597 buf
+ HEADER_SIZE(server
) - 1, len
);
1600 server
->total_read
+= length
;
1602 if (server
->ops
->is_session_expired
&&
1603 server
->ops
->is_session_expired(buf
)) {
1604 cifs_reconnect(server
);
1608 if (server
->ops
->is_status_pending
&&
1609 server
->ops
->is_status_pending(buf
, server
)) {
1610 cifs_discard_remaining_data(server
);
1614 /* set up first two iov for signature check and to get credits */
1615 rdata
->iov
[0].iov_base
= buf
;
1616 rdata
->iov
[0].iov_len
= server
->vals
->header_preamble_size
;
1617 rdata
->iov
[1].iov_base
= buf
+ server
->vals
->header_preamble_size
;
1618 rdata
->iov
[1].iov_len
=
1619 server
->total_read
- server
->vals
->header_preamble_size
;
1620 cifs_dbg(FYI
, "0: iov_base=%p iov_len=%zu\n",
1621 rdata
->iov
[0].iov_base
, rdata
->iov
[0].iov_len
);
1622 cifs_dbg(FYI
, "1: iov_base=%p iov_len=%zu\n",
1623 rdata
->iov
[1].iov_base
, rdata
->iov
[1].iov_len
);
1625 /* Was the SMB read successful? */
1626 rdata
->result
= server
->ops
->map_error(buf
, false);
1627 if (rdata
->result
!= 0) {
1628 cifs_dbg(FYI
, "%s: server returned error %d\n",
1629 __func__
, rdata
->result
);
1630 /* normal error on read response */
1631 return __cifs_readv_discard(server
, mid
, false);
1634 /* Is there enough to get to the rest of the READ_RSP header? */
1635 if (server
->total_read
< server
->vals
->read_rsp_size
) {
1636 cifs_dbg(FYI
, "%s: server returned short header. got=%u expected=%zu\n",
1637 __func__
, server
->total_read
,
1638 server
->vals
->read_rsp_size
);
1639 rdata
->result
= -EIO
;
1640 return cifs_readv_discard(server
, mid
);
1643 data_offset
= server
->ops
->read_data_offset(buf
) +
1644 server
->vals
->header_preamble_size
;
1645 if (data_offset
< server
->total_read
) {
1647 * win2k8 sometimes sends an offset of 0 when the read
1648 * is beyond the EOF. Treat it as if the data starts just after
1651 cifs_dbg(FYI
, "%s: data offset (%u) inside read response header\n",
1652 __func__
, data_offset
);
1653 data_offset
= server
->total_read
;
1654 } else if (data_offset
> MAX_CIFS_SMALL_BUFFER_SIZE
) {
1655 /* data_offset is beyond the end of smallbuf */
1656 cifs_dbg(FYI
, "%s: data offset (%u) beyond end of smallbuf\n",
1657 __func__
, data_offset
);
1658 rdata
->result
= -EIO
;
1659 return cifs_readv_discard(server
, mid
);
1662 cifs_dbg(FYI
, "%s: total_read=%u data_offset=%u\n",
1663 __func__
, server
->total_read
, data_offset
);
1665 len
= data_offset
- server
->total_read
;
1667 /* read any junk before data into the rest of smallbuf */
1668 length
= cifs_read_from_socket(server
,
1669 buf
+ server
->total_read
, len
);
1672 server
->total_read
+= length
;
1675 /* how much data is in the response? */
1676 #ifdef CONFIG_CIFS_SMB_DIRECT
1677 use_rdma_mr
= rdata
->mr
;
1679 data_len
= server
->ops
->read_data_length(buf
, use_rdma_mr
);
1680 if (!use_rdma_mr
&& (data_offset
+ data_len
> buflen
)) {
1681 /* data_len is corrupt -- discard frame */
1682 rdata
->result
= -EIO
;
1683 return cifs_readv_discard(server
, mid
);
1686 length
= rdata
->read_into_pages(server
, rdata
, data_len
);
1690 server
->total_read
+= length
;
1692 cifs_dbg(FYI
, "total_read=%u buflen=%u remaining=%u\n",
1693 server
->total_read
, buflen
, data_len
);
1695 /* discard anything left over */
1696 if (server
->total_read
< buflen
)
1697 return cifs_readv_discard(server
, mid
);
1699 dequeue_mid(mid
, false);
1700 mid
->resp_buf
= server
->smallbuf
;
1701 server
->smallbuf
= NULL
;
1706 cifs_readv_callback(struct mid_q_entry
*mid
)
1708 struct cifs_readdata
*rdata
= mid
->callback_data
;
1709 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1710 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
1711 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1713 .rq_pages
= rdata
->pages
,
1714 .rq_offset
= rdata
->page_offset
,
1715 .rq_npages
= rdata
->nr_pages
,
1716 .rq_pagesz
= rdata
->pagesz
,
1717 .rq_tailsz
= rdata
->tailsz
};
1718 struct cifs_credits credits
= { .value
= 1, .instance
= 0 };
1720 cifs_dbg(FYI
, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1721 __func__
, mid
->mid
, mid
->mid_state
, rdata
->result
,
1724 switch (mid
->mid_state
) {
1725 case MID_RESPONSE_RECEIVED
:
1726 /* result already set, check signature */
1730 rc
= cifs_verify_signature(&rqst
, server
,
1731 mid
->sequence_number
);
1733 cifs_dbg(VFS
, "SMB signature verification returned error = %d\n",
1736 /* FIXME: should this be counted toward the initiating task? */
1737 task_io_account_read(rdata
->got_bytes
);
1738 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1740 case MID_REQUEST_SUBMITTED
:
1741 case MID_RETRY_NEEDED
:
1742 rdata
->result
= -EAGAIN
;
1743 if (server
->sign
&& rdata
->got_bytes
)
1744 /* reset bytes number since we can not check a sign */
1745 rdata
->got_bytes
= 0;
1746 /* FIXME: should this be counted toward the initiating task? */
1747 task_io_account_read(rdata
->got_bytes
);
1748 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1751 rdata
->result
= -EIO
;
1754 queue_work(cifsiod_wq
, &rdata
->work
);
1755 DeleteMidQEntry(mid
);
1756 add_credits(server
, &credits
, 0);
1759 /* cifs_async_readv - send an async write, and set up mid to handle result */
1761 cifs_async_readv(struct cifs_readdata
*rdata
)
1764 READ_REQ
*smb
= NULL
;
1766 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1767 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1770 cifs_dbg(FYI
, "%s: offset=%llu bytes=%u\n",
1771 __func__
, rdata
->offset
, rdata
->bytes
);
1773 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1776 wct
= 10; /* old style read */
1777 if ((rdata
->offset
>> 32) > 0) {
1778 /* can not handle this big offset for old */
1783 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **)&smb
);
1787 smb
->hdr
.Pid
= cpu_to_le16((__u16
)rdata
->pid
);
1788 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(rdata
->pid
>> 16));
1790 smb
->AndXCommand
= 0xFF; /* none */
1791 smb
->Fid
= rdata
->cfile
->fid
.netfid
;
1792 smb
->OffsetLow
= cpu_to_le32(rdata
->offset
& 0xFFFFFFFF);
1794 smb
->OffsetHigh
= cpu_to_le32(rdata
->offset
>> 32);
1796 smb
->MaxCount
= cpu_to_le16(rdata
->bytes
& 0xFFFF);
1797 smb
->MaxCountHigh
= cpu_to_le32(rdata
->bytes
>> 16);
1801 /* old style read */
1802 struct smb_com_readx_req
*smbr
=
1803 (struct smb_com_readx_req
*)smb
;
1804 smbr
->ByteCount
= 0;
1807 /* 4 for RFC1001 length + 1 for BCC */
1808 rdata
->iov
[0].iov_base
= smb
;
1809 rdata
->iov
[0].iov_len
= 4;
1810 rdata
->iov
[1].iov_base
= (char *)smb
+ 4;
1811 rdata
->iov
[1].iov_len
= get_rfc1002_length(smb
);
1813 kref_get(&rdata
->refcount
);
1814 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, cifs_readv_receive
,
1815 cifs_readv_callback
, NULL
, rdata
, 0, NULL
);
1818 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1820 kref_put(&rdata
->refcount
, cifs_readdata_release
);
1822 cifs_small_buf_release(smb
);
1827 CIFSSMBRead(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1828 unsigned int *nbytes
, char **buf
, int *pbuf_type
)
1831 READ_REQ
*pSMB
= NULL
;
1832 READ_RSP
*pSMBr
= NULL
;
1833 char *pReadData
= NULL
;
1835 int resp_buf_type
= 0;
1837 struct kvec rsp_iov
;
1838 __u32 pid
= io_parms
->pid
;
1839 __u16 netfid
= io_parms
->netfid
;
1840 __u64 offset
= io_parms
->offset
;
1841 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1842 unsigned int count
= io_parms
->length
;
1844 cifs_dbg(FYI
, "Reading %d bytes on fid %d\n", count
, netfid
);
1845 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1848 wct
= 10; /* old style read */
1849 if ((offset
>> 32) > 0) {
1850 /* can not handle this big offset for old */
1856 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **) &pSMB
);
1860 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1861 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1863 /* tcon and ses pointer are checked in smb_init */
1864 if (tcon
->ses
->server
== NULL
)
1865 return -ECONNABORTED
;
1867 pSMB
->AndXCommand
= 0xFF; /* none */
1869 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1871 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1873 pSMB
->Remaining
= 0;
1874 pSMB
->MaxCount
= cpu_to_le16(count
& 0xFFFF);
1875 pSMB
->MaxCountHigh
= cpu_to_le32(count
>> 16);
1877 pSMB
->ByteCount
= 0; /* no need to do le conversion since 0 */
1879 /* old style read */
1880 struct smb_com_readx_req
*pSMBW
=
1881 (struct smb_com_readx_req
*)pSMB
;
1882 pSMBW
->ByteCount
= 0;
1885 iov
[0].iov_base
= (char *)pSMB
;
1886 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
1887 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1, &resp_buf_type
,
1888 CIFS_LOG_ERROR
, &rsp_iov
);
1889 cifs_small_buf_release(pSMB
);
1890 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1891 pSMBr
= (READ_RSP
*)rsp_iov
.iov_base
;
1893 cifs_dbg(VFS
, "Send error in read = %d\n", rc
);
1895 int data_length
= le16_to_cpu(pSMBr
->DataLengthHigh
);
1896 data_length
= data_length
<< 16;
1897 data_length
+= le16_to_cpu(pSMBr
->DataLength
);
1898 *nbytes
= data_length
;
1900 /*check that DataLength would not go beyond end of SMB */
1901 if ((data_length
> CIFSMaxBufSize
)
1902 || (data_length
> count
)) {
1903 cifs_dbg(FYI
, "bad length %d for count %d\n",
1904 data_length
, count
);
1908 pReadData
= (char *) (&pSMBr
->hdr
.Protocol
) +
1909 le16_to_cpu(pSMBr
->DataOffset
);
1910 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1911 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1913 }*/ /* can not use copy_to_user when using page cache*/
1915 memcpy(*buf
, pReadData
, data_length
);
1920 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
1921 } else if (resp_buf_type
!= CIFS_NO_BUFFER
) {
1922 /* return buffer to caller to free */
1923 *buf
= rsp_iov
.iov_base
;
1924 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1925 *pbuf_type
= CIFS_SMALL_BUFFER
;
1926 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1927 *pbuf_type
= CIFS_LARGE_BUFFER
;
1928 } /* else no valid buffer on return - leave as null */
1930 /* Note: On -EAGAIN error only caller can retry on handle based calls
1931 since file handle passed in no longer valid */
1937 CIFSSMBWrite(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1938 unsigned int *nbytes
, const char *buf
)
1941 WRITE_REQ
*pSMB
= NULL
;
1942 WRITE_RSP
*pSMBr
= NULL
;
1943 int bytes_returned
, wct
;
1946 __u32 pid
= io_parms
->pid
;
1947 __u16 netfid
= io_parms
->netfid
;
1948 __u64 offset
= io_parms
->offset
;
1949 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1950 unsigned int count
= io_parms
->length
;
1954 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1955 if (tcon
->ses
== NULL
)
1956 return -ECONNABORTED
;
1958 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1962 if ((offset
>> 32) > 0) {
1963 /* can not handle big offset for old srv */
1968 rc
= smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
,
1973 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1974 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1976 /* tcon and ses pointer are checked in smb_init */
1977 if (tcon
->ses
->server
== NULL
)
1978 return -ECONNABORTED
;
1980 pSMB
->AndXCommand
= 0xFF; /* none */
1982 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1984 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1986 pSMB
->Reserved
= 0xFFFFFFFF;
1987 pSMB
->WriteMode
= 0;
1988 pSMB
->Remaining
= 0;
1990 /* Can increase buffer size if buffer is big enough in some cases ie we
1991 can send more if LARGE_WRITE_X capability returned by the server and if
1992 our buffer is big enough or if we convert to iovecs on socket writes
1993 and eliminate the copy to the CIFS buffer */
1994 if (tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
) {
1995 bytes_sent
= min_t(const unsigned int, CIFSMaxBufSize
, count
);
1997 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
)
2001 if (bytes_sent
> count
)
2004 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2006 memcpy(pSMB
->Data
, buf
, bytes_sent
);
2007 else if (count
!= 0) {
2009 cifs_buf_release(pSMB
);
2011 } /* else setting file size with write of zero bytes */
2013 byte_count
= bytes_sent
+ 1; /* pad */
2014 else /* wct == 12 */
2015 byte_count
= bytes_sent
+ 5; /* bigger pad, smaller smb hdr */
2017 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
& 0xFFFF);
2018 pSMB
->DataLengthHigh
= cpu_to_le16(bytes_sent
>> 16);
2019 inc_rfc1001_len(pSMB
, byte_count
);
2022 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2023 else { /* old style write has byte count 4 bytes earlier
2025 struct smb_com_writex_req
*pSMBW
=
2026 (struct smb_com_writex_req
*)pSMB
;
2027 pSMBW
->ByteCount
= cpu_to_le16(byte_count
);
2030 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2031 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2032 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2034 cifs_dbg(FYI
, "Send error in write = %d\n", rc
);
2036 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2037 *nbytes
= (*nbytes
) << 16;
2038 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2041 * Mask off high 16 bits when bytes written as returned by the
2042 * server is greater than bytes requested by the client. Some
2043 * OS/2 servers are known to set incorrect CountHigh values.
2045 if (*nbytes
> count
)
2049 cifs_buf_release(pSMB
);
2051 /* Note: On -EAGAIN error only caller can retry on handle based calls
2052 since file handle passed in no longer valid */
2058 cifs_writedata_release(struct kref
*refcount
)
2060 struct cifs_writedata
*wdata
= container_of(refcount
,
2061 struct cifs_writedata
, refcount
);
2062 #ifdef CONFIG_CIFS_SMB_DIRECT
2064 smbd_deregister_mr(wdata
->mr
);
2070 cifsFileInfo_put(wdata
->cfile
);
2072 kvfree(wdata
->pages
);
2077 * Write failed with a retryable error. Resend the write request. It's also
2078 * possible that the page was redirtied so re-clean the page.
2081 cifs_writev_requeue(struct cifs_writedata
*wdata
)
2084 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
2085 struct TCP_Server_Info
*server
;
2086 unsigned int rest_len
;
2088 server
= tlink_tcon(wdata
->cfile
->tlink
)->ses
->server
;
2090 rest_len
= wdata
->bytes
;
2092 struct cifs_writedata
*wdata2
;
2093 unsigned int j
, nr_pages
, wsize
, tailsz
, cur_len
;
2095 wsize
= server
->ops
->wp_retry_size(inode
);
2096 if (wsize
< rest_len
) {
2097 nr_pages
= wsize
/ PAGE_SIZE
;
2102 cur_len
= nr_pages
* PAGE_SIZE
;
2105 nr_pages
= DIV_ROUND_UP(rest_len
, PAGE_SIZE
);
2107 tailsz
= rest_len
- (nr_pages
- 1) * PAGE_SIZE
;
2110 wdata2
= cifs_writedata_alloc(nr_pages
, cifs_writev_complete
);
2116 for (j
= 0; j
< nr_pages
; j
++) {
2117 wdata2
->pages
[j
] = wdata
->pages
[i
+ j
];
2118 lock_page(wdata2
->pages
[j
]);
2119 clear_page_dirty_for_io(wdata2
->pages
[j
]);
2122 wdata2
->sync_mode
= wdata
->sync_mode
;
2123 wdata2
->nr_pages
= nr_pages
;
2124 wdata2
->offset
= page_offset(wdata2
->pages
[0]);
2125 wdata2
->pagesz
= PAGE_SIZE
;
2126 wdata2
->tailsz
= tailsz
;
2127 wdata2
->bytes
= cur_len
;
2129 rc
= cifs_get_writable_file(CIFS_I(inode
), FIND_WR_ANY
,
2131 if (!wdata2
->cfile
) {
2132 cifs_dbg(VFS
, "No writable handle to retry writepages rc=%d\n",
2134 if (!is_retryable_error(rc
))
2137 wdata2
->pid
= wdata2
->cfile
->pid
;
2138 rc
= server
->ops
->async_writev(wdata2
,
2139 cifs_writedata_release
);
2142 for (j
= 0; j
< nr_pages
; j
++) {
2143 unlock_page(wdata2
->pages
[j
]);
2144 if (rc
!= 0 && !is_retryable_error(rc
)) {
2145 SetPageError(wdata2
->pages
[j
]);
2146 end_page_writeback(wdata2
->pages
[j
]);
2147 put_page(wdata2
->pages
[j
]);
2152 kref_put(&wdata2
->refcount
, cifs_writedata_release
);
2153 if (is_retryable_error(rc
))
2159 rest_len
-= cur_len
;
2161 } while (i
< wdata
->nr_pages
);
2163 /* cleanup remaining pages from the original wdata */
2164 for (; i
< wdata
->nr_pages
; i
++) {
2165 SetPageError(wdata
->pages
[i
]);
2166 end_page_writeback(wdata
->pages
[i
]);
2167 put_page(wdata
->pages
[i
]);
2170 if (rc
!= 0 && !is_retryable_error(rc
))
2171 mapping_set_error(inode
->i_mapping
, rc
);
2172 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2176 cifs_writev_complete(struct work_struct
*work
)
2178 struct cifs_writedata
*wdata
= container_of(work
,
2179 struct cifs_writedata
, work
);
2180 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
2183 if (wdata
->result
== 0) {
2184 spin_lock(&inode
->i_lock
);
2185 cifs_update_eof(CIFS_I(inode
), wdata
->offset
, wdata
->bytes
);
2186 spin_unlock(&inode
->i_lock
);
2187 cifs_stats_bytes_written(tlink_tcon(wdata
->cfile
->tlink
),
2189 } else if (wdata
->sync_mode
== WB_SYNC_ALL
&& wdata
->result
== -EAGAIN
)
2190 return cifs_writev_requeue(wdata
);
2192 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
2193 struct page
*page
= wdata
->pages
[i
];
2194 if (wdata
->result
== -EAGAIN
)
2195 __set_page_dirty_nobuffers(page
);
2196 else if (wdata
->result
< 0)
2198 end_page_writeback(page
);
2201 if (wdata
->result
!= -EAGAIN
)
2202 mapping_set_error(inode
->i_mapping
, wdata
->result
);
2203 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2206 struct cifs_writedata
*
2207 cifs_writedata_alloc(unsigned int nr_pages
, work_func_t complete
)
2209 struct page
**pages
=
2210 kcalloc(nr_pages
, sizeof(struct page
*), GFP_NOFS
);
2212 return cifs_writedata_direct_alloc(pages
, complete
);
2217 struct cifs_writedata
*
2218 cifs_writedata_direct_alloc(struct page
**pages
, work_func_t complete
)
2220 struct cifs_writedata
*wdata
;
2222 wdata
= kzalloc(sizeof(*wdata
), GFP_NOFS
);
2223 if (wdata
!= NULL
) {
2224 wdata
->pages
= pages
;
2225 kref_init(&wdata
->refcount
);
2226 INIT_LIST_HEAD(&wdata
->list
);
2227 init_completion(&wdata
->done
);
2228 INIT_WORK(&wdata
->work
, complete
);
2234 * Check the mid_state and signature on received buffer (if any), and queue the
2235 * workqueue completion task.
2238 cifs_writev_callback(struct mid_q_entry
*mid
)
2240 struct cifs_writedata
*wdata
= mid
->callback_data
;
2241 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2242 unsigned int written
;
2243 WRITE_RSP
*smb
= (WRITE_RSP
*)mid
->resp_buf
;
2244 struct cifs_credits credits
= { .value
= 1, .instance
= 0 };
2246 switch (mid
->mid_state
) {
2247 case MID_RESPONSE_RECEIVED
:
2248 wdata
->result
= cifs_check_receive(mid
, tcon
->ses
->server
, 0);
2249 if (wdata
->result
!= 0)
2252 written
= le16_to_cpu(smb
->CountHigh
);
2254 written
+= le16_to_cpu(smb
->Count
);
2256 * Mask off high 16 bits when bytes written as returned
2257 * by the server is greater than bytes requested by the
2258 * client. OS/2 servers are known to set incorrect
2261 if (written
> wdata
->bytes
)
2264 if (written
< wdata
->bytes
)
2265 wdata
->result
= -ENOSPC
;
2267 wdata
->bytes
= written
;
2269 case MID_REQUEST_SUBMITTED
:
2270 case MID_RETRY_NEEDED
:
2271 wdata
->result
= -EAGAIN
;
2274 wdata
->result
= -EIO
;
2278 queue_work(cifsiod_wq
, &wdata
->work
);
2279 DeleteMidQEntry(mid
);
2280 add_credits(tcon
->ses
->server
, &credits
, 0);
2283 /* cifs_async_writev - send an async write, and set up mid to handle result */
2285 cifs_async_writev(struct cifs_writedata
*wdata
,
2286 void (*release
)(struct kref
*kref
))
2289 WRITE_REQ
*smb
= NULL
;
2291 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2293 struct smb_rqst rqst
= { };
2295 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2299 if (wdata
->offset
>> 32 > 0) {
2300 /* can not handle big offset for old srv */
2305 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **)&smb
);
2307 goto async_writev_out
;
2309 smb
->hdr
.Pid
= cpu_to_le16((__u16
)wdata
->pid
);
2310 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(wdata
->pid
>> 16));
2312 smb
->AndXCommand
= 0xFF; /* none */
2313 smb
->Fid
= wdata
->cfile
->fid
.netfid
;
2314 smb
->OffsetLow
= cpu_to_le32(wdata
->offset
& 0xFFFFFFFF);
2316 smb
->OffsetHigh
= cpu_to_le32(wdata
->offset
>> 32);
2317 smb
->Reserved
= 0xFFFFFFFF;
2322 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2324 /* 4 for RFC1001 length + 1 for BCC */
2326 iov
[0].iov_base
= smb
;
2327 iov
[1].iov_len
= get_rfc1002_length(smb
) + 1;
2328 iov
[1].iov_base
= (char *)smb
+ 4;
2332 rqst
.rq_pages
= wdata
->pages
;
2333 rqst
.rq_offset
= wdata
->page_offset
;
2334 rqst
.rq_npages
= wdata
->nr_pages
;
2335 rqst
.rq_pagesz
= wdata
->pagesz
;
2336 rqst
.rq_tailsz
= wdata
->tailsz
;
2338 cifs_dbg(FYI
, "async write at %llu %u bytes\n",
2339 wdata
->offset
, wdata
->bytes
);
2341 smb
->DataLengthLow
= cpu_to_le16(wdata
->bytes
& 0xFFFF);
2342 smb
->DataLengthHigh
= cpu_to_le16(wdata
->bytes
>> 16);
2345 inc_rfc1001_len(&smb
->hdr
, wdata
->bytes
+ 1);
2346 put_bcc(wdata
->bytes
+ 1, &smb
->hdr
);
2349 struct smb_com_writex_req
*smbw
=
2350 (struct smb_com_writex_req
*)smb
;
2351 inc_rfc1001_len(&smbw
->hdr
, wdata
->bytes
+ 5);
2352 put_bcc(wdata
->bytes
+ 5, &smbw
->hdr
);
2353 iov
[1].iov_len
+= 4; /* pad bigger by four bytes */
2356 kref_get(&wdata
->refcount
);
2357 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, NULL
,
2358 cifs_writev_callback
, NULL
, wdata
, 0, NULL
);
2361 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2363 kref_put(&wdata
->refcount
, release
);
2366 cifs_small_buf_release(smb
);
2371 CIFSSMBWrite2(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
2372 unsigned int *nbytes
, struct kvec
*iov
, int n_vec
)
2375 WRITE_REQ
*pSMB
= NULL
;
2378 int resp_buf_type
= 0;
2379 __u32 pid
= io_parms
->pid
;
2380 __u16 netfid
= io_parms
->netfid
;
2381 __u64 offset
= io_parms
->offset
;
2382 struct cifs_tcon
*tcon
= io_parms
->tcon
;
2383 unsigned int count
= io_parms
->length
;
2384 struct kvec rsp_iov
;
2388 cifs_dbg(FYI
, "write2 at %lld %d bytes\n", (long long)offset
, count
);
2390 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2394 if ((offset
>> 32) > 0) {
2395 /* can not handle big offset for old srv */
2399 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
);
2403 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
2404 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
2406 /* tcon and ses pointer are checked in smb_init */
2407 if (tcon
->ses
->server
== NULL
)
2408 return -ECONNABORTED
;
2410 pSMB
->AndXCommand
= 0xFF; /* none */
2412 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
2414 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
2415 pSMB
->Reserved
= 0xFFFFFFFF;
2416 pSMB
->WriteMode
= 0;
2417 pSMB
->Remaining
= 0;
2420 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2422 pSMB
->DataLengthLow
= cpu_to_le16(count
& 0xFFFF);
2423 pSMB
->DataLengthHigh
= cpu_to_le16(count
>> 16);
2424 /* header + 1 byte pad */
2425 smb_hdr_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 1;
2427 inc_rfc1001_len(pSMB
, count
+ 1);
2428 else /* wct == 12 */
2429 inc_rfc1001_len(pSMB
, count
+ 5); /* smb data starts later */
2431 pSMB
->ByteCount
= cpu_to_le16(count
+ 1);
2432 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2433 struct smb_com_writex_req
*pSMBW
=
2434 (struct smb_com_writex_req
*)pSMB
;
2435 pSMBW
->ByteCount
= cpu_to_le16(count
+ 5);
2437 iov
[0].iov_base
= pSMB
;
2439 iov
[0].iov_len
= smb_hdr_len
+ 4;
2440 else /* wct == 12 pad bigger by four bytes */
2441 iov
[0].iov_len
= smb_hdr_len
+ 8;
2443 rc
= SendReceive2(xid
, tcon
->ses
, iov
, n_vec
+ 1, &resp_buf_type
, 0,
2445 cifs_small_buf_release(pSMB
);
2446 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2448 cifs_dbg(FYI
, "Send error Write2 = %d\n", rc
);
2449 } else if (resp_buf_type
== 0) {
2450 /* presumably this can not happen, but best to be safe */
2453 WRITE_RSP
*pSMBr
= (WRITE_RSP
*)rsp_iov
.iov_base
;
2454 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2455 *nbytes
= (*nbytes
) << 16;
2456 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2459 * Mask off high 16 bits when bytes written as returned by the
2460 * server is greater than bytes requested by the client. OS/2
2461 * servers are known to set incorrect CountHigh values.
2463 if (*nbytes
> count
)
2467 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2469 /* Note: On -EAGAIN error only caller can retry on handle based calls
2470 since file handle passed in no longer valid */
2475 int cifs_lockv(const unsigned int xid
, struct cifs_tcon
*tcon
,
2476 const __u16 netfid
, const __u8 lock_type
, const __u32 num_unlock
,
2477 const __u32 num_lock
, LOCKING_ANDX_RANGE
*buf
)
2480 LOCK_REQ
*pSMB
= NULL
;
2482 struct kvec rsp_iov
;
2486 cifs_dbg(FYI
, "cifs_lockv num lock %d num unlock %d\n",
2487 num_lock
, num_unlock
);
2489 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2494 pSMB
->NumberOfLocks
= cpu_to_le16(num_lock
);
2495 pSMB
->NumberOfUnlocks
= cpu_to_le16(num_unlock
);
2496 pSMB
->LockType
= lock_type
;
2497 pSMB
->AndXCommand
= 0xFF; /* none */
2498 pSMB
->Fid
= netfid
; /* netfid stays le */
2500 count
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2501 inc_rfc1001_len(pSMB
, count
);
2502 pSMB
->ByteCount
= cpu_to_le16(count
);
2504 iov
[0].iov_base
= (char *)pSMB
;
2505 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4 -
2506 (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2507 iov
[1].iov_base
= (char *)buf
;
2508 iov
[1].iov_len
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2510 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2511 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 2, &resp_buf_type
,
2512 CIFS_NO_RSP_BUF
, &rsp_iov
);
2513 cifs_small_buf_release(pSMB
);
2515 cifs_dbg(FYI
, "Send error in cifs_lockv = %d\n", rc
);
2521 CIFSSMBLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2522 const __u16 smb_file_id
, const __u32 netpid
, const __u64 len
,
2523 const __u64 offset
, const __u32 numUnlock
,
2524 const __u32 numLock
, const __u8 lockType
,
2525 const bool waitFlag
, const __u8 oplock_level
)
2528 LOCK_REQ
*pSMB
= NULL
;
2529 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2534 cifs_dbg(FYI
, "CIFSSMBLock timeout %d numLock %d\n",
2535 (int)waitFlag
, numLock
);
2536 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2541 if (lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
2542 /* no response expected */
2543 flags
= CIFS_NO_SRV_RSP
| CIFS_NON_BLOCKING
| CIFS_OBREAK_OP
;
2545 } else if (waitFlag
) {
2546 flags
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2547 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
2552 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
2553 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
2554 pSMB
->LockType
= lockType
;
2555 pSMB
->OplockLevel
= oplock_level
;
2556 pSMB
->AndXCommand
= 0xFF; /* none */
2557 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
2559 if ((numLock
!= 0) || (numUnlock
!= 0)) {
2560 pSMB
->Locks
[0].Pid
= cpu_to_le16(netpid
);
2561 /* BB where to store pid high? */
2562 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
2563 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
2564 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
2565 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
2566 count
= sizeof(LOCKING_ANDX_RANGE
);
2571 inc_rfc1001_len(pSMB
, count
);
2572 pSMB
->ByteCount
= cpu_to_le16(count
);
2575 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2576 (struct smb_hdr
*) pSMB
, &bytes_returned
);
2578 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)pSMB
, flags
);
2579 cifs_small_buf_release(pSMB
);
2580 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2582 cifs_dbg(FYI
, "Send error in Lock = %d\n", rc
);
2584 /* Note: On -EAGAIN error only caller can retry on handle based calls
2585 since file handle passed in no longer valid */
2590 CIFSSMBPosixLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2591 const __u16 smb_file_id
, const __u32 netpid
,
2592 const loff_t start_offset
, const __u64 len
,
2593 struct file_lock
*pLockData
, const __u16 lock_type
,
2594 const bool waitFlag
)
2596 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2597 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2598 struct cifs_posix_lock
*parm_data
;
2601 int bytes_returned
= 0;
2602 int resp_buf_type
= 0;
2603 __u16 params
, param_offset
, offset
, byte_count
, count
;
2605 struct kvec rsp_iov
;
2607 cifs_dbg(FYI
, "Posix Lock\n");
2609 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
2614 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)pSMB
;
2617 pSMB
->MaxSetupCount
= 0;
2620 pSMB
->Reserved2
= 0;
2621 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2622 offset
= param_offset
+ params
;
2624 count
= sizeof(struct cifs_posix_lock
);
2625 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2626 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2627 pSMB
->SetupCount
= 1;
2628 pSMB
->Reserved3
= 0;
2630 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
2632 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2633 byte_count
= 3 /* pad */ + params
+ count
;
2634 pSMB
->DataCount
= cpu_to_le16(count
);
2635 pSMB
->ParameterCount
= cpu_to_le16(params
);
2636 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2637 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2638 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2639 parm_data
= (struct cifs_posix_lock
*)
2640 (((char *) &pSMB
->hdr
.Protocol
) + offset
);
2642 parm_data
->lock_type
= cpu_to_le16(lock_type
);
2644 timeout
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2645 parm_data
->lock_flags
= cpu_to_le16(1);
2646 pSMB
->Timeout
= cpu_to_le32(-1);
2650 parm_data
->pid
= cpu_to_le32(netpid
);
2651 parm_data
->start
= cpu_to_le64(start_offset
);
2652 parm_data
->length
= cpu_to_le64(len
); /* normalize negative numbers */
2654 pSMB
->DataOffset
= cpu_to_le16(offset
);
2655 pSMB
->Fid
= smb_file_id
;
2656 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_LOCK
);
2657 pSMB
->Reserved4
= 0;
2658 inc_rfc1001_len(pSMB
, byte_count
);
2659 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2661 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2662 (struct smb_hdr
*) pSMBr
, &bytes_returned
);
2664 iov
[0].iov_base
= (char *)pSMB
;
2665 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
2666 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
2667 &resp_buf_type
, timeout
, &rsp_iov
);
2668 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)rsp_iov
.iov_base
;
2670 cifs_small_buf_release(pSMB
);
2673 cifs_dbg(FYI
, "Send error in Posix Lock = %d\n", rc
);
2674 } else if (pLockData
) {
2675 /* lock structure can be returned on get */
2678 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2680 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(*parm_data
)) {
2681 rc
= -EIO
; /* bad smb */
2684 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
2685 data_count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2686 if (data_count
< sizeof(struct cifs_posix_lock
)) {
2690 parm_data
= (struct cifs_posix_lock
*)
2691 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2692 if (parm_data
->lock_type
== cpu_to_le16(CIFS_UNLCK
))
2693 pLockData
->fl_type
= F_UNLCK
;
2695 if (parm_data
->lock_type
==
2696 cpu_to_le16(CIFS_RDLCK
))
2697 pLockData
->fl_type
= F_RDLCK
;
2698 else if (parm_data
->lock_type
==
2699 cpu_to_le16(CIFS_WRLCK
))
2700 pLockData
->fl_type
= F_WRLCK
;
2702 pLockData
->fl_start
= le64_to_cpu(parm_data
->start
);
2703 pLockData
->fl_end
= pLockData
->fl_start
+
2704 le64_to_cpu(parm_data
->length
) - 1;
2705 pLockData
->fl_pid
= -le32_to_cpu(parm_data
->pid
);
2710 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2712 /* Note: On -EAGAIN error only caller can retry on handle based calls
2713 since file handle passed in no longer valid */
2720 CIFSSMBClose(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2723 CLOSE_REQ
*pSMB
= NULL
;
2724 cifs_dbg(FYI
, "In CIFSSMBClose\n");
2726 /* do not retry on dead session on close */
2727 rc
= small_smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
);
2733 pSMB
->FileID
= (__u16
) smb_file_id
;
2734 pSMB
->LastWriteTime
= 0xFFFFFFFF;
2735 pSMB
->ByteCount
= 0;
2736 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2737 cifs_small_buf_release(pSMB
);
2738 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_closes
);
2741 /* EINTR is expected when user ctl-c to kill app */
2742 cifs_dbg(VFS
, "Send error in Close = %d\n", rc
);
2746 /* Since session is dead, file will be closed on server already */
2754 CIFSSMBFlush(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2757 FLUSH_REQ
*pSMB
= NULL
;
2758 cifs_dbg(FYI
, "In CIFSSMBFlush\n");
2760 rc
= small_smb_init(SMB_COM_FLUSH
, 1, tcon
, (void **) &pSMB
);
2764 pSMB
->FileID
= (__u16
) smb_file_id
;
2765 pSMB
->ByteCount
= 0;
2766 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2767 cifs_small_buf_release(pSMB
);
2768 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_flushes
);
2770 cifs_dbg(VFS
, "Send error in Flush = %d\n", rc
);
2776 CIFSSMBRename(const unsigned int xid
, struct cifs_tcon
*tcon
,
2777 const char *from_name
, const char *to_name
,
2778 struct cifs_sb_info
*cifs_sb
)
2781 RENAME_REQ
*pSMB
= NULL
;
2782 RENAME_RSP
*pSMBr
= NULL
;
2784 int name_len
, name_len2
;
2786 int remap
= cifs_remap(cifs_sb
);
2788 cifs_dbg(FYI
, "In CIFSSMBRename\n");
2790 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
2795 pSMB
->BufferFormat
= 0x04;
2796 pSMB
->SearchAttributes
=
2797 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2800 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2801 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2802 from_name
, PATH_MAX
,
2803 cifs_sb
->local_nls
, remap
);
2804 name_len
++; /* trailing null */
2806 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2807 /* protocol requires ASCII signature byte on Unicode string */
2808 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2810 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2811 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2813 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2814 name_len2
*= 2; /* convert to bytes */
2816 name_len
= copy_path_name(pSMB
->OldFileName
, from_name
);
2817 name_len2
= copy_path_name(pSMB
->OldFileName
+name_len
+1, to_name
);
2818 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2819 name_len2
++; /* signature byte */
2822 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2823 inc_rfc1001_len(pSMB
, count
);
2824 pSMB
->ByteCount
= cpu_to_le16(count
);
2826 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2827 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2828 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_renames
);
2830 cifs_dbg(FYI
, "Send error in rename = %d\n", rc
);
2832 cifs_buf_release(pSMB
);
2840 int CIFSSMBRenameOpenFile(const unsigned int xid
, struct cifs_tcon
*pTcon
,
2841 int netfid
, const char *target_name
,
2842 const struct nls_table
*nls_codepage
, int remap
)
2844 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2845 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2846 struct set_file_rename
*rename_info
;
2848 char dummy_string
[30];
2850 int bytes_returned
= 0;
2852 __u16 params
, param_offset
, offset
, count
, byte_count
;
2854 cifs_dbg(FYI
, "Rename to File by handle\n");
2855 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
2861 pSMB
->MaxSetupCount
= 0;
2865 pSMB
->Reserved2
= 0;
2866 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2867 offset
= param_offset
+ params
;
2869 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2870 rename_info
= (struct set_file_rename
*) data_offset
;
2871 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2872 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2873 pSMB
->SetupCount
= 1;
2874 pSMB
->Reserved3
= 0;
2875 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2876 byte_count
= 3 /* pad */ + params
;
2877 pSMB
->ParameterCount
= cpu_to_le16(params
);
2878 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2879 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2880 pSMB
->DataOffset
= cpu_to_le16(offset
);
2881 /* construct random name ".cifs_tmp<inodenum><mid>" */
2882 rename_info
->overwrite
= cpu_to_le32(1);
2883 rename_info
->root_fid
= 0;
2884 /* unicode only call */
2885 if (target_name
== NULL
) {
2886 sprintf(dummy_string
, "cifs%x", pSMB
->hdr
.Mid
);
2888 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2889 dummy_string
, 24, nls_codepage
, remap
);
2892 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2893 target_name
, PATH_MAX
, nls_codepage
,
2896 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
2897 count
= 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str
);
2898 byte_count
+= count
;
2899 pSMB
->DataCount
= cpu_to_le16(count
);
2900 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2902 pSMB
->InformationLevel
=
2903 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
2904 pSMB
->Reserved4
= 0;
2905 inc_rfc1001_len(pSMB
, byte_count
);
2906 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2907 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
2908 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2909 cifs_stats_inc(&pTcon
->stats
.cifs_stats
.num_t2renames
);
2911 cifs_dbg(FYI
, "Send error in Rename (by file handle) = %d\n",
2914 cifs_buf_release(pSMB
);
2916 /* Note: On -EAGAIN error only caller can retry on handle based calls
2917 since file handle passed in no longer valid */
2923 CIFSSMBCopy(const unsigned int xid
, struct cifs_tcon
*tcon
,
2924 const char *fromName
, const __u16 target_tid
, const char *toName
,
2925 const int flags
, const struct nls_table
*nls_codepage
, int remap
)
2928 COPY_REQ
*pSMB
= NULL
;
2929 COPY_RSP
*pSMBr
= NULL
;
2931 int name_len
, name_len2
;
2934 cifs_dbg(FYI
, "In CIFSSMBCopy\n");
2936 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
2941 pSMB
->BufferFormat
= 0x04;
2942 pSMB
->Tid2
= target_tid
;
2944 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
2946 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2947 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2948 fromName
, PATH_MAX
, nls_codepage
,
2950 name_len
++; /* trailing null */
2952 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2953 /* protocol requires ASCII signature byte on Unicode string */
2954 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2956 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2957 toName
, PATH_MAX
, nls_codepage
, remap
);
2958 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2959 name_len2
*= 2; /* convert to bytes */
2961 name_len
= copy_path_name(pSMB
->OldFileName
, fromName
);
2962 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2963 name_len2
= copy_path_name(pSMB
->OldFileName
+name_len
+1, toName
);
2964 name_len2
++; /* signature byte */
2967 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2968 inc_rfc1001_len(pSMB
, count
);
2969 pSMB
->ByteCount
= cpu_to_le16(count
);
2971 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2972 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2974 cifs_dbg(FYI
, "Send error in copy = %d with %d files copied\n",
2975 rc
, le16_to_cpu(pSMBr
->CopyCount
));
2977 cifs_buf_release(pSMB
);
2986 CIFSUnixCreateSymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2987 const char *fromName
, const char *toName
,
2988 const struct nls_table
*nls_codepage
, int remap
)
2990 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2991 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2994 int name_len_target
;
2996 int bytes_returned
= 0;
2997 __u16 params
, param_offset
, offset
, byte_count
;
2999 cifs_dbg(FYI
, "In Symlink Unix style\n");
3001 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3006 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3008 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fromName
,
3009 /* find define for this maxpathcomponent */
3010 PATH_MAX
, nls_codepage
, remap
);
3011 name_len
++; /* trailing null */
3015 name_len
= copy_path_name(pSMB
->FileName
, fromName
);
3017 params
= 6 + name_len
;
3018 pSMB
->MaxSetupCount
= 0;
3022 pSMB
->Reserved2
= 0;
3023 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3024 InformationLevel
) - 4;
3025 offset
= param_offset
+ params
;
3027 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
3028 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3030 cifsConvertToUTF16((__le16
*) data_offset
, toName
,
3031 /* find define for this maxpathcomponent */
3032 PATH_MAX
, nls_codepage
, remap
);
3033 name_len_target
++; /* trailing null */
3034 name_len_target
*= 2;
3036 name_len_target
= copy_path_name(data_offset
, toName
);
3039 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3040 /* BB find exact max on data count below from sess */
3041 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3042 pSMB
->SetupCount
= 1;
3043 pSMB
->Reserved3
= 0;
3044 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3045 byte_count
= 3 /* pad */ + params
+ name_len_target
;
3046 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
3047 pSMB
->ParameterCount
= cpu_to_le16(params
);
3048 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3049 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3050 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3051 pSMB
->DataOffset
= cpu_to_le16(offset
);
3052 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
3053 pSMB
->Reserved4
= 0;
3054 inc_rfc1001_len(pSMB
, byte_count
);
3055 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3056 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3057 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3058 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_symlinks
);
3060 cifs_dbg(FYI
, "Send error in SetPathInfo create symlink = %d\n",
3063 cifs_buf_release(pSMB
);
3066 goto createSymLinkRetry
;
3072 CIFSUnixCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3073 const char *fromName
, const char *toName
,
3074 const struct nls_table
*nls_codepage
, int remap
)
3076 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
3077 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
3080 int name_len_target
;
3082 int bytes_returned
= 0;
3083 __u16 params
, param_offset
, offset
, byte_count
;
3085 cifs_dbg(FYI
, "In Create Hard link Unix style\n");
3086 createHardLinkRetry
:
3087 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3092 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3093 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->FileName
, toName
,
3094 PATH_MAX
, nls_codepage
, remap
);
3095 name_len
++; /* trailing null */
3099 name_len
= copy_path_name(pSMB
->FileName
, toName
);
3101 params
= 6 + name_len
;
3102 pSMB
->MaxSetupCount
= 0;
3106 pSMB
->Reserved2
= 0;
3107 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3108 InformationLevel
) - 4;
3109 offset
= param_offset
+ params
;
3111 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
3112 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3114 cifsConvertToUTF16((__le16
*) data_offset
, fromName
,
3115 PATH_MAX
, nls_codepage
, remap
);
3116 name_len_target
++; /* trailing null */
3117 name_len_target
*= 2;
3119 name_len_target
= copy_path_name(data_offset
, fromName
);
3122 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3123 /* BB find exact max on data count below from sess*/
3124 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3125 pSMB
->SetupCount
= 1;
3126 pSMB
->Reserved3
= 0;
3127 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3128 byte_count
= 3 /* pad */ + params
+ name_len_target
;
3129 pSMB
->ParameterCount
= cpu_to_le16(params
);
3130 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3131 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
3132 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3133 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3134 pSMB
->DataOffset
= cpu_to_le16(offset
);
3135 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
3136 pSMB
->Reserved4
= 0;
3137 inc_rfc1001_len(pSMB
, byte_count
);
3138 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3139 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3140 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3141 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3143 cifs_dbg(FYI
, "Send error in SetPathInfo (hard link) = %d\n",
3146 cifs_buf_release(pSMB
);
3148 goto createHardLinkRetry
;
3154 CIFSCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3155 const char *from_name
, const char *to_name
,
3156 struct cifs_sb_info
*cifs_sb
)
3159 NT_RENAME_REQ
*pSMB
= NULL
;
3160 RENAME_RSP
*pSMBr
= NULL
;
3162 int name_len
, name_len2
;
3164 int remap
= cifs_remap(cifs_sb
);
3166 cifs_dbg(FYI
, "In CIFSCreateHardLink\n");
3167 winCreateHardLinkRetry
:
3169 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
3174 pSMB
->SearchAttributes
=
3175 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
3177 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
3178 pSMB
->ClusterCount
= 0;
3180 pSMB
->BufferFormat
= 0x04;
3182 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3184 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, from_name
,
3185 PATH_MAX
, cifs_sb
->local_nls
, remap
);
3186 name_len
++; /* trailing null */
3189 /* protocol specifies ASCII buffer format (0x04) for unicode */
3190 pSMB
->OldFileName
[name_len
] = 0x04;
3191 pSMB
->OldFileName
[name_len
+ 1] = 0x00; /* pad */
3193 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
3194 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
3196 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
3197 name_len2
*= 2; /* convert to bytes */
3199 name_len
= copy_path_name(pSMB
->OldFileName
, from_name
);
3200 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
3201 name_len2
= copy_path_name(pSMB
->OldFileName
+name_len
+1, to_name
);
3202 name_len2
++; /* signature byte */
3205 count
= 1 /* string type byte */ + name_len
+ name_len2
;
3206 inc_rfc1001_len(pSMB
, count
);
3207 pSMB
->ByteCount
= cpu_to_le16(count
);
3209 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3210 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3211 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3213 cifs_dbg(FYI
, "Send error in hard link (NT rename) = %d\n", rc
);
3215 cifs_buf_release(pSMB
);
3217 goto winCreateHardLinkRetry
;
3223 CIFSSMBUnixQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3224 const unsigned char *searchName
, char **symlinkinfo
,
3225 const struct nls_table
*nls_codepage
, int remap
)
3227 /* SMB_QUERY_FILE_UNIX_LINK */
3228 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3229 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3233 __u16 params
, byte_count
;
3236 cifs_dbg(FYI
, "In QPathSymLinkInfo (Unix) for path %s\n", searchName
);
3239 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3244 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3246 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3247 searchName
, PATH_MAX
, nls_codepage
,
3249 name_len
++; /* trailing null */
3252 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
3255 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3256 pSMB
->TotalDataCount
= 0;
3257 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3258 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3259 pSMB
->MaxSetupCount
= 0;
3263 pSMB
->Reserved2
= 0;
3264 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3265 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3266 pSMB
->DataCount
= 0;
3267 pSMB
->DataOffset
= 0;
3268 pSMB
->SetupCount
= 1;
3269 pSMB
->Reserved3
= 0;
3270 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3271 byte_count
= params
+ 1 /* pad */ ;
3272 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3273 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3274 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
3275 pSMB
->Reserved4
= 0;
3276 inc_rfc1001_len(pSMB
, byte_count
);
3277 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3279 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3280 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3282 cifs_dbg(FYI
, "Send error in QuerySymLinkInfo = %d\n", rc
);
3284 /* 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)
3292 u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3294 data_start
= ((char *) &pSMBr
->hdr
.Protocol
) +
3295 le16_to_cpu(pSMBr
->t2
.DataOffset
);
3297 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3302 /* BB FIXME investigate remapping reserved chars here */
3303 *symlinkinfo
= cifs_strndup_from_utf16(data_start
,
3304 count
, is_unicode
, nls_codepage
);
3309 cifs_buf_release(pSMB
);
3311 goto querySymLinkRetry
;
3316 * Recent Windows versions now create symlinks more frequently
3317 * and they use the "reparse point" mechanism below. We can of course
3318 * do symlinks nicely to Samba and other servers which support the
3319 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3320 * "MF" symlinks optionally, but for recent Windows we really need to
3321 * reenable the code below and fix the cifs_symlink callers to handle this.
3322 * In the interim this code has been moved to its own config option so
3323 * it is not compiled in by default until callers fixed up and more tested.
3326 CIFSSMBQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3327 __u16 fid
, char **symlinkinfo
,
3328 const struct nls_table
*nls_codepage
)
3332 struct smb_com_transaction_ioctl_req
*pSMB
;
3333 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3335 unsigned int sub_len
;
3337 struct reparse_symlink_data
*reparse_buf
;
3338 struct reparse_posix_data
*posix_buf
;
3339 __u32 data_offset
, data_count
;
3342 cifs_dbg(FYI
, "In Windows reparse style QueryLink for fid %u\n", fid
);
3343 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3348 pSMB
->TotalParameterCount
= 0 ;
3349 pSMB
->TotalDataCount
= 0;
3350 pSMB
->MaxParameterCount
= cpu_to_le32(2);
3351 /* BB find exact data count max from sess structure BB */
3352 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3353 pSMB
->MaxSetupCount
= 4;
3355 pSMB
->ParameterOffset
= 0;
3356 pSMB
->DataCount
= 0;
3357 pSMB
->DataOffset
= 0;
3358 pSMB
->SetupCount
= 4;
3359 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3360 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3361 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
3362 pSMB
->IsFsctl
= 1; /* FSCTL */
3363 pSMB
->IsRootFlag
= 0;
3364 pSMB
->Fid
= fid
; /* file handle always le */
3365 pSMB
->ByteCount
= 0;
3367 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3368 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3370 cifs_dbg(FYI
, "Send error in QueryReparseLinkInfo = %d\n", rc
);
3374 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3375 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3376 if (get_bcc(&pSMBr
->hdr
) < 2 || data_offset
> 512) {
3377 /* BB also check enough total bytes returned */
3378 rc
= -EIO
; /* bad smb */
3381 if (!data_count
|| (data_count
> 2048)) {
3383 cifs_dbg(FYI
, "Invalid return data count on get reparse info ioctl\n");
3386 end_of_smb
= 2 + get_bcc(&pSMBr
->hdr
) + (char *)&pSMBr
->ByteCount
;
3387 reparse_buf
= (struct reparse_symlink_data
*)
3388 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
3389 if ((char *)reparse_buf
>= end_of_smb
) {
3393 if (reparse_buf
->ReparseTag
== cpu_to_le32(IO_REPARSE_TAG_NFS
)) {
3394 cifs_dbg(FYI
, "NFS style reparse tag\n");
3395 posix_buf
= (struct reparse_posix_data
*)reparse_buf
;
3397 if (posix_buf
->InodeType
!= cpu_to_le64(NFS_SPECFILE_LNK
)) {
3398 cifs_dbg(FYI
, "unsupported file type 0x%llx\n",
3399 le64_to_cpu(posix_buf
->InodeType
));
3404 sub_len
= le16_to_cpu(reparse_buf
->ReparseDataLength
);
3405 if (posix_buf
->PathBuffer
+ sub_len
> end_of_smb
) {
3406 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3410 *symlinkinfo
= cifs_strndup_from_utf16(posix_buf
->PathBuffer
,
3411 sub_len
, is_unicode
, nls_codepage
);
3413 } else if (reparse_buf
->ReparseTag
!=
3414 cpu_to_le32(IO_REPARSE_TAG_SYMLINK
)) {
3419 /* Reparse tag is NTFS symlink */
3420 sub_start
= le16_to_cpu(reparse_buf
->SubstituteNameOffset
) +
3421 reparse_buf
->PathBuffer
;
3422 sub_len
= le16_to_cpu(reparse_buf
->SubstituteNameLength
);
3423 if (sub_start
+ sub_len
> end_of_smb
) {
3424 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3428 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3433 /* BB FIXME investigate remapping reserved chars here */
3434 *symlinkinfo
= cifs_strndup_from_utf16(sub_start
, sub_len
, is_unicode
,
3439 cifs_buf_release(pSMB
);
3442 * Note: On -EAGAIN error only caller can retry on handle based calls
3443 * since file handle passed in no longer valid.
3449 CIFSSMB_set_compression(const unsigned int xid
, struct cifs_tcon
*tcon
,
3454 struct smb_com_transaction_compr_ioctl_req
*pSMB
;
3455 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3457 cifs_dbg(FYI
, "Set compression for %u\n", fid
);
3458 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3463 pSMB
->compression_state
= cpu_to_le16(COMPRESSION_FORMAT_DEFAULT
);
3465 pSMB
->TotalParameterCount
= 0;
3466 pSMB
->TotalDataCount
= cpu_to_le32(2);
3467 pSMB
->MaxParameterCount
= 0;
3468 pSMB
->MaxDataCount
= 0;
3469 pSMB
->MaxSetupCount
= 4;
3471 pSMB
->ParameterOffset
= 0;
3472 pSMB
->DataCount
= cpu_to_le32(2);
3474 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req
,
3475 compression_state
) - 4); /* 84 */
3476 pSMB
->SetupCount
= 4;
3477 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3478 pSMB
->ParameterCount
= 0;
3479 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_SET_COMPRESSION
);
3480 pSMB
->IsFsctl
= 1; /* FSCTL */
3481 pSMB
->IsRootFlag
= 0;
3482 pSMB
->Fid
= fid
; /* file handle always le */
3483 /* 3 byte pad, followed by 2 byte compress state */
3484 pSMB
->ByteCount
= cpu_to_le16(5);
3485 inc_rfc1001_len(pSMB
, 5);
3487 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3488 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3490 cifs_dbg(FYI
, "Send error in SetCompression = %d\n", rc
);
3492 cifs_buf_release(pSMB
);
3495 * Note: On -EAGAIN error only caller can retry on handle based calls
3496 * since file handle passed in no longer valid.
3502 #ifdef CONFIG_CIFS_POSIX
3504 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3505 static void cifs_convert_ace(struct posix_acl_xattr_entry
*ace
,
3506 struct cifs_posix_ace
*cifs_ace
)
3508 /* u8 cifs fields do not need le conversion */
3509 ace
->e_perm
= cpu_to_le16(cifs_ace
->cifs_e_perm
);
3510 ace
->e_tag
= cpu_to_le16(cifs_ace
->cifs_e_tag
);
3511 ace
->e_id
= cpu_to_le32(le64_to_cpu(cifs_ace
->cifs_uid
));
3513 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3514 ace->e_perm, ace->e_tag, ace->e_id);
3520 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3521 static int cifs_copy_posix_acl(char *trgt
, char *src
, const int buflen
,
3522 const int acl_type
, const int size_of_data_area
)
3527 struct cifs_posix_ace
*pACE
;
3528 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)src
;
3529 struct posix_acl_xattr_header
*local_acl
= (void *)trgt
;
3531 if (le16_to_cpu(cifs_acl
->version
) != CIFS_ACL_VERSION
)
3534 if (acl_type
== ACL_TYPE_ACCESS
) {
3535 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3536 pACE
= &cifs_acl
->ace_array
[0];
3537 size
= sizeof(struct cifs_posix_acl
);
3538 size
+= sizeof(struct cifs_posix_ace
) * count
;
3539 /* check if we would go beyond end of SMB */
3540 if (size_of_data_area
< size
) {
3541 cifs_dbg(FYI
, "bad CIFS POSIX ACL size %d vs. %d\n",
3542 size_of_data_area
, size
);
3545 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3546 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3547 size
= sizeof(struct cifs_posix_acl
);
3548 size
+= sizeof(struct cifs_posix_ace
) * count
;
3549 /* skip past access ACEs to get to default ACEs */
3550 pACE
= &cifs_acl
->ace_array
[count
];
3551 count
= le16_to_cpu(cifs_acl
->default_entry_count
);
3552 size
+= sizeof(struct cifs_posix_ace
) * count
;
3553 /* check if we would go beyond end of SMB */
3554 if (size_of_data_area
< size
)
3561 size
= posix_acl_xattr_size(count
);
3562 if ((buflen
== 0) || (local_acl
== NULL
)) {
3563 /* used to query ACL EA size */
3564 } else if (size
> buflen
) {
3566 } else /* buffer big enough */ {
3567 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3569 local_acl
->a_version
= cpu_to_le32(POSIX_ACL_XATTR_VERSION
);
3570 for (i
= 0; i
< count
; i
++) {
3571 cifs_convert_ace(&ace
[i
], pACE
);
3578 static void convert_ace_to_cifs_ace(struct cifs_posix_ace
*cifs_ace
,
3579 const struct posix_acl_xattr_entry
*local_ace
)
3581 cifs_ace
->cifs_e_perm
= le16_to_cpu(local_ace
->e_perm
);
3582 cifs_ace
->cifs_e_tag
= le16_to_cpu(local_ace
->e_tag
);
3583 /* BB is there a better way to handle the large uid? */
3584 if (local_ace
->e_id
== cpu_to_le32(-1)) {
3585 /* Probably no need to le convert -1 on any arch but can not hurt */
3586 cifs_ace
->cifs_uid
= cpu_to_le64(-1);
3588 cifs_ace
->cifs_uid
= cpu_to_le64(le32_to_cpu(local_ace
->e_id
));
3590 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3591 ace->e_perm, ace->e_tag, ace->e_id);
3595 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3596 static __u16
ACL_to_cifs_posix(char *parm_data
, const char *pACL
,
3597 const int buflen
, const int acl_type
)
3600 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)parm_data
;
3601 struct posix_acl_xattr_header
*local_acl
= (void *)pACL
;
3602 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3606 if ((buflen
== 0) || (pACL
== NULL
) || (cifs_acl
== NULL
))
3609 count
= posix_acl_xattr_count((size_t)buflen
);
3610 cifs_dbg(FYI
, "setting acl with %d entries from buf of length %d and version of %d\n",
3611 count
, buflen
, le32_to_cpu(local_acl
->a_version
));
3612 if (le32_to_cpu(local_acl
->a_version
) != 2) {
3613 cifs_dbg(FYI
, "unknown POSIX ACL version %d\n",
3614 le32_to_cpu(local_acl
->a_version
));
3617 cifs_acl
->version
= cpu_to_le16(1);
3618 if (acl_type
== ACL_TYPE_ACCESS
) {
3619 cifs_acl
->access_entry_count
= cpu_to_le16(count
);
3620 cifs_acl
->default_entry_count
= cpu_to_le16(0xFFFF);
3621 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3622 cifs_acl
->default_entry_count
= cpu_to_le16(count
);
3623 cifs_acl
->access_entry_count
= cpu_to_le16(0xFFFF);
3625 cifs_dbg(FYI
, "unknown ACL type %d\n", acl_type
);
3628 for (i
= 0; i
< count
; i
++)
3629 convert_ace_to_cifs_ace(&cifs_acl
->ace_array
[i
], &ace
[i
]);
3631 rc
= (__u16
)(count
* sizeof(struct cifs_posix_ace
));
3632 rc
+= sizeof(struct cifs_posix_acl
);
3633 /* BB add check to make sure ACL does not overflow SMB */
3639 CIFSSMBGetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3640 const unsigned char *searchName
,
3641 char *acl_inf
, const int buflen
, const int acl_type
,
3642 const struct nls_table
*nls_codepage
, int remap
)
3644 /* SMB_QUERY_POSIX_ACL */
3645 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3646 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3650 __u16 params
, byte_count
;
3652 cifs_dbg(FYI
, "In GetPosixACL (Unix) for path %s\n", searchName
);
3655 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3660 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3662 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3663 searchName
, PATH_MAX
, nls_codepage
,
3665 name_len
++; /* trailing null */
3667 pSMB
->FileName
[name_len
] = 0;
3668 pSMB
->FileName
[name_len
+1] = 0;
3670 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
3673 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3674 pSMB
->TotalDataCount
= 0;
3675 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3676 /* BB find exact max data count below from sess structure BB */
3677 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3678 pSMB
->MaxSetupCount
= 0;
3682 pSMB
->Reserved2
= 0;
3683 pSMB
->ParameterOffset
= cpu_to_le16(
3684 offsetof(struct smb_com_transaction2_qpi_req
,
3685 InformationLevel
) - 4);
3686 pSMB
->DataCount
= 0;
3687 pSMB
->DataOffset
= 0;
3688 pSMB
->SetupCount
= 1;
3689 pSMB
->Reserved3
= 0;
3690 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3691 byte_count
= params
+ 1 /* pad */ ;
3692 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3693 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3694 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_ACL
);
3695 pSMB
->Reserved4
= 0;
3696 inc_rfc1001_len(pSMB
, byte_count
);
3697 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3699 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3700 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3701 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3703 cifs_dbg(FYI
, "Send error in Query POSIX ACL = %d\n", rc
);
3705 /* decode response */
3707 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3708 /* BB also check enough total bytes returned */
3709 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3710 rc
= -EIO
; /* bad smb */
3712 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3713 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3714 rc
= cifs_copy_posix_acl(acl_inf
,
3715 (char *)&pSMBr
->hdr
.Protocol
+data_offset
,
3716 buflen
, acl_type
, count
);
3719 cifs_buf_release(pSMB
);
3726 CIFSSMBSetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3727 const unsigned char *fileName
,
3728 const char *local_acl
, const int buflen
,
3730 const struct nls_table
*nls_codepage
, int remap
)
3732 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3733 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3737 int bytes_returned
= 0;
3738 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
3740 cifs_dbg(FYI
, "In SetPosixACL (Unix) for path %s\n", fileName
);
3742 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3746 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3748 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
3749 PATH_MAX
, nls_codepage
, remap
);
3750 name_len
++; /* trailing null */
3753 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
3755 params
= 6 + name_len
;
3756 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3757 /* BB find max SMB size from sess */
3758 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3759 pSMB
->MaxSetupCount
= 0;
3763 pSMB
->Reserved2
= 0;
3764 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3765 InformationLevel
) - 4;
3766 offset
= param_offset
+ params
;
3767 parm_data
= ((char *) &pSMB
->hdr
.Protocol
) + offset
;
3768 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3770 /* convert to on the wire format for POSIX ACL */
3771 data_count
= ACL_to_cifs_posix(parm_data
, local_acl
, buflen
, acl_type
);
3773 if (data_count
== 0) {
3775 goto setACLerrorExit
;
3777 pSMB
->DataOffset
= cpu_to_le16(offset
);
3778 pSMB
->SetupCount
= 1;
3779 pSMB
->Reserved3
= 0;
3780 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3781 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_ACL
);
3782 byte_count
= 3 /* pad */ + params
+ data_count
;
3783 pSMB
->DataCount
= cpu_to_le16(data_count
);
3784 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3785 pSMB
->ParameterCount
= cpu_to_le16(params
);
3786 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3787 pSMB
->Reserved4
= 0;
3788 inc_rfc1001_len(pSMB
, byte_count
);
3789 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3790 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3791 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3793 cifs_dbg(FYI
, "Set POSIX ACL returned %d\n", rc
);
3796 cifs_buf_release(pSMB
);
3802 /* BB fix tabs in this function FIXME BB */
3804 CIFSGetExtAttr(const unsigned int xid
, struct cifs_tcon
*tcon
,
3805 const int netfid
, __u64
*pExtAttrBits
, __u64
*pMask
)
3808 struct smb_t2_qfi_req
*pSMB
= NULL
;
3809 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3811 __u16 params
, byte_count
;
3813 cifs_dbg(FYI
, "In GetExtAttr\n");
3818 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3823 params
= 2 /* level */ + 2 /* fid */;
3824 pSMB
->t2
.TotalDataCount
= 0;
3825 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3826 /* BB find exact max data count below from sess structure BB */
3827 pSMB
->t2
.MaxDataCount
= cpu_to_le16(4000);
3828 pSMB
->t2
.MaxSetupCount
= 0;
3829 pSMB
->t2
.Reserved
= 0;
3831 pSMB
->t2
.Timeout
= 0;
3832 pSMB
->t2
.Reserved2
= 0;
3833 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3835 pSMB
->t2
.DataCount
= 0;
3836 pSMB
->t2
.DataOffset
= 0;
3837 pSMB
->t2
.SetupCount
= 1;
3838 pSMB
->t2
.Reserved3
= 0;
3839 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3840 byte_count
= params
+ 1 /* pad */ ;
3841 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3842 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3843 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_ATTR_FLAGS
);
3846 inc_rfc1001_len(pSMB
, byte_count
);
3847 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3849 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3850 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3852 cifs_dbg(FYI
, "error %d in GetExtAttr\n", rc
);
3854 /* decode response */
3855 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3856 /* BB also check enough total bytes returned */
3857 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3858 /* If rc should we check for EOPNOSUPP and
3859 disable the srvino flag? or in caller? */
3860 rc
= -EIO
; /* bad smb */
3862 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3863 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3864 struct file_chattr_info
*pfinfo
;
3865 /* BB Do we need a cast or hash here ? */
3867 cifs_dbg(FYI
, "Illegal size ret in GetExtAttr\n");
3871 pfinfo
= (struct file_chattr_info
*)
3872 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
3873 *pExtAttrBits
= le64_to_cpu(pfinfo
->mode
);
3874 *pMask
= le64_to_cpu(pfinfo
->mask
);
3878 cifs_buf_release(pSMB
);
3880 goto GetExtAttrRetry
;
3884 #endif /* CONFIG_POSIX */
3887 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3888 * all NT TRANSACTS that we init here have total parm and data under about 400
3889 * bytes (to fit in small cifs buffer size), which is the case so far, it
3890 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3891 * returned setup area) and MaxParameterCount (returned parms size) must be set
3895 smb_init_nttransact(const __u16 sub_command
, const int setup_count
,
3896 const int parm_len
, struct cifs_tcon
*tcon
,
3901 struct smb_com_ntransact_req
*pSMB
;
3903 rc
= small_smb_init(SMB_COM_NT_TRANSACT
, 19 + setup_count
, tcon
,
3907 *ret_buf
= (void *)pSMB
;
3909 pSMB
->TotalParameterCount
= cpu_to_le32(parm_len
);
3910 pSMB
->TotalDataCount
= 0;
3911 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3912 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3913 pSMB
->DataCount
= pSMB
->TotalDataCount
;
3914 temp_offset
= offsetof(struct smb_com_ntransact_req
, Parms
) +
3915 (setup_count
* 2) - 4 /* for rfc1001 length itself */;
3916 pSMB
->ParameterOffset
= cpu_to_le32(temp_offset
);
3917 pSMB
->DataOffset
= cpu_to_le32(temp_offset
+ parm_len
);
3918 pSMB
->SetupCount
= setup_count
; /* no need to le convert byte fields */
3919 pSMB
->SubCommand
= cpu_to_le16(sub_command
);
3924 validate_ntransact(char *buf
, char **ppparm
, char **ppdata
,
3925 __u32
*pparmlen
, __u32
*pdatalen
)
3928 __u32 data_count
, data_offset
, parm_count
, parm_offset
;
3929 struct smb_com_ntransact_rsp
*pSMBr
;
3938 pSMBr
= (struct smb_com_ntransact_rsp
*)buf
;
3940 bcc
= get_bcc(&pSMBr
->hdr
);
3941 end_of_smb
= 2 /* sizeof byte count */ + bcc
+
3942 (char *)&pSMBr
->ByteCount
;
3944 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3945 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3946 parm_offset
= le32_to_cpu(pSMBr
->ParameterOffset
);
3947 parm_count
= le32_to_cpu(pSMBr
->ParameterCount
);
3949 *ppparm
= (char *)&pSMBr
->hdr
.Protocol
+ parm_offset
;
3950 *ppdata
= (char *)&pSMBr
->hdr
.Protocol
+ data_offset
;
3952 /* should we also check that parm and data areas do not overlap? */
3953 if (*ppparm
> end_of_smb
) {
3954 cifs_dbg(FYI
, "parms start after end of smb\n");
3956 } else if (parm_count
+ *ppparm
> end_of_smb
) {
3957 cifs_dbg(FYI
, "parm end after end of smb\n");
3959 } else if (*ppdata
> end_of_smb
) {
3960 cifs_dbg(FYI
, "data starts after end of smb\n");
3962 } else if (data_count
+ *ppdata
> end_of_smb
) {
3963 cifs_dbg(FYI
, "data %p + count %d (%p) past smb end %p start %p\n",
3964 *ppdata
, data_count
, (data_count
+ *ppdata
),
3967 } else if (parm_count
+ data_count
> bcc
) {
3968 cifs_dbg(FYI
, "parm count and data count larger than SMB\n");
3971 *pdatalen
= data_count
;
3972 *pparmlen
= parm_count
;
3976 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3978 CIFSSMBGetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3979 struct cifs_ntsd
**acl_inf
, __u32
*pbuflen
)
3983 QUERY_SEC_DESC_REQ
*pSMB
;
3985 struct kvec rsp_iov
;
3987 cifs_dbg(FYI
, "GetCifsACL\n");
3992 rc
= smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC
, 0,
3993 8 /* parm len */, tcon
, (void **) &pSMB
);
3997 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3998 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3999 pSMB
->MaxSetupCount
= 0;
4000 pSMB
->Fid
= fid
; /* file handle always le */
4001 pSMB
->AclFlags
= cpu_to_le32(CIFS_ACL_OWNER
| CIFS_ACL_GROUP
|
4003 pSMB
->ByteCount
= cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
4004 inc_rfc1001_len(pSMB
, 11);
4005 iov
[0].iov_base
= (char *)pSMB
;
4006 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
4008 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovec */, &buf_type
,
4010 cifs_small_buf_release(pSMB
);
4011 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
4013 cifs_dbg(FYI
, "Send error in QuerySecDesc = %d\n", rc
);
4014 } else { /* decode response */
4018 struct smb_com_ntransact_rsp
*pSMBr
;
4021 /* validate_nttransact */
4022 rc
= validate_ntransact(rsp_iov
.iov_base
, (char **)&parm
,
4023 &pdata
, &parm_len
, pbuflen
);
4026 pSMBr
= (struct smb_com_ntransact_rsp
*)rsp_iov
.iov_base
;
4028 cifs_dbg(FYI
, "smb %p parm %p data %p\n",
4029 pSMBr
, parm
, *acl_inf
);
4031 if (le32_to_cpu(pSMBr
->ParameterCount
) != 4) {
4032 rc
= -EIO
; /* bad smb */
4037 /* BB check that data area is minimum length and as big as acl_len */
4039 acl_len
= le32_to_cpu(*parm
);
4040 if (acl_len
!= *pbuflen
) {
4041 cifs_dbg(VFS
, "acl length %d does not match %d\n",
4043 if (*pbuflen
> acl_len
)
4047 /* check if buffer is big enough for the acl
4048 header followed by the smallest SID */
4049 if ((*pbuflen
< sizeof(struct cifs_ntsd
) + 8) ||
4050 (*pbuflen
>= 64 * 1024)) {
4051 cifs_dbg(VFS
, "bad acl length %d\n", *pbuflen
);
4055 *acl_inf
= kmemdup(pdata
, *pbuflen
, GFP_KERNEL
);
4056 if (*acl_inf
== NULL
) {
4063 free_rsp_buf(buf_type
, rsp_iov
.iov_base
);
4068 CIFSSMBSetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
4069 struct cifs_ntsd
*pntsd
, __u32 acllen
, int aclflag
)
4071 __u16 byte_count
, param_count
, data_count
, param_offset
, data_offset
;
4073 int bytes_returned
= 0;
4074 SET_SEC_DESC_REQ
*pSMB
= NULL
;
4078 rc
= smb_init(SMB_COM_NT_TRANSACT
, 19, tcon
, (void **) &pSMB
, &pSMBr
);
4082 pSMB
->MaxSetupCount
= 0;
4086 param_offset
= offsetof(struct smb_com_transaction_ssec_req
, Fid
) - 4;
4087 data_count
= acllen
;
4088 data_offset
= param_offset
+ param_count
;
4089 byte_count
= 3 /* pad */ + param_count
;
4091 pSMB
->DataCount
= cpu_to_le32(data_count
);
4092 pSMB
->TotalDataCount
= pSMB
->DataCount
;
4093 pSMB
->MaxParameterCount
= cpu_to_le32(4);
4094 pSMB
->MaxDataCount
= cpu_to_le32(16384);
4095 pSMB
->ParameterCount
= cpu_to_le32(param_count
);
4096 pSMB
->ParameterOffset
= cpu_to_le32(param_offset
);
4097 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4098 pSMB
->DataOffset
= cpu_to_le32(data_offset
);
4099 pSMB
->SetupCount
= 0;
4100 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC
);
4101 pSMB
->ByteCount
= cpu_to_le16(byte_count
+data_count
);
4103 pSMB
->Fid
= fid
; /* file handle always le */
4104 pSMB
->Reserved2
= 0;
4105 pSMB
->AclFlags
= cpu_to_le32(aclflag
);
4107 if (pntsd
&& acllen
) {
4108 memcpy((char *)pSMBr
+ offsetof(struct smb_hdr
, Protocol
) +
4109 data_offset
, pntsd
, acllen
);
4110 inc_rfc1001_len(pSMB
, byte_count
+ data_count
);
4112 inc_rfc1001_len(pSMB
, byte_count
);
4114 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4115 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4117 cifs_dbg(FYI
, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4118 bytes_returned
, rc
);
4120 cifs_dbg(FYI
, "Set CIFS ACL returned %d\n", rc
);
4121 cifs_buf_release(pSMB
);
4124 goto setCifsAclRetry
;
4130 /* Legacy Query Path Information call for lookup to old servers such
4133 SMBQueryInformation(const unsigned int xid
, struct cifs_tcon
*tcon
,
4134 const char *search_name
, FILE_ALL_INFO
*data
,
4135 const struct nls_table
*nls_codepage
, int remap
)
4137 QUERY_INFORMATION_REQ
*pSMB
;
4138 QUERY_INFORMATION_RSP
*pSMBr
;
4143 cifs_dbg(FYI
, "In SMBQPath path %s\n", search_name
);
4145 rc
= smb_init(SMB_COM_QUERY_INFORMATION
, 0, tcon
, (void **) &pSMB
,
4150 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4152 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4153 search_name
, PATH_MAX
, nls_codepage
,
4155 name_len
++; /* trailing null */
4158 name_len
= copy_path_name(pSMB
->FileName
, search_name
);
4160 pSMB
->BufferFormat
= 0x04;
4161 name_len
++; /* account for buffer type byte */
4162 inc_rfc1001_len(pSMB
, (__u16
)name_len
);
4163 pSMB
->ByteCount
= cpu_to_le16(name_len
);
4165 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4166 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4168 cifs_dbg(FYI
, "Send error in QueryInfo = %d\n", rc
);
4170 struct timespec64 ts
;
4171 __u32 time
= le32_to_cpu(pSMBr
->last_write_time
);
4173 /* decode response */
4174 /* BB FIXME - add time zone adjustment BB */
4175 memset(data
, 0, sizeof(FILE_ALL_INFO
));
4178 /* decode time fields */
4179 data
->ChangeTime
= cpu_to_le64(cifs_UnixTimeToNT(ts
));
4180 data
->LastWriteTime
= data
->ChangeTime
;
4181 data
->LastAccessTime
= 0;
4182 data
->AllocationSize
=
4183 cpu_to_le64(le32_to_cpu(pSMBr
->size
));
4184 data
->EndOfFile
= data
->AllocationSize
;
4186 cpu_to_le32(le16_to_cpu(pSMBr
->attr
));
4188 rc
= -EIO
; /* bad buffer passed in */
4190 cifs_buf_release(pSMB
);
4199 CIFSSMBQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4200 u16 netfid
, FILE_ALL_INFO
*pFindData
)
4202 struct smb_t2_qfi_req
*pSMB
= NULL
;
4203 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4206 __u16 params
, byte_count
;
4209 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4214 params
= 2 /* level */ + 2 /* fid */;
4215 pSMB
->t2
.TotalDataCount
= 0;
4216 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4217 /* BB find exact max data count below from sess structure BB */
4218 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4219 pSMB
->t2
.MaxSetupCount
= 0;
4220 pSMB
->t2
.Reserved
= 0;
4222 pSMB
->t2
.Timeout
= 0;
4223 pSMB
->t2
.Reserved2
= 0;
4224 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4226 pSMB
->t2
.DataCount
= 0;
4227 pSMB
->t2
.DataOffset
= 0;
4228 pSMB
->t2
.SetupCount
= 1;
4229 pSMB
->t2
.Reserved3
= 0;
4230 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4231 byte_count
= params
+ 1 /* pad */ ;
4232 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4233 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4234 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4237 inc_rfc1001_len(pSMB
, byte_count
);
4238 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4240 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4241 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4243 cifs_dbg(FYI
, "Send error in QFileInfo = %d", rc
);
4244 } else { /* decode response */
4245 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4247 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4249 else if (get_bcc(&pSMBr
->hdr
) < 40)
4250 rc
= -EIO
; /* bad smb */
4251 else if (pFindData
) {
4252 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4253 memcpy((char *) pFindData
,
4254 (char *) &pSMBr
->hdr
.Protocol
+
4255 data_offset
, sizeof(FILE_ALL_INFO
));
4259 cifs_buf_release(pSMB
);
4261 goto QFileInfoRetry
;
4267 CIFSSMBQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4268 const char *search_name
, FILE_ALL_INFO
*data
,
4269 int legacy
/* old style infolevel */,
4270 const struct nls_table
*nls_codepage
, int remap
)
4272 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4273 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4274 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4278 __u16 params
, byte_count
;
4280 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4282 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4287 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4289 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, search_name
,
4290 PATH_MAX
, nls_codepage
, remap
);
4291 name_len
++; /* trailing null */
4294 name_len
= copy_path_name(pSMB
->FileName
, search_name
);
4297 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4298 pSMB
->TotalDataCount
= 0;
4299 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4300 /* BB find exact max SMB PDU from sess structure BB */
4301 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4302 pSMB
->MaxSetupCount
= 0;
4306 pSMB
->Reserved2
= 0;
4307 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4308 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4309 pSMB
->DataCount
= 0;
4310 pSMB
->DataOffset
= 0;
4311 pSMB
->SetupCount
= 1;
4312 pSMB
->Reserved3
= 0;
4313 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4314 byte_count
= params
+ 1 /* pad */ ;
4315 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4316 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4318 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
4320 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_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
, "Send error in QPathInfo = %d\n", rc
);
4329 } else { /* decode response */
4330 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4332 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4334 else if (!legacy
&& get_bcc(&pSMBr
->hdr
) < 40)
4335 rc
= -EIO
; /* bad smb */
4336 else if (legacy
&& get_bcc(&pSMBr
->hdr
) < 24)
4337 rc
= -EIO
; /* 24 or 26 expected but we do not read
4341 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4344 * On legacy responses we do not read the last field,
4345 * EAsize, fortunately since it varies by subdialect and
4346 * also note it differs on Set vs Get, ie two bytes or 4
4347 * bytes depending but we don't care here.
4350 size
= sizeof(FILE_INFO_STANDARD
);
4352 size
= sizeof(FILE_ALL_INFO
);
4353 memcpy((char *) data
, (char *) &pSMBr
->hdr
.Protocol
+
4358 cifs_buf_release(pSMB
);
4360 goto QPathInfoRetry
;
4366 CIFSSMBUnixQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4367 u16 netfid
, FILE_UNIX_BASIC_INFO
*pFindData
)
4369 struct smb_t2_qfi_req
*pSMB
= NULL
;
4370 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4373 __u16 params
, byte_count
;
4376 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4381 params
= 2 /* level */ + 2 /* fid */;
4382 pSMB
->t2
.TotalDataCount
= 0;
4383 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4384 /* BB find exact max data count below from sess structure BB */
4385 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4386 pSMB
->t2
.MaxSetupCount
= 0;
4387 pSMB
->t2
.Reserved
= 0;
4389 pSMB
->t2
.Timeout
= 0;
4390 pSMB
->t2
.Reserved2
= 0;
4391 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4393 pSMB
->t2
.DataCount
= 0;
4394 pSMB
->t2
.DataOffset
= 0;
4395 pSMB
->t2
.SetupCount
= 1;
4396 pSMB
->t2
.Reserved3
= 0;
4397 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4398 byte_count
= params
+ 1 /* pad */ ;
4399 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4400 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4401 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4404 inc_rfc1001_len(pSMB
, byte_count
);
4405 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4407 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4408 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4410 cifs_dbg(FYI
, "Send error in UnixQFileInfo = %d", rc
);
4411 } else { /* decode response */
4412 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4414 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4415 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4416 rc
= -EIO
; /* bad smb */
4418 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4419 memcpy((char *) pFindData
,
4420 (char *) &pSMBr
->hdr
.Protocol
+
4422 sizeof(FILE_UNIX_BASIC_INFO
));
4426 cifs_buf_release(pSMB
);
4428 goto UnixQFileInfoRetry
;
4434 CIFSSMBUnixQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4435 const unsigned char *searchName
,
4436 FILE_UNIX_BASIC_INFO
*pFindData
,
4437 const struct nls_table
*nls_codepage
, int remap
)
4439 /* SMB_QUERY_FILE_UNIX_BASIC */
4440 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4441 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4443 int bytes_returned
= 0;
4445 __u16 params
, byte_count
;
4447 cifs_dbg(FYI
, "In QPathInfo (Unix) the path %s\n", searchName
);
4449 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4454 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4456 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4457 PATH_MAX
, nls_codepage
, remap
);
4458 name_len
++; /* trailing null */
4461 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
4464 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4465 pSMB
->TotalDataCount
= 0;
4466 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4467 /* BB find exact max SMB PDU from sess structure BB */
4468 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4469 pSMB
->MaxSetupCount
= 0;
4473 pSMB
->Reserved2
= 0;
4474 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4475 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4476 pSMB
->DataCount
= 0;
4477 pSMB
->DataOffset
= 0;
4478 pSMB
->SetupCount
= 1;
4479 pSMB
->Reserved3
= 0;
4480 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4481 byte_count
= params
+ 1 /* pad */ ;
4482 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4483 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4484 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4485 pSMB
->Reserved4
= 0;
4486 inc_rfc1001_len(pSMB
, byte_count
);
4487 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4489 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4490 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4492 cifs_dbg(FYI
, "Send error in UnixQPathInfo = %d", rc
);
4493 } else { /* decode response */
4494 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4496 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4497 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4498 rc
= -EIO
; /* bad smb */
4500 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4501 memcpy((char *) pFindData
,
4502 (char *) &pSMBr
->hdr
.Protocol
+
4504 sizeof(FILE_UNIX_BASIC_INFO
));
4507 cifs_buf_release(pSMB
);
4509 goto UnixQPathInfoRetry
;
4514 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4516 CIFSFindFirst(const unsigned int xid
, struct cifs_tcon
*tcon
,
4517 const char *searchName
, struct cifs_sb_info
*cifs_sb
,
4518 __u16
*pnetfid
, __u16 search_flags
,
4519 struct cifs_search_info
*psrch_inf
, bool msearch
)
4521 /* level 257 SMB_ */
4522 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
4523 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
4524 T2_FFIRST_RSP_PARMS
*parms
;
4526 int bytes_returned
= 0;
4527 int name_len
, remap
;
4528 __u16 params
, byte_count
;
4529 struct nls_table
*nls_codepage
;
4531 cifs_dbg(FYI
, "In FindFirst for %s\n", searchName
);
4534 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4539 nls_codepage
= cifs_sb
->local_nls
;
4540 remap
= cifs_remap(cifs_sb
);
4542 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4544 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4545 PATH_MAX
, nls_codepage
, remap
);
4546 /* We can not add the asterik earlier in case
4547 it got remapped to 0xF03A as if it were part of the
4548 directory name instead of a wildcard */
4551 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4552 pSMB
->FileName
[name_len
+1] = 0;
4553 pSMB
->FileName
[name_len
+2] = '*';
4554 pSMB
->FileName
[name_len
+3] = 0;
4555 name_len
+= 4; /* now the trailing null */
4556 /* null terminate just in case */
4557 pSMB
->FileName
[name_len
] = 0;
4558 pSMB
->FileName
[name_len
+1] = 0;
4562 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
4564 if (WARN_ON_ONCE(name_len
> PATH_MAX
-2))
4565 name_len
= PATH_MAX
-2;
4566 /* overwrite nul byte */
4567 pSMB
->FileName
[name_len
-1] = CIFS_DIR_SEP(cifs_sb
);
4568 pSMB
->FileName
[name_len
] = '*';
4569 pSMB
->FileName
[name_len
+1] = 0;
4574 params
= 12 + name_len
/* includes null */ ;
4575 pSMB
->TotalDataCount
= 0; /* no EAs */
4576 pSMB
->MaxParameterCount
= cpu_to_le16(10);
4577 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4578 pSMB
->MaxSetupCount
= 0;
4582 pSMB
->Reserved2
= 0;
4583 byte_count
= params
+ 1 /* pad */ ;
4584 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4585 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4586 pSMB
->ParameterOffset
= cpu_to_le16(
4587 offsetof(struct smb_com_transaction2_ffirst_req
, SearchAttributes
)
4589 pSMB
->DataCount
= 0;
4590 pSMB
->DataOffset
= 0;
4591 pSMB
->SetupCount
= 1; /* one byte, no need to make endian neutral */
4592 pSMB
->Reserved3
= 0;
4593 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
4594 pSMB
->SearchAttributes
=
4595 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
4597 pSMB
->SearchCount
= cpu_to_le16(CIFSMaxBufSize
/sizeof(FILE_UNIX_INFO
));
4598 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4599 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4601 /* BB what should we set StorageType to? Does it matter? BB */
4602 pSMB
->SearchStorageType
= 0;
4603 inc_rfc1001_len(pSMB
, byte_count
);
4604 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4606 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4607 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4608 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_ffirst
);
4610 if (rc
) {/* BB add logic to retry regular search if Unix search
4611 rejected unexpectedly by server */
4612 /* BB Add code to handle unsupported level rc */
4613 cifs_dbg(FYI
, "Error in FindFirst = %d\n", rc
);
4615 cifs_buf_release(pSMB
);
4617 /* BB eventually could optimize out free and realloc of buf */
4620 goto findFirstRetry
;
4621 } else { /* decode response */
4622 /* BB remember to free buffer if error BB */
4623 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4627 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4628 psrch_inf
->unicode
= true;
4630 psrch_inf
->unicode
= false;
4632 psrch_inf
->ntwrk_buf_start
= (char *)pSMBr
;
4633 psrch_inf
->smallBuf
= false;
4634 psrch_inf
->srch_entries_start
=
4635 (char *) &pSMBr
->hdr
.Protocol
+
4636 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4637 parms
= (T2_FFIRST_RSP_PARMS
*)((char *) &pSMBr
->hdr
.Protocol
+
4638 le16_to_cpu(pSMBr
->t2
.ParameterOffset
));
4640 if (parms
->EndofSearch
)
4641 psrch_inf
->endOfSearch
= true;
4643 psrch_inf
->endOfSearch
= false;
4645 psrch_inf
->entries_in_buffer
=
4646 le16_to_cpu(parms
->SearchCount
);
4647 psrch_inf
->index_of_last_entry
= 2 /* skip . and .. */ +
4648 psrch_inf
->entries_in_buffer
;
4649 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4650 if (CIFSMaxBufSize
< lnoff
) {
4651 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4652 psrch_inf
->last_entry
= NULL
;
4656 psrch_inf
->last_entry
= psrch_inf
->srch_entries_start
+
4660 *pnetfid
= parms
->SearchHandle
;
4662 cifs_buf_release(pSMB
);
4669 int CIFSFindNext(const unsigned int xid
, struct cifs_tcon
*tcon
,
4670 __u16 searchHandle
, __u16 search_flags
,
4671 struct cifs_search_info
*psrch_inf
)
4673 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
4674 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
4675 T2_FNEXT_RSP_PARMS
*parms
;
4676 char *response_data
;
4679 unsigned int name_len
;
4680 __u16 params
, byte_count
;
4682 cifs_dbg(FYI
, "In FindNext\n");
4684 if (psrch_inf
->endOfSearch
)
4687 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4692 params
= 14; /* includes 2 bytes of null string, converted to LE below*/
4694 pSMB
->TotalDataCount
= 0; /* no EAs */
4695 pSMB
->MaxParameterCount
= cpu_to_le16(8);
4696 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4697 pSMB
->MaxSetupCount
= 0;
4701 pSMB
->Reserved2
= 0;
4702 pSMB
->ParameterOffset
= cpu_to_le16(
4703 offsetof(struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
4704 pSMB
->DataCount
= 0;
4705 pSMB
->DataOffset
= 0;
4706 pSMB
->SetupCount
= 1;
4707 pSMB
->Reserved3
= 0;
4708 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
4709 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
4711 cpu_to_le16(CIFSMaxBufSize
/ sizeof(FILE_UNIX_INFO
));
4712 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4713 pSMB
->ResumeKey
= psrch_inf
->resume_key
;
4714 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4716 name_len
= psrch_inf
->resume_name_len
;
4718 if (name_len
< PATH_MAX
) {
4719 memcpy(pSMB
->ResumeFileName
, psrch_inf
->presume_name
, name_len
);
4720 byte_count
+= name_len
;
4721 /* 14 byte parm len above enough for 2 byte null terminator */
4722 pSMB
->ResumeFileName
[name_len
] = 0;
4723 pSMB
->ResumeFileName
[name_len
+1] = 0;
4726 goto FNext2_err_exit
;
4728 byte_count
= params
+ 1 /* pad */ ;
4729 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4730 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4731 inc_rfc1001_len(pSMB
, byte_count
);
4732 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4734 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4735 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4736 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fnext
);
4739 psrch_inf
->endOfSearch
= true;
4740 cifs_buf_release(pSMB
);
4741 rc
= 0; /* search probably was closed at end of search*/
4743 cifs_dbg(FYI
, "FindNext returned = %d\n", rc
);
4744 } else { /* decode response */
4745 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4750 /* BB fixme add lock for file (srch_info) struct here */
4751 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4752 psrch_inf
->unicode
= true;
4754 psrch_inf
->unicode
= false;
4755 response_data
= (char *) &pSMBr
->hdr
.Protocol
+
4756 le16_to_cpu(pSMBr
->t2
.ParameterOffset
);
4757 parms
= (T2_FNEXT_RSP_PARMS
*)response_data
;
4758 response_data
= (char *)&pSMBr
->hdr
.Protocol
+
4759 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4760 if (psrch_inf
->smallBuf
)
4761 cifs_small_buf_release(
4762 psrch_inf
->ntwrk_buf_start
);
4764 cifs_buf_release(psrch_inf
->ntwrk_buf_start
);
4765 psrch_inf
->srch_entries_start
= response_data
;
4766 psrch_inf
->ntwrk_buf_start
= (char *)pSMB
;
4767 psrch_inf
->smallBuf
= false;
4768 if (parms
->EndofSearch
)
4769 psrch_inf
->endOfSearch
= true;
4771 psrch_inf
->endOfSearch
= false;
4772 psrch_inf
->entries_in_buffer
=
4773 le16_to_cpu(parms
->SearchCount
);
4774 psrch_inf
->index_of_last_entry
+=
4775 psrch_inf
->entries_in_buffer
;
4776 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4777 if (CIFSMaxBufSize
< lnoff
) {
4778 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4779 psrch_inf
->last_entry
= NULL
;
4782 psrch_inf
->last_entry
=
4783 psrch_inf
->srch_entries_start
+ lnoff
;
4785 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4786 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4788 /* BB fixme add unlock here */
4793 /* BB On error, should we leave previous search buf (and count and
4794 last entry fields) intact or free the previous one? */
4796 /* Note: On -EAGAIN error only caller can retry on handle based calls
4797 since file handle passed in no longer valid */
4800 cifs_buf_release(pSMB
);
4805 CIFSFindClose(const unsigned int xid
, struct cifs_tcon
*tcon
,
4806 const __u16 searchHandle
)
4809 FINDCLOSE_REQ
*pSMB
= NULL
;
4811 cifs_dbg(FYI
, "In CIFSSMBFindClose\n");
4812 rc
= small_smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **)&pSMB
);
4814 /* no sense returning error if session restarted
4815 as file handle has been closed */
4821 pSMB
->FileID
= searchHandle
;
4822 pSMB
->ByteCount
= 0;
4823 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
4824 cifs_small_buf_release(pSMB
);
4826 cifs_dbg(VFS
, "Send error in FindClose = %d\n", rc
);
4828 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fclose
);
4830 /* Since session is dead, search handle closed on server already */
4838 CIFSGetSrvInodeNumber(const unsigned int xid
, struct cifs_tcon
*tcon
,
4839 const char *search_name
, __u64
*inode_number
,
4840 const struct nls_table
*nls_codepage
, int remap
)
4843 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4844 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4845 int name_len
, bytes_returned
;
4846 __u16 params
, byte_count
;
4848 cifs_dbg(FYI
, "In GetSrvInodeNum for %s\n", search_name
);
4852 GetInodeNumberRetry
:
4853 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4858 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4860 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4861 search_name
, PATH_MAX
, nls_codepage
,
4863 name_len
++; /* trailing null */
4866 name_len
= copy_path_name(pSMB
->FileName
, search_name
);
4869 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
4870 pSMB
->TotalDataCount
= 0;
4871 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4872 /* BB find exact max data count below from sess structure BB */
4873 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4874 pSMB
->MaxSetupCount
= 0;
4878 pSMB
->Reserved2
= 0;
4879 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4880 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4881 pSMB
->DataCount
= 0;
4882 pSMB
->DataOffset
= 0;
4883 pSMB
->SetupCount
= 1;
4884 pSMB
->Reserved3
= 0;
4885 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4886 byte_count
= params
+ 1 /* pad */ ;
4887 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4888 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4889 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO
);
4890 pSMB
->Reserved4
= 0;
4891 inc_rfc1001_len(pSMB
, byte_count
);
4892 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4894 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4895 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4897 cifs_dbg(FYI
, "error %d in QueryInternalInfo\n", rc
);
4899 /* decode response */
4900 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4901 /* BB also check enough total bytes returned */
4902 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
4903 /* If rc should we check for EOPNOSUPP and
4904 disable the srvino flag? or in caller? */
4905 rc
= -EIO
; /* bad smb */
4907 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4908 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
4909 struct file_internal_info
*pfinfo
;
4910 /* BB Do we need a cast or hash here ? */
4912 cifs_dbg(FYI
, "Illegal size ret in QryIntrnlInf\n");
4914 goto GetInodeNumOut
;
4916 pfinfo
= (struct file_internal_info
*)
4917 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
4918 *inode_number
= le64_to_cpu(pfinfo
->UniqueId
);
4922 cifs_buf_release(pSMB
);
4924 goto GetInodeNumberRetry
;
4929 CIFSGetDFSRefer(const unsigned int xid
, struct cifs_ses
*ses
,
4930 const char *search_name
, struct dfs_info3_param
**target_nodes
,
4931 unsigned int *num_of_nodes
,
4932 const struct nls_table
*nls_codepage
, int remap
)
4934 /* TRANS2_GET_DFS_REFERRAL */
4935 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
4936 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
4940 __u16 params
, byte_count
;
4942 *target_nodes
= NULL
;
4944 cifs_dbg(FYI
, "In GetDFSRefer the path %s\n", search_name
);
4945 if (ses
== NULL
|| ses
->tcon_ipc
== NULL
)
4949 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, ses
->tcon_ipc
, (void **) &pSMB
,
4954 /* server pointer checked in called function,
4955 but should never be null here anyway */
4956 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
4957 pSMB
->hdr
.Tid
= ses
->tcon_ipc
->tid
;
4958 pSMB
->hdr
.Uid
= ses
->Suid
;
4959 if (ses
->capabilities
& CAP_STATUS32
)
4960 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
4961 if (ses
->capabilities
& CAP_DFS
)
4962 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
4964 if (ses
->capabilities
& CAP_UNICODE
) {
4965 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
4967 cifsConvertToUTF16((__le16
*) pSMB
->RequestFileName
,
4968 search_name
, PATH_MAX
, nls_codepage
,
4970 name_len
++; /* trailing null */
4972 } else { /* BB improve the check for buffer overruns BB */
4973 name_len
= copy_path_name(pSMB
->RequestFileName
, search_name
);
4976 if (ses
->server
->sign
)
4977 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
4979 pSMB
->hdr
.Uid
= ses
->Suid
;
4981 params
= 2 /* level */ + name_len
/*includes null */ ;
4982 pSMB
->TotalDataCount
= 0;
4983 pSMB
->DataCount
= 0;
4984 pSMB
->DataOffset
= 0;
4985 pSMB
->MaxParameterCount
= 0;
4986 /* BB find exact max SMB PDU from sess structure BB */
4987 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4988 pSMB
->MaxSetupCount
= 0;
4992 pSMB
->Reserved2
= 0;
4993 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4994 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
4995 pSMB
->SetupCount
= 1;
4996 pSMB
->Reserved3
= 0;
4997 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
4998 byte_count
= params
+ 3 /* pad */ ;
4999 pSMB
->ParameterCount
= cpu_to_le16(params
);
5000 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5001 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
5002 inc_rfc1001_len(pSMB
, byte_count
);
5003 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5005 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
5006 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5008 cifs_dbg(FYI
, "Send error in GetDFSRefer = %d\n", rc
);
5011 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5013 /* BB Also check if enough total bytes returned? */
5014 if (rc
|| get_bcc(&pSMBr
->hdr
) < 17) {
5015 rc
= -EIO
; /* bad smb */
5019 cifs_dbg(FYI
, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
5020 get_bcc(&pSMBr
->hdr
), le16_to_cpu(pSMBr
->t2
.DataOffset
));
5022 /* parse returned result into more usable form */
5023 rc
= parse_dfs_referrals(&pSMBr
->dfs_data
,
5024 le16_to_cpu(pSMBr
->t2
.DataCount
),
5025 num_of_nodes
, target_nodes
, nls_codepage
,
5027 (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) != 0);
5030 cifs_buf_release(pSMB
);
5038 /* Query File System Info such as free space to old servers such as Win 9x */
5040 SMBOldQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5041 struct kstatfs
*FSData
)
5043 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
5044 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5045 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5046 FILE_SYSTEM_ALLOC_INFO
*response_data
;
5048 int bytes_returned
= 0;
5049 __u16 params
, byte_count
;
5051 cifs_dbg(FYI
, "OldQFSInfo\n");
5053 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5058 params
= 2; /* level */
5059 pSMB
->TotalDataCount
= 0;
5060 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5061 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5062 pSMB
->MaxSetupCount
= 0;
5066 pSMB
->Reserved2
= 0;
5067 byte_count
= params
+ 1 /* pad */ ;
5068 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5069 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5070 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5071 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5072 pSMB
->DataCount
= 0;
5073 pSMB
->DataOffset
= 0;
5074 pSMB
->SetupCount
= 1;
5075 pSMB
->Reserved3
= 0;
5076 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5077 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_ALLOCATION
);
5078 inc_rfc1001_len(pSMB
, byte_count
);
5079 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5081 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5082 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5084 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5085 } else { /* decode response */
5086 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5088 if (rc
|| get_bcc(&pSMBr
->hdr
) < 18)
5089 rc
= -EIO
; /* bad smb */
5091 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5092 cifs_dbg(FYI
, "qfsinf resp BCC: %d Offset %d\n",
5093 get_bcc(&pSMBr
->hdr
), data_offset
);
5095 response_data
= (FILE_SYSTEM_ALLOC_INFO
*)
5096 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
5098 le16_to_cpu(response_data
->BytesPerSector
) *
5099 le32_to_cpu(response_data
->
5100 SectorsPerAllocationUnit
);
5102 * much prefer larger but if server doesn't report
5103 * a valid size than 4K is a reasonable minimum
5105 if (FSData
->f_bsize
< 512)
5106 FSData
->f_bsize
= 4096;
5109 le32_to_cpu(response_data
->TotalAllocationUnits
);
5110 FSData
->f_bfree
= FSData
->f_bavail
=
5111 le32_to_cpu(response_data
->FreeAllocationUnits
);
5112 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5113 (unsigned long long)FSData
->f_blocks
,
5114 (unsigned long long)FSData
->f_bfree
,
5118 cifs_buf_release(pSMB
);
5121 goto oldQFSInfoRetry
;
5127 CIFSSMBQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5128 struct kstatfs
*FSData
)
5130 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5131 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5132 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5133 FILE_SYSTEM_INFO
*response_data
;
5135 int bytes_returned
= 0;
5136 __u16 params
, byte_count
;
5138 cifs_dbg(FYI
, "In QFSInfo\n");
5140 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5145 params
= 2; /* level */
5146 pSMB
->TotalDataCount
= 0;
5147 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5148 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5149 pSMB
->MaxSetupCount
= 0;
5153 pSMB
->Reserved2
= 0;
5154 byte_count
= params
+ 1 /* pad */ ;
5155 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5156 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5157 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5158 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5159 pSMB
->DataCount
= 0;
5160 pSMB
->DataOffset
= 0;
5161 pSMB
->SetupCount
= 1;
5162 pSMB
->Reserved3
= 0;
5163 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5164 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
5165 inc_rfc1001_len(pSMB
, byte_count
);
5166 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5168 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5169 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5171 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5172 } else { /* decode response */
5173 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5175 if (rc
|| get_bcc(&pSMBr
->hdr
) < 24)
5176 rc
= -EIO
; /* bad smb */
5178 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5182 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5185 le32_to_cpu(response_data
->BytesPerSector
) *
5186 le32_to_cpu(response_data
->
5187 SectorsPerAllocationUnit
);
5189 * much prefer larger but if server doesn't report
5190 * a valid size than 4K is a reasonable minimum
5192 if (FSData
->f_bsize
< 512)
5193 FSData
->f_bsize
= 4096;
5196 le64_to_cpu(response_data
->TotalAllocationUnits
);
5197 FSData
->f_bfree
= FSData
->f_bavail
=
5198 le64_to_cpu(response_data
->FreeAllocationUnits
);
5199 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5200 (unsigned long long)FSData
->f_blocks
,
5201 (unsigned long long)FSData
->f_bfree
,
5205 cifs_buf_release(pSMB
);
5214 CIFSSMBQFSAttributeInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5216 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5217 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5218 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5219 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
5221 int bytes_returned
= 0;
5222 __u16 params
, byte_count
;
5224 cifs_dbg(FYI
, "In QFSAttributeInfo\n");
5226 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5231 params
= 2; /* level */
5232 pSMB
->TotalDataCount
= 0;
5233 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5234 /* BB find exact max SMB PDU from sess structure BB */
5235 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5236 pSMB
->MaxSetupCount
= 0;
5240 pSMB
->Reserved2
= 0;
5241 byte_count
= params
+ 1 /* pad */ ;
5242 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5243 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5244 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5245 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5246 pSMB
->DataCount
= 0;
5247 pSMB
->DataOffset
= 0;
5248 pSMB
->SetupCount
= 1;
5249 pSMB
->Reserved3
= 0;
5250 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5251 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
5252 inc_rfc1001_len(pSMB
, byte_count
);
5253 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5255 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5256 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5258 cifs_dbg(VFS
, "Send error in QFSAttributeInfo = %d\n", rc
);
5259 } else { /* decode response */
5260 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5262 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5263 /* BB also check if enough bytes returned */
5264 rc
= -EIO
; /* bad smb */
5266 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5268 (FILE_SYSTEM_ATTRIBUTE_INFO
5269 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5271 memcpy(&tcon
->fsAttrInfo
, response_data
,
5272 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO
));
5275 cifs_buf_release(pSMB
);
5278 goto QFSAttributeRetry
;
5284 CIFSSMBQFSDeviceInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5286 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5287 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5288 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5289 FILE_SYSTEM_DEVICE_INFO
*response_data
;
5291 int bytes_returned
= 0;
5292 __u16 params
, byte_count
;
5294 cifs_dbg(FYI
, "In QFSDeviceInfo\n");
5296 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5301 params
= 2; /* level */
5302 pSMB
->TotalDataCount
= 0;
5303 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5304 /* BB find exact max SMB PDU from sess structure BB */
5305 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5306 pSMB
->MaxSetupCount
= 0;
5310 pSMB
->Reserved2
= 0;
5311 byte_count
= params
+ 1 /* pad */ ;
5312 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5313 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5314 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5315 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5317 pSMB
->DataCount
= 0;
5318 pSMB
->DataOffset
= 0;
5319 pSMB
->SetupCount
= 1;
5320 pSMB
->Reserved3
= 0;
5321 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5322 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
5323 inc_rfc1001_len(pSMB
, byte_count
);
5324 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5326 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5327 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5329 cifs_dbg(FYI
, "Send error in QFSDeviceInfo = %d\n", rc
);
5330 } else { /* decode response */
5331 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5333 if (rc
|| get_bcc(&pSMBr
->hdr
) <
5334 sizeof(FILE_SYSTEM_DEVICE_INFO
))
5335 rc
= -EIO
; /* bad smb */
5337 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5339 (FILE_SYSTEM_DEVICE_INFO
*)
5340 (((char *) &pSMBr
->hdr
.Protocol
) +
5342 memcpy(&tcon
->fsDevInfo
, response_data
,
5343 sizeof(FILE_SYSTEM_DEVICE_INFO
));
5346 cifs_buf_release(pSMB
);
5349 goto QFSDeviceRetry
;
5355 CIFSSMBQFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5357 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5358 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5359 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5360 FILE_SYSTEM_UNIX_INFO
*response_data
;
5362 int bytes_returned
= 0;
5363 __u16 params
, byte_count
;
5365 cifs_dbg(FYI
, "In QFSUnixInfo\n");
5367 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5368 (void **) &pSMB
, (void **) &pSMBr
);
5372 params
= 2; /* level */
5373 pSMB
->TotalDataCount
= 0;
5374 pSMB
->DataCount
= 0;
5375 pSMB
->DataOffset
= 0;
5376 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5377 /* BB find exact max SMB PDU from sess structure BB */
5378 pSMB
->MaxDataCount
= cpu_to_le16(100);
5379 pSMB
->MaxSetupCount
= 0;
5383 pSMB
->Reserved2
= 0;
5384 byte_count
= params
+ 1 /* pad */ ;
5385 pSMB
->ParameterCount
= cpu_to_le16(params
);
5386 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5387 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5388 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5389 pSMB
->SetupCount
= 1;
5390 pSMB
->Reserved3
= 0;
5391 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5392 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
5393 inc_rfc1001_len(pSMB
, byte_count
);
5394 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5396 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5397 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5399 cifs_dbg(VFS
, "Send error in QFSUnixInfo = %d\n", rc
);
5400 } else { /* decode response */
5401 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5403 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5404 rc
= -EIO
; /* bad smb */
5406 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5408 (FILE_SYSTEM_UNIX_INFO
5409 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5411 memcpy(&tcon
->fsUnixInfo
, response_data
,
5412 sizeof(FILE_SYSTEM_UNIX_INFO
));
5415 cifs_buf_release(pSMB
);
5425 CIFSSMBSetFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
, __u64 cap
)
5427 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5428 TRANSACTION2_SETFSI_REQ
*pSMB
= NULL
;
5429 TRANSACTION2_SETFSI_RSP
*pSMBr
= NULL
;
5431 int bytes_returned
= 0;
5432 __u16 params
, param_offset
, offset
, byte_count
;
5434 cifs_dbg(FYI
, "In SETFSUnixInfo\n");
5436 /* BB switch to small buf init to save memory */
5437 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5438 (void **) &pSMB
, (void **) &pSMBr
);
5442 params
= 4; /* 2 bytes zero followed by info level. */
5443 pSMB
->MaxSetupCount
= 0;
5447 pSMB
->Reserved2
= 0;
5448 param_offset
= offsetof(struct smb_com_transaction2_setfsi_req
, FileNum
)
5450 offset
= param_offset
+ params
;
5452 pSMB
->MaxParameterCount
= cpu_to_le16(4);
5453 /* BB find exact max SMB PDU from sess structure BB */
5454 pSMB
->MaxDataCount
= cpu_to_le16(100);
5455 pSMB
->SetupCount
= 1;
5456 pSMB
->Reserved3
= 0;
5457 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FS_INFORMATION
);
5458 byte_count
= 1 /* pad */ + params
+ 12;
5460 pSMB
->DataCount
= cpu_to_le16(12);
5461 pSMB
->ParameterCount
= cpu_to_le16(params
);
5462 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5463 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5464 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5465 pSMB
->DataOffset
= cpu_to_le16(offset
);
5469 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_CIFS_UNIX_INFO
);
5472 pSMB
->ClientUnixMajor
= cpu_to_le16(CIFS_UNIX_MAJOR_VERSION
);
5473 pSMB
->ClientUnixMinor
= cpu_to_le16(CIFS_UNIX_MINOR_VERSION
);
5474 pSMB
->ClientUnixCap
= cpu_to_le64(cap
);
5476 inc_rfc1001_len(pSMB
, byte_count
);
5477 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5479 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5480 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5482 cifs_dbg(VFS
, "Send error in SETFSUnixInfo = %d\n", rc
);
5483 } else { /* decode response */
5484 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5486 rc
= -EIO
; /* bad smb */
5488 cifs_buf_release(pSMB
);
5491 goto SETFSUnixRetry
;
5499 CIFSSMBQFSPosixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5500 struct kstatfs
*FSData
)
5502 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5503 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5504 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5505 FILE_SYSTEM_POSIX_INFO
*response_data
;
5507 int bytes_returned
= 0;
5508 __u16 params
, byte_count
;
5510 cifs_dbg(FYI
, "In QFSPosixInfo\n");
5512 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5517 params
= 2; /* level */
5518 pSMB
->TotalDataCount
= 0;
5519 pSMB
->DataCount
= 0;
5520 pSMB
->DataOffset
= 0;
5521 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5522 /* BB find exact max SMB PDU from sess structure BB */
5523 pSMB
->MaxDataCount
= cpu_to_le16(100);
5524 pSMB
->MaxSetupCount
= 0;
5528 pSMB
->Reserved2
= 0;
5529 byte_count
= params
+ 1 /* pad */ ;
5530 pSMB
->ParameterCount
= cpu_to_le16(params
);
5531 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5532 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5533 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5534 pSMB
->SetupCount
= 1;
5535 pSMB
->Reserved3
= 0;
5536 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5537 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_FS_INFO
);
5538 inc_rfc1001_len(pSMB
, byte_count
);
5539 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5541 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5542 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5544 cifs_dbg(FYI
, "Send error in QFSUnixInfo = %d\n", rc
);
5545 } else { /* decode response */
5546 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5548 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5549 rc
= -EIO
; /* bad smb */
5551 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5553 (FILE_SYSTEM_POSIX_INFO
5554 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5557 le32_to_cpu(response_data
->BlockSize
);
5559 * much prefer larger but if server doesn't report
5560 * a valid size than 4K is a reasonable minimum
5562 if (FSData
->f_bsize
< 512)
5563 FSData
->f_bsize
= 4096;
5566 le64_to_cpu(response_data
->TotalBlocks
);
5568 le64_to_cpu(response_data
->BlocksAvail
);
5569 if (response_data
->UserBlocksAvail
== cpu_to_le64(-1)) {
5570 FSData
->f_bavail
= FSData
->f_bfree
;
5573 le64_to_cpu(response_data
->UserBlocksAvail
);
5575 if (response_data
->TotalFileNodes
!= cpu_to_le64(-1))
5577 le64_to_cpu(response_data
->TotalFileNodes
);
5578 if (response_data
->FreeFileNodes
!= cpu_to_le64(-1))
5580 le64_to_cpu(response_data
->FreeFileNodes
);
5583 cifs_buf_release(pSMB
);
5593 * We can not use write of zero bytes trick to set file size due to need for
5594 * large file support. Also note that this SetPathInfo is preferred to
5595 * SetFileInfo based method in next routine which is only needed to work around
5596 * a sharing violation bugin Samba which this routine can run into.
5599 CIFSSMBSetEOF(const unsigned int xid
, struct cifs_tcon
*tcon
,
5600 const char *file_name
, __u64 size
, struct cifs_sb_info
*cifs_sb
,
5601 bool set_allocation
)
5603 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5604 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5605 struct file_end_of_file_info
*parm_data
;
5608 int bytes_returned
= 0;
5609 int remap
= cifs_remap(cifs_sb
);
5611 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
5613 cifs_dbg(FYI
, "In SetEOF\n");
5615 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5620 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5622 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5623 PATH_MAX
, cifs_sb
->local_nls
, remap
);
5624 name_len
++; /* trailing null */
5627 name_len
= copy_path_name(pSMB
->FileName
, file_name
);
5629 params
= 6 + name_len
;
5630 data_count
= sizeof(struct file_end_of_file_info
);
5631 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5632 pSMB
->MaxDataCount
= cpu_to_le16(4100);
5633 pSMB
->MaxSetupCount
= 0;
5637 pSMB
->Reserved2
= 0;
5638 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5639 InformationLevel
) - 4;
5640 offset
= param_offset
+ params
;
5641 if (set_allocation
) {
5642 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5643 pSMB
->InformationLevel
=
5644 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5646 pSMB
->InformationLevel
=
5647 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5648 } else /* Set File Size */ {
5649 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5650 pSMB
->InformationLevel
=
5651 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5653 pSMB
->InformationLevel
=
5654 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5658 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
5660 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5661 pSMB
->DataOffset
= cpu_to_le16(offset
);
5662 pSMB
->SetupCount
= 1;
5663 pSMB
->Reserved3
= 0;
5664 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5665 byte_count
= 3 /* pad */ + params
+ data_count
;
5666 pSMB
->DataCount
= cpu_to_le16(data_count
);
5667 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5668 pSMB
->ParameterCount
= cpu_to_le16(params
);
5669 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5670 pSMB
->Reserved4
= 0;
5671 inc_rfc1001_len(pSMB
, byte_count
);
5672 parm_data
->FileSize
= cpu_to_le64(size
);
5673 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5674 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5675 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5677 cifs_dbg(FYI
, "SetPathInfo (file size) returned %d\n", rc
);
5679 cifs_buf_release(pSMB
);
5688 CIFSSMBSetFileSize(const unsigned int xid
, struct cifs_tcon
*tcon
,
5689 struct cifsFileInfo
*cfile
, __u64 size
, bool set_allocation
)
5691 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5692 struct file_end_of_file_info
*parm_data
;
5694 __u16 params
, param_offset
, offset
, byte_count
, count
;
5696 cifs_dbg(FYI
, "SetFileSize (via SetFileInfo) %lld\n",
5698 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5703 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)cfile
->pid
);
5704 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(cfile
->pid
>> 16));
5707 pSMB
->MaxSetupCount
= 0;
5711 pSMB
->Reserved2
= 0;
5712 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5713 offset
= param_offset
+ params
;
5715 count
= sizeof(struct file_end_of_file_info
);
5716 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5717 /* BB find exact max SMB PDU from sess structure BB */
5718 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5719 pSMB
->SetupCount
= 1;
5720 pSMB
->Reserved3
= 0;
5721 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5722 byte_count
= 3 /* pad */ + params
+ count
;
5723 pSMB
->DataCount
= cpu_to_le16(count
);
5724 pSMB
->ParameterCount
= cpu_to_le16(params
);
5725 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5726 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5727 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5729 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
)
5731 pSMB
->DataOffset
= cpu_to_le16(offset
);
5732 parm_data
->FileSize
= cpu_to_le64(size
);
5733 pSMB
->Fid
= cfile
->fid
.netfid
;
5734 if (set_allocation
) {
5735 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5736 pSMB
->InformationLevel
=
5737 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5739 pSMB
->InformationLevel
=
5740 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5741 } else /* Set File Size */ {
5742 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5743 pSMB
->InformationLevel
=
5744 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5746 pSMB
->InformationLevel
=
5747 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5749 pSMB
->Reserved4
= 0;
5750 inc_rfc1001_len(pSMB
, byte_count
);
5751 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5752 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5753 cifs_small_buf_release(pSMB
);
5755 cifs_dbg(FYI
, "Send error in SetFileInfo (SetFileSize) = %d\n",
5759 /* Note: On -EAGAIN error only caller can retry on handle based calls
5760 since file handle passed in no longer valid */
5765 /* Some legacy servers such as NT4 require that the file times be set on
5766 an open handle, rather than by pathname - this is awkward due to
5767 potential access conflicts on the open, but it is unavoidable for these
5768 old servers since the only other choice is to go from 100 nanosecond DCE
5769 time and resort to the original setpathinfo level which takes the ancient
5770 DOS time format with 2 second granularity */
5772 CIFSSMBSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5773 const FILE_BASIC_INFO
*data
, __u16 fid
, __u32 pid_of_opener
)
5775 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5778 __u16 params
, param_offset
, offset
, byte_count
, count
;
5780 cifs_dbg(FYI
, "Set Times (via SetFileInfo)\n");
5781 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5786 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5787 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5790 pSMB
->MaxSetupCount
= 0;
5794 pSMB
->Reserved2
= 0;
5795 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5796 offset
= param_offset
+ params
;
5798 data_offset
= (char *)pSMB
+
5799 offsetof(struct smb_hdr
, Protocol
) + offset
;
5801 count
= sizeof(FILE_BASIC_INFO
);
5802 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5803 /* BB find max SMB PDU from sess */
5804 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5805 pSMB
->SetupCount
= 1;
5806 pSMB
->Reserved3
= 0;
5807 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5808 byte_count
= 3 /* pad */ + params
+ count
;
5809 pSMB
->DataCount
= cpu_to_le16(count
);
5810 pSMB
->ParameterCount
= cpu_to_le16(params
);
5811 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5812 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5813 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5814 pSMB
->DataOffset
= cpu_to_le16(offset
);
5816 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5817 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5819 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5820 pSMB
->Reserved4
= 0;
5821 inc_rfc1001_len(pSMB
, byte_count
);
5822 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5823 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5824 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5825 cifs_small_buf_release(pSMB
);
5827 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5830 /* Note: On -EAGAIN error only caller can retry on handle based calls
5831 since file handle passed in no longer valid */
5837 CIFSSMBSetFileDisposition(const unsigned int xid
, struct cifs_tcon
*tcon
,
5838 bool delete_file
, __u16 fid
, __u32 pid_of_opener
)
5840 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5843 __u16 params
, param_offset
, offset
, byte_count
, count
;
5845 cifs_dbg(FYI
, "Set File Disposition (via SetFileInfo)\n");
5846 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5851 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5852 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5855 pSMB
->MaxSetupCount
= 0;
5859 pSMB
->Reserved2
= 0;
5860 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5861 offset
= param_offset
+ params
;
5863 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5866 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5867 /* BB find max SMB PDU from sess */
5868 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5869 pSMB
->SetupCount
= 1;
5870 pSMB
->Reserved3
= 0;
5871 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5872 byte_count
= 3 /* pad */ + params
+ count
;
5873 pSMB
->DataCount
= cpu_to_le16(count
);
5874 pSMB
->ParameterCount
= cpu_to_le16(params
);
5875 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5876 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5877 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5878 pSMB
->DataOffset
= cpu_to_le16(offset
);
5880 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO
);
5881 pSMB
->Reserved4
= 0;
5882 inc_rfc1001_len(pSMB
, byte_count
);
5883 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5884 *data_offset
= delete_file
? 1 : 0;
5885 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5886 cifs_small_buf_release(pSMB
);
5888 cifs_dbg(FYI
, "Send error in SetFileDisposition = %d\n", rc
);
5894 CIFSSMBSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5895 const char *fileName
, const FILE_BASIC_INFO
*data
,
5896 const struct nls_table
*nls_codepage
, int remap
)
5898 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5899 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5902 int bytes_returned
= 0;
5904 __u16 params
, param_offset
, offset
, byte_count
, count
;
5906 cifs_dbg(FYI
, "In SetTimes\n");
5909 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5914 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5916 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5917 PATH_MAX
, nls_codepage
, remap
);
5918 name_len
++; /* trailing null */
5921 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
5924 params
= 6 + name_len
;
5925 count
= sizeof(FILE_BASIC_INFO
);
5926 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5927 /* BB find max SMB PDU from sess structure BB */
5928 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5929 pSMB
->MaxSetupCount
= 0;
5933 pSMB
->Reserved2
= 0;
5934 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5935 InformationLevel
) - 4;
5936 offset
= param_offset
+ params
;
5937 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5938 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5939 pSMB
->DataOffset
= cpu_to_le16(offset
);
5940 pSMB
->SetupCount
= 1;
5941 pSMB
->Reserved3
= 0;
5942 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5943 byte_count
= 3 /* pad */ + params
+ count
;
5945 pSMB
->DataCount
= cpu_to_le16(count
);
5946 pSMB
->ParameterCount
= cpu_to_le16(params
);
5947 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5948 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5949 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5950 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5952 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5953 pSMB
->Reserved4
= 0;
5954 inc_rfc1001_len(pSMB
, byte_count
);
5955 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5956 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5957 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5958 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5960 cifs_dbg(FYI
, "SetPathInfo (times) returned %d\n", rc
);
5962 cifs_buf_release(pSMB
);
5970 /* Can not be used to set time stamps yet (due to old DOS time format) */
5971 /* Can be used to set attributes */
5972 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5973 handling it anyway and NT4 was what we thought it would be needed for
5974 Do not delete it until we prove whether needed for Win9x though */
5976 CIFSSMBSetAttrLegacy(unsigned int xid
, struct cifs_tcon
*tcon
, char *fileName
,
5977 __u16 dos_attrs
, const struct nls_table
*nls_codepage
)
5979 SETATTR_REQ
*pSMB
= NULL
;
5980 SETATTR_RSP
*pSMBr
= NULL
;
5985 cifs_dbg(FYI
, "In SetAttrLegacy\n");
5988 rc
= smb_init(SMB_COM_SETATTR
, 8, tcon
, (void **) &pSMB
,
5993 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5995 ConvertToUTF16((__le16
*) pSMB
->fileName
, fileName
,
5996 PATH_MAX
, nls_codepage
);
5997 name_len
++; /* trailing null */
6000 name_len
= copy_path_name(pSMB
->fileName
, fileName
);
6002 pSMB
->attr
= cpu_to_le16(dos_attrs
);
6003 pSMB
->BufferFormat
= 0x04;
6004 inc_rfc1001_len(pSMB
, name_len
+ 1);
6005 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
6006 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6007 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6009 cifs_dbg(FYI
, "Error in LegacySetAttr = %d\n", rc
);
6011 cifs_buf_release(pSMB
);
6014 goto SetAttrLgcyRetry
;
6018 #endif /* temporarily unneeded SetAttr legacy function */
6021 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO
*data_offset
,
6022 const struct cifs_unix_set_info_args
*args
)
6024 u64 uid
= NO_CHANGE_64
, gid
= NO_CHANGE_64
;
6025 u64 mode
= args
->mode
;
6027 if (uid_valid(args
->uid
))
6028 uid
= from_kuid(&init_user_ns
, args
->uid
);
6029 if (gid_valid(args
->gid
))
6030 gid
= from_kgid(&init_user_ns
, args
->gid
);
6033 * Samba server ignores set of file size to zero due to bugs in some
6034 * older clients, but we should be precise - we use SetFileSize to
6035 * set file size and do not want to truncate file size to zero
6036 * accidentally as happened on one Samba server beta by putting
6037 * zero instead of -1 here
6039 data_offset
->EndOfFile
= cpu_to_le64(NO_CHANGE_64
);
6040 data_offset
->NumOfBytes
= cpu_to_le64(NO_CHANGE_64
);
6041 data_offset
->LastStatusChange
= cpu_to_le64(args
->ctime
);
6042 data_offset
->LastAccessTime
= cpu_to_le64(args
->atime
);
6043 data_offset
->LastModificationTime
= cpu_to_le64(args
->mtime
);
6044 data_offset
->Uid
= cpu_to_le64(uid
);
6045 data_offset
->Gid
= cpu_to_le64(gid
);
6046 /* better to leave device as zero when it is */
6047 data_offset
->DevMajor
= cpu_to_le64(MAJOR(args
->device
));
6048 data_offset
->DevMinor
= cpu_to_le64(MINOR(args
->device
));
6049 data_offset
->Permissions
= cpu_to_le64(mode
);
6052 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
6053 else if (S_ISDIR(mode
))
6054 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
6055 else if (S_ISLNK(mode
))
6056 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
6057 else if (S_ISCHR(mode
))
6058 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
6059 else if (S_ISBLK(mode
))
6060 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
6061 else if (S_ISFIFO(mode
))
6062 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
6063 else if (S_ISSOCK(mode
))
6064 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
6068 CIFSSMBUnixSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6069 const struct cifs_unix_set_info_args
*args
,
6070 u16 fid
, u32 pid_of_opener
)
6072 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
6075 u16 params
, param_offset
, offset
, byte_count
, count
;
6077 cifs_dbg(FYI
, "Set Unix Info (via SetFileInfo)\n");
6078 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
6083 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
6084 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
6087 pSMB
->MaxSetupCount
= 0;
6091 pSMB
->Reserved2
= 0;
6092 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
6093 offset
= param_offset
+ params
;
6095 data_offset
= (char *)pSMB
+
6096 offsetof(struct smb_hdr
, Protocol
) + offset
;
6098 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6100 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6101 /* BB find max SMB PDU from sess */
6102 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6103 pSMB
->SetupCount
= 1;
6104 pSMB
->Reserved3
= 0;
6105 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
6106 byte_count
= 3 /* pad */ + params
+ count
;
6107 pSMB
->DataCount
= cpu_to_le16(count
);
6108 pSMB
->ParameterCount
= cpu_to_le16(params
);
6109 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6110 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6111 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6112 pSMB
->DataOffset
= cpu_to_le16(offset
);
6114 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6115 pSMB
->Reserved4
= 0;
6116 inc_rfc1001_len(pSMB
, byte_count
);
6117 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6119 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO
*)data_offset
, args
);
6121 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
6122 cifs_small_buf_release(pSMB
);
6124 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
6127 /* Note: On -EAGAIN error only caller can retry on handle based calls
6128 since file handle passed in no longer valid */
6134 CIFSSMBUnixSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6135 const char *file_name
,
6136 const struct cifs_unix_set_info_args
*args
,
6137 const struct nls_table
*nls_codepage
, int remap
)
6139 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
6140 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
6143 int bytes_returned
= 0;
6144 FILE_UNIX_BASIC_INFO
*data_offset
;
6145 __u16 params
, param_offset
, offset
, count
, byte_count
;
6147 cifs_dbg(FYI
, "In SetUID/GID/Mode\n");
6149 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6154 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6156 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
6157 PATH_MAX
, nls_codepage
, remap
);
6158 name_len
++; /* trailing null */
6161 name_len
= copy_path_name(pSMB
->FileName
, file_name
);
6164 params
= 6 + name_len
;
6165 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6166 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6167 /* BB find max SMB PDU from sess structure BB */
6168 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6169 pSMB
->MaxSetupCount
= 0;
6173 pSMB
->Reserved2
= 0;
6174 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6175 InformationLevel
) - 4;
6176 offset
= param_offset
+ params
;
6178 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
6180 memset(data_offset
, 0, count
);
6181 pSMB
->DataOffset
= cpu_to_le16(offset
);
6182 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6183 pSMB
->SetupCount
= 1;
6184 pSMB
->Reserved3
= 0;
6185 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6186 byte_count
= 3 /* pad */ + params
+ count
;
6187 pSMB
->ParameterCount
= cpu_to_le16(params
);
6188 pSMB
->DataCount
= cpu_to_le16(count
);
6189 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6190 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6191 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6192 pSMB
->Reserved4
= 0;
6193 inc_rfc1001_len(pSMB
, byte_count
);
6195 cifs_fill_unix_set_info(data_offset
, args
);
6197 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6198 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6199 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6201 cifs_dbg(FYI
, "SetPathInfo (perms) returned %d\n", rc
);
6203 cifs_buf_release(pSMB
);
6209 #ifdef CONFIG_CIFS_XATTR
6211 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6212 * function used by listxattr and getxattr type calls. When ea_name is set,
6213 * it looks for that attribute name and stuffs that value into the EAData
6214 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6215 * buffer. In both cases, the return value is either the length of the
6216 * resulting data or a negative error code. If EAData is a NULL pointer then
6217 * the data isn't copied to it, but the length is returned.
6220 CIFSSMBQAllEAs(const unsigned int xid
, struct cifs_tcon
*tcon
,
6221 const unsigned char *searchName
, const unsigned char *ea_name
,
6222 char *EAData
, size_t buf_size
,
6223 struct cifs_sb_info
*cifs_sb
)
6225 /* BB assumes one setup word */
6226 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
6227 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
6228 int remap
= cifs_remap(cifs_sb
);
6229 struct nls_table
*nls_codepage
= cifs_sb
->local_nls
;
6233 struct fealist
*ea_response_data
;
6234 struct fea
*temp_fea
;
6237 __u16 params
, byte_count
, data_offset
;
6238 unsigned int ea_name_len
= ea_name
? strlen(ea_name
) : 0;
6240 cifs_dbg(FYI
, "In Query All EAs path %s\n", searchName
);
6242 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6247 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6249 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
6250 PATH_MAX
, nls_codepage
, remap
);
6251 list_len
++; /* trailing null */
6254 list_len
= copy_path_name(pSMB
->FileName
, searchName
);
6257 params
= 2 /* level */ + 4 /* reserved */ + list_len
/* includes NUL */;
6258 pSMB
->TotalDataCount
= 0;
6259 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6260 /* BB find exact max SMB PDU from sess structure BB */
6261 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
6262 pSMB
->MaxSetupCount
= 0;
6266 pSMB
->Reserved2
= 0;
6267 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
6268 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
6269 pSMB
->DataCount
= 0;
6270 pSMB
->DataOffset
= 0;
6271 pSMB
->SetupCount
= 1;
6272 pSMB
->Reserved3
= 0;
6273 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
6274 byte_count
= params
+ 1 /* pad */ ;
6275 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
6276 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6277 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
6278 pSMB
->Reserved4
= 0;
6279 inc_rfc1001_len(pSMB
, byte_count
);
6280 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6282 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6283 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6285 cifs_dbg(FYI
, "Send error in QueryAllEAs = %d\n", rc
);
6290 /* BB also check enough total bytes returned */
6291 /* BB we need to improve the validity checking
6292 of these trans2 responses */
6294 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
6295 if (rc
|| get_bcc(&pSMBr
->hdr
) < 4) {
6296 rc
= -EIO
; /* bad smb */
6300 /* check that length of list is not more than bcc */
6301 /* check that each entry does not go beyond length
6303 /* check that each element of each entry does not
6304 go beyond end of list */
6305 /* validate_trans2_offsets() */
6306 /* BB check if start of smb + data_offset > &bcc+ bcc */
6308 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
6309 ea_response_data
= (struct fealist
*)
6310 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
6312 list_len
= le32_to_cpu(ea_response_data
->list_len
);
6313 cifs_dbg(FYI
, "ea length %d\n", list_len
);
6314 if (list_len
<= 8) {
6315 cifs_dbg(FYI
, "empty EA list returned from server\n");
6316 /* didn't find the named attribute */
6322 /* make sure list_len doesn't go past end of SMB */
6323 end_of_smb
= (char *)pByteArea(&pSMBr
->hdr
) + get_bcc(&pSMBr
->hdr
);
6324 if ((char *)ea_response_data
+ list_len
> end_of_smb
) {
6325 cifs_dbg(FYI
, "EA list appears to go beyond SMB\n");
6330 /* account for ea list len */
6332 temp_fea
= ea_response_data
->list
;
6333 temp_ptr
= (char *)temp_fea
;
6334 while (list_len
> 0) {
6335 unsigned int name_len
;
6340 /* make sure we can read name_len and value_len */
6342 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6347 name_len
= temp_fea
->name_len
;
6348 value_len
= le16_to_cpu(temp_fea
->value_len
);
6349 list_len
-= name_len
+ 1 + value_len
;
6351 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6357 if (ea_name_len
== name_len
&&
6358 memcmp(ea_name
, temp_ptr
, name_len
) == 0) {
6359 temp_ptr
+= name_len
+ 1;
6363 if ((size_t)value_len
> buf_size
) {
6367 memcpy(EAData
, temp_ptr
, value_len
);
6371 /* account for prefix user. and trailing null */
6372 rc
+= (5 + 1 + name_len
);
6373 if (rc
< (int) buf_size
) {
6374 memcpy(EAData
, "user.", 5);
6376 memcpy(EAData
, temp_ptr
, name_len
);
6378 /* null terminate name */
6381 } else if (buf_size
== 0) {
6382 /* skip copy - calc size only */
6384 /* stop before overrun buffer */
6389 temp_ptr
+= name_len
+ 1 + value_len
;
6390 temp_fea
= (struct fea
*)temp_ptr
;
6393 /* didn't find the named attribute */
6398 cifs_buf_release(pSMB
);
6406 CIFSSMBSetEA(const unsigned int xid
, struct cifs_tcon
*tcon
,
6407 const char *fileName
, const char *ea_name
, const void *ea_value
,
6408 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
,
6409 struct cifs_sb_info
*cifs_sb
)
6411 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
6412 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
6413 struct fealist
*parm_data
;
6416 int bytes_returned
= 0;
6417 __u16 params
, param_offset
, byte_count
, offset
, count
;
6418 int remap
= cifs_remap(cifs_sb
);
6420 cifs_dbg(FYI
, "In SetEA\n");
6422 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6427 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6429 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
6430 PATH_MAX
, nls_codepage
, remap
);
6431 name_len
++; /* trailing null */
6434 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
6437 params
= 6 + name_len
;
6439 /* done calculating parms using name_len of file name,
6440 now use name_len to calculate length of ea name
6441 we are going to create in the inode xattrs */
6442 if (ea_name
== NULL
)
6445 name_len
= strnlen(ea_name
, 255);
6447 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
;
6448 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6449 /* BB find max SMB PDU from sess */
6450 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6451 pSMB
->MaxSetupCount
= 0;
6455 pSMB
->Reserved2
= 0;
6456 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6457 InformationLevel
) - 4;
6458 offset
= param_offset
+ params
;
6459 pSMB
->InformationLevel
=
6460 cpu_to_le16(SMB_SET_FILE_EA
);
6462 parm_data
= (void *)pSMB
+ offsetof(struct smb_hdr
, Protocol
) + offset
;
6463 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6464 pSMB
->DataOffset
= cpu_to_le16(offset
);
6465 pSMB
->SetupCount
= 1;
6466 pSMB
->Reserved3
= 0;
6467 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6468 byte_count
= 3 /* pad */ + params
+ count
;
6469 pSMB
->DataCount
= cpu_to_le16(count
);
6470 parm_data
->list_len
= cpu_to_le32(count
);
6471 parm_data
->list
[0].EA_flags
= 0;
6472 /* we checked above that name len is less than 255 */
6473 parm_data
->list
[0].name_len
= (__u8
)name_len
;
6474 /* EA names are always ASCII */
6476 strncpy(parm_data
->list
[0].name
, ea_name
, name_len
);
6477 parm_data
->list
[0].name
[name_len
] = 0;
6478 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
6479 /* caller ensures that ea_value_len is less than 64K but
6480 we need to ensure that it fits within the smb */
6482 /*BB add length check to see if it would fit in
6483 negotiated SMB buffer size BB */
6484 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6486 memcpy(parm_data
->list
[0].name
+name_len
+1,
6487 ea_value
, ea_value_len
);
6489 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6490 pSMB
->ParameterCount
= cpu_to_le16(params
);
6491 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6492 pSMB
->Reserved4
= 0;
6493 inc_rfc1001_len(pSMB
, byte_count
);
6494 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6495 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6496 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6498 cifs_dbg(FYI
, "SetPathInfo (EA) returned %d\n", rc
);
6500 cifs_buf_release(pSMB
);