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 *tgt
= dfs_cache_get_tgt_name(it
);
167 extract_unc_hostname(tgt
, &dfs_host
, &dfs_host_len
);
169 if (dfs_host_len
!= tcp_host_len
170 || strncasecmp(dfs_host
, tcp_host
, dfs_host_len
) != 0) {
171 cifs_dbg(FYI
, "%s: skipping %.*s, doesn't match %.*s",
173 (int)dfs_host_len
, dfs_host
,
174 (int)tcp_host_len
, tcp_host
);
178 scnprintf(tree
, MAX_TREE_SIZE
, "\\%s", tgt
);
180 rc
= CIFSTCon(0, tcon
->ses
, tree
, tcon
, nlsc
);
189 rc
= dfs_cache_noreq_update_tgthint(tcon
->dfs_path
+ 1,
194 dfs_cache_free_tgts(&tl
);
200 static inline int __cifs_reconnect_tcon(const struct nls_table
*nlsc
,
201 struct cifs_tcon
*tcon
)
203 return CIFSTCon(0, tcon
->ses
, tcon
->treeName
, tcon
, nlsc
);
207 /* reconnect the socket, tcon, and smb session if needed */
209 cifs_reconnect_tcon(struct cifs_tcon
*tcon
, int smb_command
)
212 struct cifs_ses
*ses
;
213 struct TCP_Server_Info
*server
;
214 struct nls_table
*nls_codepage
;
218 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
219 * tcp and smb session status done differently for those three - in the
226 server
= ses
->server
;
229 * only tree disconnect, open, and write, (and ulogoff which does not
230 * have tcon) are allowed as we start force umount
232 if (tcon
->tidStatus
== CifsExiting
) {
233 if (smb_command
!= SMB_COM_WRITE_ANDX
&&
234 smb_command
!= SMB_COM_OPEN_ANDX
&&
235 smb_command
!= SMB_COM_TREE_DISCONNECT
) {
236 cifs_dbg(FYI
, "can not send cmd %d while umounting\n",
242 retries
= server
->nr_targets
;
245 * Give demultiplex thread up to 10 seconds to each target available for
246 * reconnect -- should be greater than cifs socket timeout which is 7
249 while (server
->tcpStatus
== CifsNeedReconnect
) {
250 rc
= wait_event_interruptible_timeout(server
->response_q
,
251 (server
->tcpStatus
!= CifsNeedReconnect
),
254 cifs_dbg(FYI
, "%s: aborting reconnect due to a received"
255 " signal by the process\n", __func__
);
259 /* are we still trying to reconnect? */
260 if (server
->tcpStatus
!= CifsNeedReconnect
)
263 if (retries
&& --retries
)
267 * on "soft" mounts we wait once. Hard mounts keep
268 * retrying until process is killed or server comes
272 cifs_dbg(FYI
, "gave up waiting on reconnect in smb_init\n");
275 retries
= server
->nr_targets
;
278 if (!ses
->need_reconnect
&& !tcon
->need_reconnect
)
281 nls_codepage
= load_nls_default();
284 * need to prevent multiple threads trying to simultaneously
285 * reconnect the same SMB session
287 mutex_lock(&ses
->session_mutex
);
290 * Recheck after acquire mutex. If another thread is negotiating
291 * and the server never sends an answer the socket will be closed
292 * and tcpStatus set to reconnect.
294 if (server
->tcpStatus
== CifsNeedReconnect
) {
296 mutex_unlock(&ses
->session_mutex
);
300 rc
= cifs_negotiate_protocol(0, ses
);
301 if (rc
== 0 && ses
->need_reconnect
)
302 rc
= cifs_setup_session(0, ses
, nls_codepage
);
304 /* do we need to reconnect tcon? */
305 if (rc
|| !tcon
->need_reconnect
) {
306 mutex_unlock(&ses
->session_mutex
);
310 cifs_mark_open_files_invalid(tcon
);
311 rc
= __cifs_reconnect_tcon(nls_codepage
, tcon
);
312 mutex_unlock(&ses
->session_mutex
);
313 cifs_dbg(FYI
, "reconnect tcon rc = %d\n", rc
);
316 printk_once(KERN_WARNING
"reconnect tcon failed rc = %d\n", rc
);
320 atomic_inc(&tconInfoReconnectCount
);
322 /* tell server Unix caps we support */
323 if (ses
->capabilities
& CAP_UNIX
)
324 reset_cifs_unix_caps(0, tcon
, NULL
, NULL
);
327 * Removed call to reopen open files here. It is safer (and faster) to
328 * reopen files one at a time as needed in read and write.
330 * FIXME: what about file locks? don't we need to reclaim them ASAP?
335 * Check if handle based operation so we know whether we can continue
336 * or not without returning to caller to reset file handle
338 switch (smb_command
) {
339 case SMB_COM_READ_ANDX
:
340 case SMB_COM_WRITE_ANDX
:
342 case SMB_COM_FIND_CLOSE2
:
343 case SMB_COM_LOCKING_ANDX
:
347 unload_nls(nls_codepage
);
351 /* Allocate and return pointer to an SMB request buffer, and set basic
352 SMB information in the SMB header. If the return code is zero, this
353 function must have filled in request_buf pointer */
355 small_smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
360 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
364 *request_buf
= cifs_small_buf_get();
365 if (*request_buf
== NULL
) {
366 /* BB should we add a retry in here if not a writepage? */
370 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
,
374 cifs_stats_inc(&tcon
->num_smbs_sent
);
380 small_smb_init_no_tc(const int smb_command
, const int wct
,
381 struct cifs_ses
*ses
, void **request_buf
)
384 struct smb_hdr
*buffer
;
386 rc
= small_smb_init(smb_command
, wct
, NULL
, request_buf
);
390 buffer
= (struct smb_hdr
*)*request_buf
;
391 buffer
->Mid
= get_next_mid(ses
->server
);
392 if (ses
->capabilities
& CAP_UNICODE
)
393 buffer
->Flags2
|= SMBFLG2_UNICODE
;
394 if (ses
->capabilities
& CAP_STATUS32
)
395 buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
397 /* uid, tid can stay at zero as set in header assemble */
399 /* BB add support for turning on the signing when
400 this function is used after 1st of session setup requests */
405 /* If the return code is zero, this function must fill in request_buf pointer */
407 __smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
408 void **request_buf
, void **response_buf
)
410 *request_buf
= cifs_buf_get();
411 if (*request_buf
== NULL
) {
412 /* BB should we add a retry in here if not a writepage? */
415 /* Although the original thought was we needed the response buf for */
416 /* potential retries of smb operations it turns out we can determine */
417 /* from the mid flags when the request buffer can be resent without */
418 /* having to use a second distinct buffer for the response */
420 *response_buf
= *request_buf
;
422 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
, tcon
,
426 cifs_stats_inc(&tcon
->num_smbs_sent
);
431 /* If the return code is zero, this function must fill in request_buf pointer */
433 smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
434 void **request_buf
, void **response_buf
)
438 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
442 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
446 smb_init_no_reconnect(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
447 void **request_buf
, void **response_buf
)
449 if (tcon
->ses
->need_reconnect
|| tcon
->need_reconnect
)
452 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
455 static int validate_t2(struct smb_t2_rsp
*pSMB
)
457 unsigned int total_size
;
459 /* check for plausible wct */
460 if (pSMB
->hdr
.WordCount
< 10)
463 /* check for parm and data offset going beyond end of smb */
464 if (get_unaligned_le16(&pSMB
->t2_rsp
.ParameterOffset
) > 1024 ||
465 get_unaligned_le16(&pSMB
->t2_rsp
.DataOffset
) > 1024)
468 total_size
= get_unaligned_le16(&pSMB
->t2_rsp
.ParameterCount
);
469 if (total_size
>= 512)
472 /* check that bcc is at least as big as parms + data, and that it is
473 * less than negotiated smb buffer
475 total_size
+= get_unaligned_le16(&pSMB
->t2_rsp
.DataCount
);
476 if (total_size
> get_bcc(&pSMB
->hdr
) ||
477 total_size
>= CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
)
482 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB
,
483 sizeof(struct smb_t2_rsp
) + 16);
488 decode_ext_sec_blob(struct cifs_ses
*ses
, NEGOTIATE_RSP
*pSMBr
)
492 char *guid
= pSMBr
->u
.extended_response
.GUID
;
493 struct TCP_Server_Info
*server
= ses
->server
;
495 count
= get_bcc(&pSMBr
->hdr
);
496 if (count
< SMB1_CLIENT_GUID_SIZE
)
499 spin_lock(&cifs_tcp_ses_lock
);
500 if (server
->srv_count
> 1) {
501 spin_unlock(&cifs_tcp_ses_lock
);
502 if (memcmp(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
) != 0) {
503 cifs_dbg(FYI
, "server UID changed\n");
504 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
507 spin_unlock(&cifs_tcp_ses_lock
);
508 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
511 if (count
== SMB1_CLIENT_GUID_SIZE
) {
512 server
->sec_ntlmssp
= true;
514 count
-= SMB1_CLIENT_GUID_SIZE
;
515 rc
= decode_negTokenInit(
516 pSMBr
->u
.extended_response
.SecurityBlob
, count
, server
);
525 cifs_enable_signing(struct TCP_Server_Info
*server
, bool mnt_sign_required
)
527 bool srv_sign_required
= server
->sec_mode
& server
->vals
->signing_required
;
528 bool srv_sign_enabled
= server
->sec_mode
& server
->vals
->signing_enabled
;
529 bool mnt_sign_enabled
= global_secflags
& CIFSSEC_MAY_SIGN
;
532 * Is signing required by mnt options? If not then check
533 * global_secflags to see if it is there.
535 if (!mnt_sign_required
)
536 mnt_sign_required
= ((global_secflags
& CIFSSEC_MUST_SIGN
) ==
540 * If signing is required then it's automatically enabled too,
541 * otherwise, check to see if the secflags allow it.
543 mnt_sign_enabled
= mnt_sign_required
? mnt_sign_required
:
544 (global_secflags
& CIFSSEC_MAY_SIGN
);
546 /* If server requires signing, does client allow it? */
547 if (srv_sign_required
) {
548 if (!mnt_sign_enabled
) {
549 cifs_dbg(VFS
, "Server requires signing, but it's disabled in SecurityFlags!");
555 /* If client requires signing, does server allow it? */
556 if (mnt_sign_required
) {
557 if (!srv_sign_enabled
) {
558 cifs_dbg(VFS
, "Server does not support signing!");
564 if (cifs_rdma_enabled(server
) && server
->sign
)
565 cifs_dbg(VFS
, "Signing is enabled, and RDMA read/write will be disabled");
570 #ifdef CONFIG_CIFS_WEAK_PW_HASH
572 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
575 struct lanman_neg_rsp
*rsp
= (struct lanman_neg_rsp
*)pSMBr
;
577 if (server
->dialect
!= LANMAN_PROT
&& server
->dialect
!= LANMAN2_PROT
)
580 server
->sec_mode
= le16_to_cpu(rsp
->SecurityMode
);
581 server
->maxReq
= min_t(unsigned int,
582 le16_to_cpu(rsp
->MaxMpxCount
),
584 set_credits(server
, server
->maxReq
);
585 server
->maxBuf
= le16_to_cpu(rsp
->MaxBufSize
);
586 /* even though we do not use raw we might as well set this
587 accurately, in case we ever find a need for it */
588 if ((le16_to_cpu(rsp
->RawMode
) & RAW_ENABLE
) == RAW_ENABLE
) {
589 server
->max_rw
= 0xFF00;
590 server
->capabilities
= CAP_MPX_MODE
| CAP_RAW_MODE
;
592 server
->max_rw
= 0;/* do not need to use raw anyway */
593 server
->capabilities
= CAP_MPX_MODE
;
595 tmp
= (__s16
)le16_to_cpu(rsp
->ServerTimeZone
);
597 /* OS/2 often does not set timezone therefore
598 * we must use server time to calc time zone.
599 * Could deviate slightly from the right zone.
600 * Smallest defined timezone difference is 15 minutes
601 * (i.e. Nepal). Rounding up/down is done to match
604 int val
, seconds
, remain
, result
;
605 struct timespec64 ts
;
606 time64_t utc
= ktime_get_real_seconds();
607 ts
= cnvrtDosUnixTm(rsp
->SrvTime
.Date
,
608 rsp
->SrvTime
.Time
, 0);
609 cifs_dbg(FYI
, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n",
612 val
= (int)(utc
- ts
.tv_sec
);
614 result
= (seconds
/ MIN_TZ_ADJ
) * MIN_TZ_ADJ
;
615 remain
= seconds
% MIN_TZ_ADJ
;
616 if (remain
>= (MIN_TZ_ADJ
/ 2))
617 result
+= MIN_TZ_ADJ
;
620 server
->timeAdj
= result
;
622 server
->timeAdj
= (int)tmp
;
623 server
->timeAdj
*= 60; /* also in seconds */
625 cifs_dbg(FYI
, "server->timeAdj: %d seconds\n", server
->timeAdj
);
628 /* BB get server time for time conversions and add
629 code to use it and timezone since this is not UTC */
631 if (rsp
->EncryptionKeyLength
==
632 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE
)) {
633 memcpy(server
->cryptkey
, rsp
->EncryptionKey
,
634 CIFS_CRYPTO_KEY_SIZE
);
635 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
636 return -EIO
; /* need cryptkey unless plain text */
639 cifs_dbg(FYI
, "LANMAN negotiated\n");
644 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
646 cifs_dbg(VFS
, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
652 should_set_ext_sec_flag(enum securityEnum sectype
)
659 if (global_secflags
&
660 (CIFSSEC_MAY_KRB5
| CIFSSEC_MAY_NTLMSSP
))
669 CIFSSMBNegotiate(const unsigned int xid
, struct cifs_ses
*ses
)
672 NEGOTIATE_RSP
*pSMBr
;
676 struct TCP_Server_Info
*server
= ses
->server
;
680 WARN(1, "%s: server is NULL!\n", __func__
);
684 rc
= smb_init(SMB_COM_NEGOTIATE
, 0, NULL
/* no tcon yet */ ,
685 (void **) &pSMB
, (void **) &pSMBr
);
689 pSMB
->hdr
.Mid
= get_next_mid(server
);
690 pSMB
->hdr
.Flags2
|= (SMBFLG2_UNICODE
| SMBFLG2_ERR_STATUS
);
692 if (should_set_ext_sec_flag(ses
->sectype
)) {
693 cifs_dbg(FYI
, "Requesting extended security.");
694 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
699 * We know that all the name entries in the protocols array
700 * are short (< 16 bytes anyway) and are NUL terminated.
702 for (i
= 0; i
< CIFS_NUM_PROT
; i
++) {
703 size_t len
= strlen(protocols
[i
].name
) + 1;
705 memcpy(pSMB
->DialectsArray
+count
, protocols
[i
].name
, len
);
708 inc_rfc1001_len(pSMB
, count
);
709 pSMB
->ByteCount
= cpu_to_le16(count
);
711 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
712 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
716 server
->dialect
= le16_to_cpu(pSMBr
->DialectIndex
);
717 cifs_dbg(FYI
, "Dialect: %d\n", server
->dialect
);
718 /* Check wct = 1 error case */
719 if ((pSMBr
->hdr
.WordCount
< 13) || (server
->dialect
== BAD_PROT
)) {
720 /* core returns wct = 1, but we do not ask for core - otherwise
721 small wct just comes when dialect index is -1 indicating we
722 could not negotiate a common dialect */
725 } else if (pSMBr
->hdr
.WordCount
== 13) {
726 server
->negflavor
= CIFS_NEGFLAVOR_LANMAN
;
727 rc
= decode_lanman_negprot_rsp(server
, pSMBr
);
729 } else if (pSMBr
->hdr
.WordCount
!= 17) {
734 /* else wct == 17, NTLM or better */
736 server
->sec_mode
= pSMBr
->SecurityMode
;
737 if ((server
->sec_mode
& SECMODE_USER
) == 0)
738 cifs_dbg(FYI
, "share mode security\n");
740 /* one byte, so no need to convert this or EncryptionKeyLen from
742 server
->maxReq
= min_t(unsigned int, le16_to_cpu(pSMBr
->MaxMpxCount
),
744 set_credits(server
, server
->maxReq
);
745 /* probably no need to store and check maxvcs */
746 server
->maxBuf
= le32_to_cpu(pSMBr
->MaxBufferSize
);
747 server
->max_rw
= le32_to_cpu(pSMBr
->MaxRawSize
);
748 cifs_dbg(NOISY
, "Max buf = %d\n", ses
->server
->maxBuf
);
749 server
->capabilities
= le32_to_cpu(pSMBr
->Capabilities
);
750 server
->timeAdj
= (int)(__s16
)le16_to_cpu(pSMBr
->ServerTimeZone
);
751 server
->timeAdj
*= 60;
753 if (pSMBr
->EncryptionKeyLength
== CIFS_CRYPTO_KEY_SIZE
) {
754 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
755 memcpy(ses
->server
->cryptkey
, pSMBr
->u
.EncryptionKey
,
756 CIFS_CRYPTO_KEY_SIZE
);
757 } else if (pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
||
758 server
->capabilities
& CAP_EXTENDED_SECURITY
) {
759 server
->negflavor
= CIFS_NEGFLAVOR_EXTENDED
;
760 rc
= decode_ext_sec_blob(ses
, pSMBr
);
761 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
762 rc
= -EIO
; /* no crypt key only if plain text pwd */
764 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
765 server
->capabilities
&= ~CAP_EXTENDED_SECURITY
;
770 rc
= cifs_enable_signing(server
, ses
->sign
);
772 cifs_buf_release(pSMB
);
774 cifs_dbg(FYI
, "negprot rc %d\n", rc
);
779 CIFSSMBTDis(const unsigned int xid
, struct cifs_tcon
*tcon
)
781 struct smb_hdr
*smb_buffer
;
784 cifs_dbg(FYI
, "In tree disconnect\n");
786 /* BB: do we need to check this? These should never be NULL. */
787 if ((tcon
->ses
== NULL
) || (tcon
->ses
->server
== NULL
))
791 * No need to return error on this operation if tid invalidated and
792 * closed on server already e.g. due to tcp session crashing. Also,
793 * the tcon is no longer on the list, so no need to take lock before
796 if ((tcon
->need_reconnect
) || (tcon
->ses
->need_reconnect
))
799 rc
= small_smb_init(SMB_COM_TREE_DISCONNECT
, 0, tcon
,
800 (void **)&smb_buffer
);
804 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)smb_buffer
, 0);
805 cifs_small_buf_release(smb_buffer
);
807 cifs_dbg(FYI
, "Tree disconnect failed %d\n", rc
);
809 /* No need to return error on this operation if tid invalidated and
810 closed on server already e.g. due to tcp session crashing */
818 * This is a no-op for now. We're not really interested in the reply, but
819 * rather in the fact that the server sent one and that server->lstrp
822 * FIXME: maybe we should consider checking that the reply matches request?
825 cifs_echo_callback(struct mid_q_entry
*mid
)
827 struct TCP_Server_Info
*server
= mid
->callback_data
;
828 struct cifs_credits credits
= { .value
= 1, .instance
= 0 };
830 DeleteMidQEntry(mid
);
831 add_credits(server
, &credits
, CIFS_ECHO_OP
);
835 CIFSSMBEcho(struct TCP_Server_Info
*server
)
840 struct smb_rqst rqst
= { .rq_iov
= iov
,
843 cifs_dbg(FYI
, "In echo request\n");
845 rc
= small_smb_init(SMB_COM_ECHO
, 0, NULL
, (void **)&smb
);
849 if (server
->capabilities
& CAP_UNICODE
)
850 smb
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
852 /* set up echo request */
853 smb
->hdr
.Tid
= 0xffff;
854 smb
->hdr
.WordCount
= 1;
855 put_unaligned_le16(1, &smb
->EchoCount
);
856 put_bcc(1, &smb
->hdr
);
858 inc_rfc1001_len(smb
, 3);
861 iov
[0].iov_base
= smb
;
862 iov
[1].iov_len
= get_rfc1002_length(smb
);
863 iov
[1].iov_base
= (char *)smb
+ 4;
865 rc
= cifs_call_async(server
, &rqst
, NULL
, cifs_echo_callback
, NULL
,
866 server
, CIFS_NON_BLOCKING
| CIFS_ECHO_OP
, NULL
);
868 cifs_dbg(FYI
, "Echo request failed: %d\n", rc
);
870 cifs_small_buf_release(smb
);
876 CIFSSMBLogoff(const unsigned int xid
, struct cifs_ses
*ses
)
878 LOGOFF_ANDX_REQ
*pSMB
;
881 cifs_dbg(FYI
, "In SMBLogoff for session disconnect\n");
884 * BB: do we need to check validity of ses and server? They should
885 * always be valid since we have an active reference. If not, that
886 * should probably be a BUG()
888 if (!ses
|| !ses
->server
)
891 mutex_lock(&ses
->session_mutex
);
892 if (ses
->need_reconnect
)
893 goto session_already_dead
; /* no need to send SMBlogoff if uid
894 already closed due to reconnect */
895 rc
= small_smb_init(SMB_COM_LOGOFF_ANDX
, 2, NULL
, (void **)&pSMB
);
897 mutex_unlock(&ses
->session_mutex
);
901 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
903 if (ses
->server
->sign
)
904 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
906 pSMB
->hdr
.Uid
= ses
->Suid
;
908 pSMB
->AndXCommand
= 0xFF;
909 rc
= SendReceiveNoRsp(xid
, ses
, (char *) pSMB
, 0);
910 cifs_small_buf_release(pSMB
);
911 session_already_dead
:
912 mutex_unlock(&ses
->session_mutex
);
914 /* if session dead then we do not need to do ulogoff,
915 since server closed smb session, no sense reporting
923 CIFSPOSIXDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
,
924 const char *fileName
, __u16 type
,
925 const struct nls_table
*nls_codepage
, int remap
)
927 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
928 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
929 struct unlink_psx_rq
*pRqD
;
932 int bytes_returned
= 0;
933 __u16 params
, param_offset
, offset
, byte_count
;
935 cifs_dbg(FYI
, "In POSIX delete\n");
937 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
942 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
944 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
945 PATH_MAX
, nls_codepage
, remap
);
946 name_len
++; /* trailing null */
949 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
952 params
= 6 + name_len
;
953 pSMB
->MaxParameterCount
= cpu_to_le16(2);
954 pSMB
->MaxDataCount
= 0; /* BB double check this with jra */
955 pSMB
->MaxSetupCount
= 0;
960 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
961 InformationLevel
) - 4;
962 offset
= param_offset
+ params
;
964 /* Setup pointer to Request Data (inode type) */
965 pRqD
= (struct unlink_psx_rq
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
966 pRqD
->type
= cpu_to_le16(type
);
967 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
968 pSMB
->DataOffset
= cpu_to_le16(offset
);
969 pSMB
->SetupCount
= 1;
971 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
972 byte_count
= 3 /* pad */ + params
+ sizeof(struct unlink_psx_rq
);
974 pSMB
->DataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
975 pSMB
->TotalDataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
976 pSMB
->ParameterCount
= cpu_to_le16(params
);
977 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
978 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_UNLINK
);
980 inc_rfc1001_len(pSMB
, byte_count
);
981 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
982 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
983 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
985 cifs_dbg(FYI
, "Posix delete returned %d\n", rc
);
986 cifs_buf_release(pSMB
);
988 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
997 CIFSSMBDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
998 struct cifs_sb_info
*cifs_sb
)
1000 DELETE_FILE_REQ
*pSMB
= NULL
;
1001 DELETE_FILE_RSP
*pSMBr
= NULL
;
1005 int remap
= cifs_remap(cifs_sb
);
1008 rc
= smb_init(SMB_COM_DELETE
, 1, tcon
, (void **) &pSMB
,
1013 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1014 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->fileName
, name
,
1015 PATH_MAX
, cifs_sb
->local_nls
,
1017 name_len
++; /* trailing null */
1020 name_len
= copy_path_name(pSMB
->fileName
, name
);
1022 pSMB
->SearchAttributes
=
1023 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
);
1024 pSMB
->BufferFormat
= 0x04;
1025 inc_rfc1001_len(pSMB
, name_len
+ 1);
1026 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1027 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1028 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1029 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
1031 cifs_dbg(FYI
, "Error in RMFile = %d\n", rc
);
1033 cifs_buf_release(pSMB
);
1041 CIFSSMBRmDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
1042 struct cifs_sb_info
*cifs_sb
)
1044 DELETE_DIRECTORY_REQ
*pSMB
= NULL
;
1045 DELETE_DIRECTORY_RSP
*pSMBr
= NULL
;
1049 int remap
= cifs_remap(cifs_sb
);
1051 cifs_dbg(FYI
, "In CIFSSMBRmDir\n");
1053 rc
= smb_init(SMB_COM_DELETE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
1058 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1059 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
1060 PATH_MAX
, cifs_sb
->local_nls
,
1062 name_len
++; /* trailing null */
1065 name_len
= copy_path_name(pSMB
->DirName
, name
);
1068 pSMB
->BufferFormat
= 0x04;
1069 inc_rfc1001_len(pSMB
, name_len
+ 1);
1070 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1071 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1072 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1073 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_rmdirs
);
1075 cifs_dbg(FYI
, "Error in RMDir = %d\n", rc
);
1077 cifs_buf_release(pSMB
);
1084 CIFSSMBMkDir(const unsigned int xid
, struct inode
*inode
, umode_t mode
,
1085 struct cifs_tcon
*tcon
, const char *name
,
1086 struct cifs_sb_info
*cifs_sb
)
1089 CREATE_DIRECTORY_REQ
*pSMB
= NULL
;
1090 CREATE_DIRECTORY_RSP
*pSMBr
= NULL
;
1093 int remap
= cifs_remap(cifs_sb
);
1095 cifs_dbg(FYI
, "In CIFSSMBMkDir\n");
1097 rc
= smb_init(SMB_COM_CREATE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
1102 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1103 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
1104 PATH_MAX
, cifs_sb
->local_nls
,
1106 name_len
++; /* trailing null */
1109 name_len
= copy_path_name(pSMB
->DirName
, name
);
1112 pSMB
->BufferFormat
= 0x04;
1113 inc_rfc1001_len(pSMB
, name_len
+ 1);
1114 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1115 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1116 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1117 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_mkdirs
);
1119 cifs_dbg(FYI
, "Error in Mkdir = %d\n", rc
);
1121 cifs_buf_release(pSMB
);
1128 CIFSPOSIXCreate(const unsigned int xid
, struct cifs_tcon
*tcon
,
1129 __u32 posix_flags
, __u64 mode
, __u16
*netfid
,
1130 FILE_UNIX_BASIC_INFO
*pRetData
, __u32
*pOplock
,
1131 const char *name
, const struct nls_table
*nls_codepage
,
1134 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
1135 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
1138 int bytes_returned
= 0;
1139 __u16 params
, param_offset
, offset
, byte_count
, count
;
1140 OPEN_PSX_REQ
*pdata
;
1141 OPEN_PSX_RSP
*psx_rsp
;
1143 cifs_dbg(FYI
, "In POSIX Create\n");
1145 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1150 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1152 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, name
,
1153 PATH_MAX
, nls_codepage
, remap
);
1154 name_len
++; /* trailing null */
1157 name_len
= copy_path_name(pSMB
->FileName
, name
);
1160 params
= 6 + name_len
;
1161 count
= sizeof(OPEN_PSX_REQ
);
1162 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1163 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* large enough */
1164 pSMB
->MaxSetupCount
= 0;
1168 pSMB
->Reserved2
= 0;
1169 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
1170 InformationLevel
) - 4;
1171 offset
= param_offset
+ params
;
1172 pdata
= (OPEN_PSX_REQ
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
1173 pdata
->Level
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
1174 pdata
->Permissions
= cpu_to_le64(mode
);
1175 pdata
->PosixOpenFlags
= cpu_to_le32(posix_flags
);
1176 pdata
->OpenFlags
= cpu_to_le32(*pOplock
);
1177 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
1178 pSMB
->DataOffset
= cpu_to_le16(offset
);
1179 pSMB
->SetupCount
= 1;
1180 pSMB
->Reserved3
= 0;
1181 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
1182 byte_count
= 3 /* pad */ + params
+ count
;
1184 pSMB
->DataCount
= cpu_to_le16(count
);
1185 pSMB
->ParameterCount
= cpu_to_le16(params
);
1186 pSMB
->TotalDataCount
= pSMB
->DataCount
;
1187 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1188 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_OPEN
);
1189 pSMB
->Reserved4
= 0;
1190 inc_rfc1001_len(pSMB
, byte_count
);
1191 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1192 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1193 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1195 cifs_dbg(FYI
, "Posix create returned %d\n", rc
);
1196 goto psx_create_err
;
1199 cifs_dbg(FYI
, "copying inode info\n");
1200 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
1202 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)) {
1203 rc
= -EIO
; /* bad smb */
1204 goto psx_create_err
;
1207 /* copy return information to pRetData */
1208 psx_rsp
= (OPEN_PSX_RSP
*)((char *) &pSMBr
->hdr
.Protocol
1209 + le16_to_cpu(pSMBr
->t2
.DataOffset
));
1211 *pOplock
= le16_to_cpu(psx_rsp
->OplockFlags
);
1213 *netfid
= psx_rsp
->Fid
; /* cifs fid stays in le */
1214 /* Let caller know file was created so we can set the mode. */
1215 /* Do we care about the CreateAction in any other cases? */
1216 if (cpu_to_le32(FILE_CREATE
) == psx_rsp
->CreateAction
)
1217 *pOplock
|= CIFS_CREATE_ACTION
;
1218 /* check to make sure response data is there */
1219 if (psx_rsp
->ReturnedLevel
!= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
)) {
1220 pRetData
->Type
= cpu_to_le32(-1); /* unknown */
1221 cifs_dbg(NOISY
, "unknown type\n");
1223 if (get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)
1224 + sizeof(FILE_UNIX_BASIC_INFO
)) {
1225 cifs_dbg(VFS
, "Open response data too small\n");
1226 pRetData
->Type
= cpu_to_le32(-1);
1227 goto psx_create_err
;
1229 memcpy((char *) pRetData
,
1230 (char *)psx_rsp
+ sizeof(OPEN_PSX_RSP
),
1231 sizeof(FILE_UNIX_BASIC_INFO
));
1235 cifs_buf_release(pSMB
);
1237 if (posix_flags
& SMB_O_DIRECTORY
)
1238 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixmkdirs
);
1240 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixopens
);
1248 static __u16
convert_disposition(int disposition
)
1252 switch (disposition
) {
1253 case FILE_SUPERSEDE
:
1254 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1257 ofun
= SMBOPEN_OAPPEND
;
1260 ofun
= SMBOPEN_OCREATE
;
1263 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OAPPEND
;
1265 case FILE_OVERWRITE
:
1266 ofun
= SMBOPEN_OTRUNC
;
1268 case FILE_OVERWRITE_IF
:
1269 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1272 cifs_dbg(FYI
, "unknown disposition %d\n", disposition
);
1273 ofun
= SMBOPEN_OAPPEND
; /* regular open */
1279 access_flags_to_smbopen_mode(const int access_flags
)
1281 int masked_flags
= access_flags
& (GENERIC_READ
| GENERIC_WRITE
);
1283 if (masked_flags
== GENERIC_READ
)
1284 return SMBOPEN_READ
;
1285 else if (masked_flags
== GENERIC_WRITE
)
1286 return SMBOPEN_WRITE
;
1288 /* just go for read/write */
1289 return SMBOPEN_READWRITE
;
1293 SMBLegacyOpen(const unsigned int xid
, struct cifs_tcon
*tcon
,
1294 const char *fileName
, const int openDisposition
,
1295 const int access_flags
, const int create_options
, __u16
*netfid
,
1296 int *pOplock
, FILE_ALL_INFO
*pfile_info
,
1297 const struct nls_table
*nls_codepage
, int remap
)
1300 OPENX_REQ
*pSMB
= NULL
;
1301 OPENX_RSP
*pSMBr
= NULL
;
1307 rc
= smb_init(SMB_COM_OPEN_ANDX
, 15, tcon
, (void **) &pSMB
,
1312 pSMB
->AndXCommand
= 0xFF; /* none */
1314 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1315 count
= 1; /* account for one byte pad to word boundary */
1317 cifsConvertToUTF16((__le16
*) (pSMB
->fileName
+ 1),
1318 fileName
, PATH_MAX
, nls_codepage
, remap
);
1319 name_len
++; /* trailing null */
1322 count
= 0; /* no pad */
1323 name_len
= copy_path_name(pSMB
->fileName
, fileName
);
1325 if (*pOplock
& REQ_OPLOCK
)
1326 pSMB
->OpenFlags
= cpu_to_le16(REQ_OPLOCK
);
1327 else if (*pOplock
& REQ_BATCHOPLOCK
)
1328 pSMB
->OpenFlags
= cpu_to_le16(REQ_BATCHOPLOCK
);
1330 pSMB
->OpenFlags
|= cpu_to_le16(REQ_MORE_INFO
);
1331 pSMB
->Mode
= cpu_to_le16(access_flags_to_smbopen_mode(access_flags
));
1332 pSMB
->Mode
|= cpu_to_le16(0x40); /* deny none */
1333 /* set file as system file if special file such
1334 as fifo and server expecting SFU style and
1335 no Unix extensions */
1337 if (create_options
& CREATE_OPTION_SPECIAL
)
1338 pSMB
->FileAttributes
= cpu_to_le16(ATTR_SYSTEM
);
1339 else /* BB FIXME BB */
1340 pSMB
->FileAttributes
= cpu_to_le16(0/*ATTR_NORMAL*/);
1342 if (create_options
& CREATE_OPTION_READONLY
)
1343 pSMB
->FileAttributes
|= cpu_to_le16(ATTR_READONLY
);
1346 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1347 CREATE_OPTIONS_MASK); */
1348 /* BB FIXME END BB */
1350 pSMB
->Sattr
= cpu_to_le16(ATTR_HIDDEN
| ATTR_SYSTEM
| ATTR_DIRECTORY
);
1351 pSMB
->OpenFunction
= cpu_to_le16(convert_disposition(openDisposition
));
1353 inc_rfc1001_len(pSMB
, count
);
1355 pSMB
->ByteCount
= cpu_to_le16(count
);
1356 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1357 (struct smb_hdr
*)pSMBr
, &bytes_returned
, 0);
1358 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1360 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1362 /* BB verify if wct == 15 */
1364 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1366 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
1367 /* Let caller know file was created so we can set the mode. */
1368 /* Do we care about the CreateAction in any other cases? */
1370 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1371 *pOplock |= CIFS_CREATE_ACTION; */
1375 pfile_info
->CreationTime
= 0; /* BB convert CreateTime*/
1376 pfile_info
->LastAccessTime
= 0; /* BB fixme */
1377 pfile_info
->LastWriteTime
= 0; /* BB fixme */
1378 pfile_info
->ChangeTime
= 0; /* BB fixme */
1379 pfile_info
->Attributes
=
1380 cpu_to_le32(le16_to_cpu(pSMBr
->FileAttributes
));
1381 /* the file_info buf is endian converted by caller */
1382 pfile_info
->AllocationSize
=
1383 cpu_to_le64(le32_to_cpu(pSMBr
->EndOfFile
));
1384 pfile_info
->EndOfFile
= pfile_info
->AllocationSize
;
1385 pfile_info
->NumberOfLinks
= cpu_to_le32(1);
1386 pfile_info
->DeletePending
= 0;
1390 cifs_buf_release(pSMB
);
1397 CIFS_open(const unsigned int xid
, struct cifs_open_parms
*oparms
, int *oplock
,
1401 OPEN_REQ
*req
= NULL
;
1402 OPEN_RSP
*rsp
= NULL
;
1406 struct cifs_sb_info
*cifs_sb
= oparms
->cifs_sb
;
1407 struct cifs_tcon
*tcon
= oparms
->tcon
;
1408 int remap
= cifs_remap(cifs_sb
);
1409 const struct nls_table
*nls
= cifs_sb
->local_nls
;
1410 int create_options
= oparms
->create_options
;
1411 int desired_access
= oparms
->desired_access
;
1412 int disposition
= oparms
->disposition
;
1413 const char *path
= oparms
->path
;
1416 rc
= smb_init(SMB_COM_NT_CREATE_ANDX
, 24, tcon
, (void **)&req
,
1421 /* no commands go after this */
1422 req
->AndXCommand
= 0xFF;
1424 if (req
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1425 /* account for one byte pad to word boundary */
1427 name_len
= cifsConvertToUTF16((__le16
*)(req
->fileName
+ 1),
1428 path
, PATH_MAX
, nls
, remap
);
1432 req
->NameLength
= cpu_to_le16(name_len
);
1434 /* BB improve check for buffer overruns BB */
1437 name_len
= copy_path_name(req
->fileName
, path
);
1438 req
->NameLength
= cpu_to_le16(name_len
);
1441 if (*oplock
& REQ_OPLOCK
)
1442 req
->OpenFlags
= cpu_to_le32(REQ_OPLOCK
);
1443 else if (*oplock
& REQ_BATCHOPLOCK
)
1444 req
->OpenFlags
= cpu_to_le32(REQ_BATCHOPLOCK
);
1446 req
->DesiredAccess
= cpu_to_le32(desired_access
);
1447 req
->AllocationSize
= 0;
1450 * Set file as system file if special file such as fifo and server
1451 * expecting SFU style and no Unix extensions.
1453 if (create_options
& CREATE_OPTION_SPECIAL
)
1454 req
->FileAttributes
= cpu_to_le32(ATTR_SYSTEM
);
1456 req
->FileAttributes
= cpu_to_le32(ATTR_NORMAL
);
1459 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1460 * sensitive checks for other servers such as Samba.
1462 if (tcon
->ses
->capabilities
& CAP_UNIX
)
1463 req
->FileAttributes
|= cpu_to_le32(ATTR_POSIX_SEMANTICS
);
1465 if (create_options
& CREATE_OPTION_READONLY
)
1466 req
->FileAttributes
|= cpu_to_le32(ATTR_READONLY
);
1468 req
->ShareAccess
= cpu_to_le32(FILE_SHARE_ALL
);
1469 req
->CreateDisposition
= cpu_to_le32(disposition
);
1470 req
->CreateOptions
= cpu_to_le32(create_options
& CREATE_OPTIONS_MASK
);
1472 /* BB Expirement with various impersonation levels and verify */
1473 req
->ImpersonationLevel
= cpu_to_le32(SECURITY_IMPERSONATION
);
1474 req
->SecurityFlags
= SECURITY_CONTEXT_TRACKING
|SECURITY_EFFECTIVE_ONLY
;
1477 inc_rfc1001_len(req
, count
);
1479 req
->ByteCount
= cpu_to_le16(count
);
1480 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*)req
,
1481 (struct smb_hdr
*)rsp
, &bytes_returned
, 0);
1482 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1484 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1485 cifs_buf_release(req
);
1491 /* 1 byte no need to le_to_cpu */
1492 *oplock
= rsp
->OplockLevel
;
1493 /* cifs fid stays in le */
1494 oparms
->fid
->netfid
= rsp
->Fid
;
1495 oparms
->fid
->access
= desired_access
;
1497 /* Let caller know file was created so we can set the mode. */
1498 /* Do we care about the CreateAction in any other cases? */
1499 if (cpu_to_le32(FILE_CREATE
) == rsp
->CreateAction
)
1500 *oplock
|= CIFS_CREATE_ACTION
;
1503 /* copy from CreationTime to Attributes */
1504 memcpy((char *)buf
, (char *)&rsp
->CreationTime
, 36);
1505 /* the file_info buf is endian converted by caller */
1506 buf
->AllocationSize
= rsp
->AllocationSize
;
1507 buf
->EndOfFile
= rsp
->EndOfFile
;
1508 buf
->NumberOfLinks
= cpu_to_le32(1);
1509 buf
->DeletePending
= 0;
1512 cifs_buf_release(req
);
1517 * Discard any remaining data in the current SMB. To do this, we borrow the
1521 cifs_discard_remaining_data(struct TCP_Server_Info
*server
)
1523 unsigned int rfclen
= server
->pdu_size
;
1524 int remaining
= rfclen
+ server
->vals
->header_preamble_size
-
1527 while (remaining
> 0) {
1530 length
= cifs_read_from_socket(server
, server
->bigbuf
,
1531 min_t(unsigned int, remaining
,
1532 CIFSMaxBufSize
+ MAX_HEADER_SIZE(server
)));
1535 server
->total_read
+= length
;
1536 remaining
-= length
;
1543 __cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
,
1548 length
= cifs_discard_remaining_data(server
);
1549 dequeue_mid(mid
, malformed
);
1550 mid
->resp_buf
= server
->smallbuf
;
1551 server
->smallbuf
= NULL
;
1556 cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1558 struct cifs_readdata
*rdata
= mid
->callback_data
;
1560 return __cifs_readv_discard(server
, mid
, rdata
->result
);
1564 cifs_readv_receive(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1567 unsigned int data_offset
, data_len
;
1568 struct cifs_readdata
*rdata
= mid
->callback_data
;
1569 char *buf
= server
->smallbuf
;
1570 unsigned int buflen
= server
->pdu_size
+
1571 server
->vals
->header_preamble_size
;
1572 bool use_rdma_mr
= false;
1574 cifs_dbg(FYI
, "%s: mid=%llu offset=%llu bytes=%u\n",
1575 __func__
, mid
->mid
, rdata
->offset
, rdata
->bytes
);
1578 * read the rest of READ_RSP header (sans Data array), or whatever we
1579 * can if there's not enough data. At this point, we've read down to
1582 len
= min_t(unsigned int, buflen
, server
->vals
->read_rsp_size
) -
1583 HEADER_SIZE(server
) + 1;
1585 length
= cifs_read_from_socket(server
,
1586 buf
+ HEADER_SIZE(server
) - 1, len
);
1589 server
->total_read
+= length
;
1591 if (server
->ops
->is_session_expired
&&
1592 server
->ops
->is_session_expired(buf
)) {
1593 cifs_reconnect(server
);
1594 wake_up(&server
->response_q
);
1598 if (server
->ops
->is_status_pending
&&
1599 server
->ops
->is_status_pending(buf
, server
)) {
1600 cifs_discard_remaining_data(server
);
1604 /* set up first two iov for signature check and to get credits */
1605 rdata
->iov
[0].iov_base
= buf
;
1606 rdata
->iov
[0].iov_len
= server
->vals
->header_preamble_size
;
1607 rdata
->iov
[1].iov_base
= buf
+ server
->vals
->header_preamble_size
;
1608 rdata
->iov
[1].iov_len
=
1609 server
->total_read
- server
->vals
->header_preamble_size
;
1610 cifs_dbg(FYI
, "0: iov_base=%p iov_len=%zu\n",
1611 rdata
->iov
[0].iov_base
, rdata
->iov
[0].iov_len
);
1612 cifs_dbg(FYI
, "1: iov_base=%p iov_len=%zu\n",
1613 rdata
->iov
[1].iov_base
, rdata
->iov
[1].iov_len
);
1615 /* Was the SMB read successful? */
1616 rdata
->result
= server
->ops
->map_error(buf
, false);
1617 if (rdata
->result
!= 0) {
1618 cifs_dbg(FYI
, "%s: server returned error %d\n",
1619 __func__
, rdata
->result
);
1620 /* normal error on read response */
1621 return __cifs_readv_discard(server
, mid
, false);
1624 /* Is there enough to get to the rest of the READ_RSP header? */
1625 if (server
->total_read
< server
->vals
->read_rsp_size
) {
1626 cifs_dbg(FYI
, "%s: server returned short header. got=%u expected=%zu\n",
1627 __func__
, server
->total_read
,
1628 server
->vals
->read_rsp_size
);
1629 rdata
->result
= -EIO
;
1630 return cifs_readv_discard(server
, mid
);
1633 data_offset
= server
->ops
->read_data_offset(buf
) +
1634 server
->vals
->header_preamble_size
;
1635 if (data_offset
< server
->total_read
) {
1637 * win2k8 sometimes sends an offset of 0 when the read
1638 * is beyond the EOF. Treat it as if the data starts just after
1641 cifs_dbg(FYI
, "%s: data offset (%u) inside read response header\n",
1642 __func__
, data_offset
);
1643 data_offset
= server
->total_read
;
1644 } else if (data_offset
> MAX_CIFS_SMALL_BUFFER_SIZE
) {
1645 /* data_offset is beyond the end of smallbuf */
1646 cifs_dbg(FYI
, "%s: data offset (%u) beyond end of smallbuf\n",
1647 __func__
, data_offset
);
1648 rdata
->result
= -EIO
;
1649 return cifs_readv_discard(server
, mid
);
1652 cifs_dbg(FYI
, "%s: total_read=%u data_offset=%u\n",
1653 __func__
, server
->total_read
, data_offset
);
1655 len
= data_offset
- server
->total_read
;
1657 /* read any junk before data into the rest of smallbuf */
1658 length
= cifs_read_from_socket(server
,
1659 buf
+ server
->total_read
, len
);
1662 server
->total_read
+= length
;
1665 /* how much data is in the response? */
1666 #ifdef CONFIG_CIFS_SMB_DIRECT
1667 use_rdma_mr
= rdata
->mr
;
1669 data_len
= server
->ops
->read_data_length(buf
, use_rdma_mr
);
1670 if (!use_rdma_mr
&& (data_offset
+ data_len
> buflen
)) {
1671 /* data_len is corrupt -- discard frame */
1672 rdata
->result
= -EIO
;
1673 return cifs_readv_discard(server
, mid
);
1676 length
= rdata
->read_into_pages(server
, rdata
, data_len
);
1680 server
->total_read
+= length
;
1682 cifs_dbg(FYI
, "total_read=%u buflen=%u remaining=%u\n",
1683 server
->total_read
, buflen
, data_len
);
1685 /* discard anything left over */
1686 if (server
->total_read
< buflen
)
1687 return cifs_readv_discard(server
, mid
);
1689 dequeue_mid(mid
, false);
1690 mid
->resp_buf
= server
->smallbuf
;
1691 server
->smallbuf
= NULL
;
1696 cifs_readv_callback(struct mid_q_entry
*mid
)
1698 struct cifs_readdata
*rdata
= mid
->callback_data
;
1699 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1700 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
1701 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1703 .rq_pages
= rdata
->pages
,
1704 .rq_offset
= rdata
->page_offset
,
1705 .rq_npages
= rdata
->nr_pages
,
1706 .rq_pagesz
= rdata
->pagesz
,
1707 .rq_tailsz
= rdata
->tailsz
};
1708 struct cifs_credits credits
= { .value
= 1, .instance
= 0 };
1710 cifs_dbg(FYI
, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1711 __func__
, mid
->mid
, mid
->mid_state
, rdata
->result
,
1714 switch (mid
->mid_state
) {
1715 case MID_RESPONSE_RECEIVED
:
1716 /* result already set, check signature */
1720 rc
= cifs_verify_signature(&rqst
, server
,
1721 mid
->sequence_number
);
1723 cifs_dbg(VFS
, "SMB signature verification returned error = %d\n",
1726 /* FIXME: should this be counted toward the initiating task? */
1727 task_io_account_read(rdata
->got_bytes
);
1728 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1730 case MID_REQUEST_SUBMITTED
:
1731 case MID_RETRY_NEEDED
:
1732 rdata
->result
= -EAGAIN
;
1733 if (server
->sign
&& rdata
->got_bytes
)
1734 /* reset bytes number since we can not check a sign */
1735 rdata
->got_bytes
= 0;
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
);
1741 rdata
->result
= -EIO
;
1744 queue_work(cifsiod_wq
, &rdata
->work
);
1745 DeleteMidQEntry(mid
);
1746 add_credits(server
, &credits
, 0);
1749 /* cifs_async_readv - send an async write, and set up mid to handle result */
1751 cifs_async_readv(struct cifs_readdata
*rdata
)
1754 READ_REQ
*smb
= NULL
;
1756 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1757 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1760 cifs_dbg(FYI
, "%s: offset=%llu bytes=%u\n",
1761 __func__
, rdata
->offset
, rdata
->bytes
);
1763 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1766 wct
= 10; /* old style read */
1767 if ((rdata
->offset
>> 32) > 0) {
1768 /* can not handle this big offset for old */
1773 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **)&smb
);
1777 smb
->hdr
.Pid
= cpu_to_le16((__u16
)rdata
->pid
);
1778 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(rdata
->pid
>> 16));
1780 smb
->AndXCommand
= 0xFF; /* none */
1781 smb
->Fid
= rdata
->cfile
->fid
.netfid
;
1782 smb
->OffsetLow
= cpu_to_le32(rdata
->offset
& 0xFFFFFFFF);
1784 smb
->OffsetHigh
= cpu_to_le32(rdata
->offset
>> 32);
1786 smb
->MaxCount
= cpu_to_le16(rdata
->bytes
& 0xFFFF);
1787 smb
->MaxCountHigh
= cpu_to_le32(rdata
->bytes
>> 16);
1791 /* old style read */
1792 struct smb_com_readx_req
*smbr
=
1793 (struct smb_com_readx_req
*)smb
;
1794 smbr
->ByteCount
= 0;
1797 /* 4 for RFC1001 length + 1 for BCC */
1798 rdata
->iov
[0].iov_base
= smb
;
1799 rdata
->iov
[0].iov_len
= 4;
1800 rdata
->iov
[1].iov_base
= (char *)smb
+ 4;
1801 rdata
->iov
[1].iov_len
= get_rfc1002_length(smb
);
1803 kref_get(&rdata
->refcount
);
1804 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, cifs_readv_receive
,
1805 cifs_readv_callback
, NULL
, rdata
, 0, NULL
);
1808 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1810 kref_put(&rdata
->refcount
, cifs_readdata_release
);
1812 cifs_small_buf_release(smb
);
1817 CIFSSMBRead(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1818 unsigned int *nbytes
, char **buf
, int *pbuf_type
)
1821 READ_REQ
*pSMB
= NULL
;
1822 READ_RSP
*pSMBr
= NULL
;
1823 char *pReadData
= NULL
;
1825 int resp_buf_type
= 0;
1827 struct kvec rsp_iov
;
1828 __u32 pid
= io_parms
->pid
;
1829 __u16 netfid
= io_parms
->netfid
;
1830 __u64 offset
= io_parms
->offset
;
1831 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1832 unsigned int count
= io_parms
->length
;
1834 cifs_dbg(FYI
, "Reading %d bytes on fid %d\n", count
, netfid
);
1835 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1838 wct
= 10; /* old style read */
1839 if ((offset
>> 32) > 0) {
1840 /* can not handle this big offset for old */
1846 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **) &pSMB
);
1850 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1851 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1853 /* tcon and ses pointer are checked in smb_init */
1854 if (tcon
->ses
->server
== NULL
)
1855 return -ECONNABORTED
;
1857 pSMB
->AndXCommand
= 0xFF; /* none */
1859 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1861 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1863 pSMB
->Remaining
= 0;
1864 pSMB
->MaxCount
= cpu_to_le16(count
& 0xFFFF);
1865 pSMB
->MaxCountHigh
= cpu_to_le32(count
>> 16);
1867 pSMB
->ByteCount
= 0; /* no need to do le conversion since 0 */
1869 /* old style read */
1870 struct smb_com_readx_req
*pSMBW
=
1871 (struct smb_com_readx_req
*)pSMB
;
1872 pSMBW
->ByteCount
= 0;
1875 iov
[0].iov_base
= (char *)pSMB
;
1876 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
1877 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1, &resp_buf_type
,
1878 CIFS_LOG_ERROR
, &rsp_iov
);
1879 cifs_small_buf_release(pSMB
);
1880 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1881 pSMBr
= (READ_RSP
*)rsp_iov
.iov_base
;
1883 cifs_dbg(VFS
, "Send error in read = %d\n", rc
);
1885 int data_length
= le16_to_cpu(pSMBr
->DataLengthHigh
);
1886 data_length
= data_length
<< 16;
1887 data_length
+= le16_to_cpu(pSMBr
->DataLength
);
1888 *nbytes
= data_length
;
1890 /*check that DataLength would not go beyond end of SMB */
1891 if ((data_length
> CIFSMaxBufSize
)
1892 || (data_length
> count
)) {
1893 cifs_dbg(FYI
, "bad length %d for count %d\n",
1894 data_length
, count
);
1898 pReadData
= (char *) (&pSMBr
->hdr
.Protocol
) +
1899 le16_to_cpu(pSMBr
->DataOffset
);
1900 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1901 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1903 }*/ /* can not use copy_to_user when using page cache*/
1905 memcpy(*buf
, pReadData
, data_length
);
1910 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
1911 } else if (resp_buf_type
!= CIFS_NO_BUFFER
) {
1912 /* return buffer to caller to free */
1913 *buf
= rsp_iov
.iov_base
;
1914 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1915 *pbuf_type
= CIFS_SMALL_BUFFER
;
1916 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1917 *pbuf_type
= CIFS_LARGE_BUFFER
;
1918 } /* else no valid buffer on return - leave as null */
1920 /* Note: On -EAGAIN error only caller can retry on handle based calls
1921 since file handle passed in no longer valid */
1927 CIFSSMBWrite(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1928 unsigned int *nbytes
, const char *buf
)
1931 WRITE_REQ
*pSMB
= NULL
;
1932 WRITE_RSP
*pSMBr
= NULL
;
1933 int bytes_returned
, wct
;
1936 __u32 pid
= io_parms
->pid
;
1937 __u16 netfid
= io_parms
->netfid
;
1938 __u64 offset
= io_parms
->offset
;
1939 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1940 unsigned int count
= io_parms
->length
;
1944 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1945 if (tcon
->ses
== NULL
)
1946 return -ECONNABORTED
;
1948 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1952 if ((offset
>> 32) > 0) {
1953 /* can not handle big offset for old srv */
1958 rc
= smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
,
1963 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1964 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1966 /* tcon and ses pointer are checked in smb_init */
1967 if (tcon
->ses
->server
== NULL
)
1968 return -ECONNABORTED
;
1970 pSMB
->AndXCommand
= 0xFF; /* none */
1972 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1974 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1976 pSMB
->Reserved
= 0xFFFFFFFF;
1977 pSMB
->WriteMode
= 0;
1978 pSMB
->Remaining
= 0;
1980 /* Can increase buffer size if buffer is big enough in some cases ie we
1981 can send more if LARGE_WRITE_X capability returned by the server and if
1982 our buffer is big enough or if we convert to iovecs on socket writes
1983 and eliminate the copy to the CIFS buffer */
1984 if (tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
) {
1985 bytes_sent
= min_t(const unsigned int, CIFSMaxBufSize
, count
);
1987 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
)
1991 if (bytes_sent
> count
)
1994 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1996 memcpy(pSMB
->Data
, buf
, bytes_sent
);
1997 else if (count
!= 0) {
1999 cifs_buf_release(pSMB
);
2001 } /* else setting file size with write of zero bytes */
2003 byte_count
= bytes_sent
+ 1; /* pad */
2004 else /* wct == 12 */
2005 byte_count
= bytes_sent
+ 5; /* bigger pad, smaller smb hdr */
2007 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
& 0xFFFF);
2008 pSMB
->DataLengthHigh
= cpu_to_le16(bytes_sent
>> 16);
2009 inc_rfc1001_len(pSMB
, byte_count
);
2012 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2013 else { /* old style write has byte count 4 bytes earlier
2015 struct smb_com_writex_req
*pSMBW
=
2016 (struct smb_com_writex_req
*)pSMB
;
2017 pSMBW
->ByteCount
= cpu_to_le16(byte_count
);
2020 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2021 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2022 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2024 cifs_dbg(FYI
, "Send error in write = %d\n", rc
);
2026 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2027 *nbytes
= (*nbytes
) << 16;
2028 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2031 * Mask off high 16 bits when bytes written as returned by the
2032 * server is greater than bytes requested by the client. Some
2033 * OS/2 servers are known to set incorrect CountHigh values.
2035 if (*nbytes
> count
)
2039 cifs_buf_release(pSMB
);
2041 /* Note: On -EAGAIN error only caller can retry on handle based calls
2042 since file handle passed in no longer valid */
2048 cifs_writedata_release(struct kref
*refcount
)
2050 struct cifs_writedata
*wdata
= container_of(refcount
,
2051 struct cifs_writedata
, refcount
);
2052 #ifdef CONFIG_CIFS_SMB_DIRECT
2054 smbd_deregister_mr(wdata
->mr
);
2060 cifsFileInfo_put(wdata
->cfile
);
2062 kvfree(wdata
->pages
);
2067 * Write failed with a retryable error. Resend the write request. It's also
2068 * possible that the page was redirtied so re-clean the page.
2071 cifs_writev_requeue(struct cifs_writedata
*wdata
)
2074 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
2075 struct TCP_Server_Info
*server
;
2076 unsigned int rest_len
;
2078 server
= tlink_tcon(wdata
->cfile
->tlink
)->ses
->server
;
2080 rest_len
= wdata
->bytes
;
2082 struct cifs_writedata
*wdata2
;
2083 unsigned int j
, nr_pages
, wsize
, tailsz
, cur_len
;
2085 wsize
= server
->ops
->wp_retry_size(inode
);
2086 if (wsize
< rest_len
) {
2087 nr_pages
= wsize
/ PAGE_SIZE
;
2092 cur_len
= nr_pages
* PAGE_SIZE
;
2095 nr_pages
= DIV_ROUND_UP(rest_len
, PAGE_SIZE
);
2097 tailsz
= rest_len
- (nr_pages
- 1) * PAGE_SIZE
;
2100 wdata2
= cifs_writedata_alloc(nr_pages
, cifs_writev_complete
);
2106 for (j
= 0; j
< nr_pages
; j
++) {
2107 wdata2
->pages
[j
] = wdata
->pages
[i
+ j
];
2108 lock_page(wdata2
->pages
[j
]);
2109 clear_page_dirty_for_io(wdata2
->pages
[j
]);
2112 wdata2
->sync_mode
= wdata
->sync_mode
;
2113 wdata2
->nr_pages
= nr_pages
;
2114 wdata2
->offset
= page_offset(wdata2
->pages
[0]);
2115 wdata2
->pagesz
= PAGE_SIZE
;
2116 wdata2
->tailsz
= tailsz
;
2117 wdata2
->bytes
= cur_len
;
2119 rc
= cifs_get_writable_file(CIFS_I(inode
), FIND_WR_ANY
,
2121 if (!wdata2
->cfile
) {
2122 cifs_dbg(VFS
, "No writable handle to retry writepages rc=%d\n",
2124 if (!is_retryable_error(rc
))
2127 wdata2
->pid
= wdata2
->cfile
->pid
;
2128 rc
= server
->ops
->async_writev(wdata2
,
2129 cifs_writedata_release
);
2132 for (j
= 0; j
< nr_pages
; j
++) {
2133 unlock_page(wdata2
->pages
[j
]);
2134 if (rc
!= 0 && !is_retryable_error(rc
)) {
2135 SetPageError(wdata2
->pages
[j
]);
2136 end_page_writeback(wdata2
->pages
[j
]);
2137 put_page(wdata2
->pages
[j
]);
2142 kref_put(&wdata2
->refcount
, cifs_writedata_release
);
2143 if (is_retryable_error(rc
))
2149 rest_len
-= cur_len
;
2151 } while (i
< wdata
->nr_pages
);
2153 /* cleanup remaining pages from the original wdata */
2154 for (; i
< wdata
->nr_pages
; i
++) {
2155 SetPageError(wdata
->pages
[i
]);
2156 end_page_writeback(wdata
->pages
[i
]);
2157 put_page(wdata
->pages
[i
]);
2160 if (rc
!= 0 && !is_retryable_error(rc
))
2161 mapping_set_error(inode
->i_mapping
, rc
);
2162 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2166 cifs_writev_complete(struct work_struct
*work
)
2168 struct cifs_writedata
*wdata
= container_of(work
,
2169 struct cifs_writedata
, work
);
2170 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
2173 if (wdata
->result
== 0) {
2174 spin_lock(&inode
->i_lock
);
2175 cifs_update_eof(CIFS_I(inode
), wdata
->offset
, wdata
->bytes
);
2176 spin_unlock(&inode
->i_lock
);
2177 cifs_stats_bytes_written(tlink_tcon(wdata
->cfile
->tlink
),
2179 } else if (wdata
->sync_mode
== WB_SYNC_ALL
&& wdata
->result
== -EAGAIN
)
2180 return cifs_writev_requeue(wdata
);
2182 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
2183 struct page
*page
= wdata
->pages
[i
];
2184 if (wdata
->result
== -EAGAIN
)
2185 __set_page_dirty_nobuffers(page
);
2186 else if (wdata
->result
< 0)
2188 end_page_writeback(page
);
2191 if (wdata
->result
!= -EAGAIN
)
2192 mapping_set_error(inode
->i_mapping
, wdata
->result
);
2193 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2196 struct cifs_writedata
*
2197 cifs_writedata_alloc(unsigned int nr_pages
, work_func_t complete
)
2199 struct page
**pages
=
2200 kcalloc(nr_pages
, sizeof(struct page
*), GFP_NOFS
);
2202 return cifs_writedata_direct_alloc(pages
, complete
);
2207 struct cifs_writedata
*
2208 cifs_writedata_direct_alloc(struct page
**pages
, work_func_t complete
)
2210 struct cifs_writedata
*wdata
;
2212 wdata
= kzalloc(sizeof(*wdata
), GFP_NOFS
);
2213 if (wdata
!= NULL
) {
2214 wdata
->pages
= pages
;
2215 kref_init(&wdata
->refcount
);
2216 INIT_LIST_HEAD(&wdata
->list
);
2217 init_completion(&wdata
->done
);
2218 INIT_WORK(&wdata
->work
, complete
);
2224 * Check the mid_state and signature on received buffer (if any), and queue the
2225 * workqueue completion task.
2228 cifs_writev_callback(struct mid_q_entry
*mid
)
2230 struct cifs_writedata
*wdata
= mid
->callback_data
;
2231 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2232 unsigned int written
;
2233 WRITE_RSP
*smb
= (WRITE_RSP
*)mid
->resp_buf
;
2234 struct cifs_credits credits
= { .value
= 1, .instance
= 0 };
2236 switch (mid
->mid_state
) {
2237 case MID_RESPONSE_RECEIVED
:
2238 wdata
->result
= cifs_check_receive(mid
, tcon
->ses
->server
, 0);
2239 if (wdata
->result
!= 0)
2242 written
= le16_to_cpu(smb
->CountHigh
);
2244 written
+= le16_to_cpu(smb
->Count
);
2246 * Mask off high 16 bits when bytes written as returned
2247 * by the server is greater than bytes requested by the
2248 * client. OS/2 servers are known to set incorrect
2251 if (written
> wdata
->bytes
)
2254 if (written
< wdata
->bytes
)
2255 wdata
->result
= -ENOSPC
;
2257 wdata
->bytes
= written
;
2259 case MID_REQUEST_SUBMITTED
:
2260 case MID_RETRY_NEEDED
:
2261 wdata
->result
= -EAGAIN
;
2264 wdata
->result
= -EIO
;
2268 queue_work(cifsiod_wq
, &wdata
->work
);
2269 DeleteMidQEntry(mid
);
2270 add_credits(tcon
->ses
->server
, &credits
, 0);
2273 /* cifs_async_writev - send an async write, and set up mid to handle result */
2275 cifs_async_writev(struct cifs_writedata
*wdata
,
2276 void (*release
)(struct kref
*kref
))
2279 WRITE_REQ
*smb
= NULL
;
2281 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2283 struct smb_rqst rqst
= { };
2285 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2289 if (wdata
->offset
>> 32 > 0) {
2290 /* can not handle big offset for old srv */
2295 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **)&smb
);
2297 goto async_writev_out
;
2299 smb
->hdr
.Pid
= cpu_to_le16((__u16
)wdata
->pid
);
2300 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(wdata
->pid
>> 16));
2302 smb
->AndXCommand
= 0xFF; /* none */
2303 smb
->Fid
= wdata
->cfile
->fid
.netfid
;
2304 smb
->OffsetLow
= cpu_to_le32(wdata
->offset
& 0xFFFFFFFF);
2306 smb
->OffsetHigh
= cpu_to_le32(wdata
->offset
>> 32);
2307 smb
->Reserved
= 0xFFFFFFFF;
2312 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2314 /* 4 for RFC1001 length + 1 for BCC */
2316 iov
[0].iov_base
= smb
;
2317 iov
[1].iov_len
= get_rfc1002_length(smb
) + 1;
2318 iov
[1].iov_base
= (char *)smb
+ 4;
2322 rqst
.rq_pages
= wdata
->pages
;
2323 rqst
.rq_offset
= wdata
->page_offset
;
2324 rqst
.rq_npages
= wdata
->nr_pages
;
2325 rqst
.rq_pagesz
= wdata
->pagesz
;
2326 rqst
.rq_tailsz
= wdata
->tailsz
;
2328 cifs_dbg(FYI
, "async write at %llu %u bytes\n",
2329 wdata
->offset
, wdata
->bytes
);
2331 smb
->DataLengthLow
= cpu_to_le16(wdata
->bytes
& 0xFFFF);
2332 smb
->DataLengthHigh
= cpu_to_le16(wdata
->bytes
>> 16);
2335 inc_rfc1001_len(&smb
->hdr
, wdata
->bytes
+ 1);
2336 put_bcc(wdata
->bytes
+ 1, &smb
->hdr
);
2339 struct smb_com_writex_req
*smbw
=
2340 (struct smb_com_writex_req
*)smb
;
2341 inc_rfc1001_len(&smbw
->hdr
, wdata
->bytes
+ 5);
2342 put_bcc(wdata
->bytes
+ 5, &smbw
->hdr
);
2343 iov
[1].iov_len
+= 4; /* pad bigger by four bytes */
2346 kref_get(&wdata
->refcount
);
2347 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, NULL
,
2348 cifs_writev_callback
, NULL
, wdata
, 0, NULL
);
2351 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2353 kref_put(&wdata
->refcount
, release
);
2356 cifs_small_buf_release(smb
);
2361 CIFSSMBWrite2(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
2362 unsigned int *nbytes
, struct kvec
*iov
, int n_vec
)
2365 WRITE_REQ
*pSMB
= NULL
;
2368 int resp_buf_type
= 0;
2369 __u32 pid
= io_parms
->pid
;
2370 __u16 netfid
= io_parms
->netfid
;
2371 __u64 offset
= io_parms
->offset
;
2372 struct cifs_tcon
*tcon
= io_parms
->tcon
;
2373 unsigned int count
= io_parms
->length
;
2374 struct kvec rsp_iov
;
2378 cifs_dbg(FYI
, "write2 at %lld %d bytes\n", (long long)offset
, count
);
2380 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2384 if ((offset
>> 32) > 0) {
2385 /* can not handle big offset for old srv */
2389 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
);
2393 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
2394 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
2396 /* tcon and ses pointer are checked in smb_init */
2397 if (tcon
->ses
->server
== NULL
)
2398 return -ECONNABORTED
;
2400 pSMB
->AndXCommand
= 0xFF; /* none */
2402 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
2404 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
2405 pSMB
->Reserved
= 0xFFFFFFFF;
2406 pSMB
->WriteMode
= 0;
2407 pSMB
->Remaining
= 0;
2410 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2412 pSMB
->DataLengthLow
= cpu_to_le16(count
& 0xFFFF);
2413 pSMB
->DataLengthHigh
= cpu_to_le16(count
>> 16);
2414 /* header + 1 byte pad */
2415 smb_hdr_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 1;
2417 inc_rfc1001_len(pSMB
, count
+ 1);
2418 else /* wct == 12 */
2419 inc_rfc1001_len(pSMB
, count
+ 5); /* smb data starts later */
2421 pSMB
->ByteCount
= cpu_to_le16(count
+ 1);
2422 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2423 struct smb_com_writex_req
*pSMBW
=
2424 (struct smb_com_writex_req
*)pSMB
;
2425 pSMBW
->ByteCount
= cpu_to_le16(count
+ 5);
2427 iov
[0].iov_base
= pSMB
;
2429 iov
[0].iov_len
= smb_hdr_len
+ 4;
2430 else /* wct == 12 pad bigger by four bytes */
2431 iov
[0].iov_len
= smb_hdr_len
+ 8;
2433 rc
= SendReceive2(xid
, tcon
->ses
, iov
, n_vec
+ 1, &resp_buf_type
, 0,
2435 cifs_small_buf_release(pSMB
);
2436 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2438 cifs_dbg(FYI
, "Send error Write2 = %d\n", rc
);
2439 } else if (resp_buf_type
== 0) {
2440 /* presumably this can not happen, but best to be safe */
2443 WRITE_RSP
*pSMBr
= (WRITE_RSP
*)rsp_iov
.iov_base
;
2444 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2445 *nbytes
= (*nbytes
) << 16;
2446 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2449 * Mask off high 16 bits when bytes written as returned by the
2450 * server is greater than bytes requested by the client. OS/2
2451 * servers are known to set incorrect CountHigh values.
2453 if (*nbytes
> count
)
2457 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2459 /* Note: On -EAGAIN error only caller can retry on handle based calls
2460 since file handle passed in no longer valid */
2465 int cifs_lockv(const unsigned int xid
, struct cifs_tcon
*tcon
,
2466 const __u16 netfid
, const __u8 lock_type
, const __u32 num_unlock
,
2467 const __u32 num_lock
, LOCKING_ANDX_RANGE
*buf
)
2470 LOCK_REQ
*pSMB
= NULL
;
2472 struct kvec rsp_iov
;
2476 cifs_dbg(FYI
, "cifs_lockv num lock %d num unlock %d\n",
2477 num_lock
, num_unlock
);
2479 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2484 pSMB
->NumberOfLocks
= cpu_to_le16(num_lock
);
2485 pSMB
->NumberOfUnlocks
= cpu_to_le16(num_unlock
);
2486 pSMB
->LockType
= lock_type
;
2487 pSMB
->AndXCommand
= 0xFF; /* none */
2488 pSMB
->Fid
= netfid
; /* netfid stays le */
2490 count
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2491 inc_rfc1001_len(pSMB
, count
);
2492 pSMB
->ByteCount
= cpu_to_le16(count
);
2494 iov
[0].iov_base
= (char *)pSMB
;
2495 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4 -
2496 (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2497 iov
[1].iov_base
= (char *)buf
;
2498 iov
[1].iov_len
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2500 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2501 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 2, &resp_buf_type
,
2502 CIFS_NO_RSP_BUF
, &rsp_iov
);
2503 cifs_small_buf_release(pSMB
);
2505 cifs_dbg(FYI
, "Send error in cifs_lockv = %d\n", rc
);
2511 CIFSSMBLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2512 const __u16 smb_file_id
, const __u32 netpid
, const __u64 len
,
2513 const __u64 offset
, const __u32 numUnlock
,
2514 const __u32 numLock
, const __u8 lockType
,
2515 const bool waitFlag
, const __u8 oplock_level
)
2518 LOCK_REQ
*pSMB
= NULL
;
2519 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2524 cifs_dbg(FYI
, "CIFSSMBLock timeout %d numLock %d\n",
2525 (int)waitFlag
, numLock
);
2526 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2531 if (lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
2532 /* no response expected */
2533 flags
= CIFS_NO_SRV_RSP
| CIFS_NON_BLOCKING
| CIFS_OBREAK_OP
;
2535 } else if (waitFlag
) {
2536 flags
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2537 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
2542 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
2543 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
2544 pSMB
->LockType
= lockType
;
2545 pSMB
->OplockLevel
= oplock_level
;
2546 pSMB
->AndXCommand
= 0xFF; /* none */
2547 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
2549 if ((numLock
!= 0) || (numUnlock
!= 0)) {
2550 pSMB
->Locks
[0].Pid
= cpu_to_le16(netpid
);
2551 /* BB where to store pid high? */
2552 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
2553 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
2554 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
2555 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
2556 count
= sizeof(LOCKING_ANDX_RANGE
);
2561 inc_rfc1001_len(pSMB
, count
);
2562 pSMB
->ByteCount
= cpu_to_le16(count
);
2565 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2566 (struct smb_hdr
*) pSMB
, &bytes_returned
);
2568 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)pSMB
, flags
);
2569 cifs_small_buf_release(pSMB
);
2570 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2572 cifs_dbg(FYI
, "Send error in Lock = %d\n", rc
);
2574 /* Note: On -EAGAIN error only caller can retry on handle based calls
2575 since file handle passed in no longer valid */
2580 CIFSSMBPosixLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2581 const __u16 smb_file_id
, const __u32 netpid
,
2582 const loff_t start_offset
, const __u64 len
,
2583 struct file_lock
*pLockData
, const __u16 lock_type
,
2584 const bool waitFlag
)
2586 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2587 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2588 struct cifs_posix_lock
*parm_data
;
2591 int bytes_returned
= 0;
2592 int resp_buf_type
= 0;
2593 __u16 params
, param_offset
, offset
, byte_count
, count
;
2595 struct kvec rsp_iov
;
2597 cifs_dbg(FYI
, "Posix Lock\n");
2599 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
2604 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)pSMB
;
2607 pSMB
->MaxSetupCount
= 0;
2610 pSMB
->Reserved2
= 0;
2611 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2612 offset
= param_offset
+ params
;
2614 count
= sizeof(struct cifs_posix_lock
);
2615 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2616 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2617 pSMB
->SetupCount
= 1;
2618 pSMB
->Reserved3
= 0;
2620 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
2622 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2623 byte_count
= 3 /* pad */ + params
+ count
;
2624 pSMB
->DataCount
= cpu_to_le16(count
);
2625 pSMB
->ParameterCount
= cpu_to_le16(params
);
2626 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2627 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2628 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2629 parm_data
= (struct cifs_posix_lock
*)
2630 (((char *) &pSMB
->hdr
.Protocol
) + offset
);
2632 parm_data
->lock_type
= cpu_to_le16(lock_type
);
2634 timeout
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2635 parm_data
->lock_flags
= cpu_to_le16(1);
2636 pSMB
->Timeout
= cpu_to_le32(-1);
2640 parm_data
->pid
= cpu_to_le32(netpid
);
2641 parm_data
->start
= cpu_to_le64(start_offset
);
2642 parm_data
->length
= cpu_to_le64(len
); /* normalize negative numbers */
2644 pSMB
->DataOffset
= cpu_to_le16(offset
);
2645 pSMB
->Fid
= smb_file_id
;
2646 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_LOCK
);
2647 pSMB
->Reserved4
= 0;
2648 inc_rfc1001_len(pSMB
, byte_count
);
2649 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2651 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2652 (struct smb_hdr
*) pSMBr
, &bytes_returned
);
2654 iov
[0].iov_base
= (char *)pSMB
;
2655 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
2656 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
2657 &resp_buf_type
, timeout
, &rsp_iov
);
2658 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)rsp_iov
.iov_base
;
2660 cifs_small_buf_release(pSMB
);
2663 cifs_dbg(FYI
, "Send error in Posix Lock = %d\n", rc
);
2664 } else if (pLockData
) {
2665 /* lock structure can be returned on get */
2668 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2670 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(*parm_data
)) {
2671 rc
= -EIO
; /* bad smb */
2674 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
2675 data_count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2676 if (data_count
< sizeof(struct cifs_posix_lock
)) {
2680 parm_data
= (struct cifs_posix_lock
*)
2681 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2682 if (parm_data
->lock_type
== cpu_to_le16(CIFS_UNLCK
))
2683 pLockData
->fl_type
= F_UNLCK
;
2685 if (parm_data
->lock_type
==
2686 cpu_to_le16(CIFS_RDLCK
))
2687 pLockData
->fl_type
= F_RDLCK
;
2688 else if (parm_data
->lock_type
==
2689 cpu_to_le16(CIFS_WRLCK
))
2690 pLockData
->fl_type
= F_WRLCK
;
2692 pLockData
->fl_start
= le64_to_cpu(parm_data
->start
);
2693 pLockData
->fl_end
= pLockData
->fl_start
+
2694 le64_to_cpu(parm_data
->length
) - 1;
2695 pLockData
->fl_pid
= -le32_to_cpu(parm_data
->pid
);
2700 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2702 /* Note: On -EAGAIN error only caller can retry on handle based calls
2703 since file handle passed in no longer valid */
2710 CIFSSMBClose(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2713 CLOSE_REQ
*pSMB
= NULL
;
2714 cifs_dbg(FYI
, "In CIFSSMBClose\n");
2716 /* do not retry on dead session on close */
2717 rc
= small_smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
);
2723 pSMB
->FileID
= (__u16
) smb_file_id
;
2724 pSMB
->LastWriteTime
= 0xFFFFFFFF;
2725 pSMB
->ByteCount
= 0;
2726 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2727 cifs_small_buf_release(pSMB
);
2728 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_closes
);
2731 /* EINTR is expected when user ctl-c to kill app */
2732 cifs_dbg(VFS
, "Send error in Close = %d\n", rc
);
2736 /* Since session is dead, file will be closed on server already */
2744 CIFSSMBFlush(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2747 FLUSH_REQ
*pSMB
= NULL
;
2748 cifs_dbg(FYI
, "In CIFSSMBFlush\n");
2750 rc
= small_smb_init(SMB_COM_FLUSH
, 1, tcon
, (void **) &pSMB
);
2754 pSMB
->FileID
= (__u16
) smb_file_id
;
2755 pSMB
->ByteCount
= 0;
2756 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2757 cifs_small_buf_release(pSMB
);
2758 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_flushes
);
2760 cifs_dbg(VFS
, "Send error in Flush = %d\n", rc
);
2766 CIFSSMBRename(const unsigned int xid
, struct cifs_tcon
*tcon
,
2767 const char *from_name
, const char *to_name
,
2768 struct cifs_sb_info
*cifs_sb
)
2771 RENAME_REQ
*pSMB
= NULL
;
2772 RENAME_RSP
*pSMBr
= NULL
;
2774 int name_len
, name_len2
;
2776 int remap
= cifs_remap(cifs_sb
);
2778 cifs_dbg(FYI
, "In CIFSSMBRename\n");
2780 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
2785 pSMB
->BufferFormat
= 0x04;
2786 pSMB
->SearchAttributes
=
2787 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2790 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2791 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2792 from_name
, PATH_MAX
,
2793 cifs_sb
->local_nls
, remap
);
2794 name_len
++; /* trailing null */
2796 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2797 /* protocol requires ASCII signature byte on Unicode string */
2798 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2800 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2801 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2803 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2804 name_len2
*= 2; /* convert to bytes */
2806 name_len
= copy_path_name(pSMB
->OldFileName
, from_name
);
2807 name_len2
= copy_path_name(pSMB
->OldFileName
+name_len
+1, to_name
);
2808 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2809 name_len2
++; /* signature byte */
2812 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2813 inc_rfc1001_len(pSMB
, count
);
2814 pSMB
->ByteCount
= cpu_to_le16(count
);
2816 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2817 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2818 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_renames
);
2820 cifs_dbg(FYI
, "Send error in rename = %d\n", rc
);
2822 cifs_buf_release(pSMB
);
2830 int CIFSSMBRenameOpenFile(const unsigned int xid
, struct cifs_tcon
*pTcon
,
2831 int netfid
, const char *target_name
,
2832 const struct nls_table
*nls_codepage
, int remap
)
2834 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2835 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2836 struct set_file_rename
*rename_info
;
2838 char dummy_string
[30];
2840 int bytes_returned
= 0;
2842 __u16 params
, param_offset
, offset
, count
, byte_count
;
2844 cifs_dbg(FYI
, "Rename to File by handle\n");
2845 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
2851 pSMB
->MaxSetupCount
= 0;
2855 pSMB
->Reserved2
= 0;
2856 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2857 offset
= param_offset
+ params
;
2859 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2860 rename_info
= (struct set_file_rename
*) data_offset
;
2861 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2862 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2863 pSMB
->SetupCount
= 1;
2864 pSMB
->Reserved3
= 0;
2865 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2866 byte_count
= 3 /* pad */ + params
;
2867 pSMB
->ParameterCount
= cpu_to_le16(params
);
2868 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2869 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2870 pSMB
->DataOffset
= cpu_to_le16(offset
);
2871 /* construct random name ".cifs_tmp<inodenum><mid>" */
2872 rename_info
->overwrite
= cpu_to_le32(1);
2873 rename_info
->root_fid
= 0;
2874 /* unicode only call */
2875 if (target_name
== NULL
) {
2876 sprintf(dummy_string
, "cifs%x", pSMB
->hdr
.Mid
);
2878 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2879 dummy_string
, 24, nls_codepage
, remap
);
2882 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2883 target_name
, PATH_MAX
, nls_codepage
,
2886 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
2887 count
= 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str
);
2888 byte_count
+= count
;
2889 pSMB
->DataCount
= cpu_to_le16(count
);
2890 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2892 pSMB
->InformationLevel
=
2893 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
2894 pSMB
->Reserved4
= 0;
2895 inc_rfc1001_len(pSMB
, byte_count
);
2896 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2897 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
2898 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2899 cifs_stats_inc(&pTcon
->stats
.cifs_stats
.num_t2renames
);
2901 cifs_dbg(FYI
, "Send error in Rename (by file handle) = %d\n",
2904 cifs_buf_release(pSMB
);
2906 /* Note: On -EAGAIN error only caller can retry on handle based calls
2907 since file handle passed in no longer valid */
2913 CIFSSMBCopy(const unsigned int xid
, struct cifs_tcon
*tcon
,
2914 const char *fromName
, const __u16 target_tid
, const char *toName
,
2915 const int flags
, const struct nls_table
*nls_codepage
, int remap
)
2918 COPY_REQ
*pSMB
= NULL
;
2919 COPY_RSP
*pSMBr
= NULL
;
2921 int name_len
, name_len2
;
2924 cifs_dbg(FYI
, "In CIFSSMBCopy\n");
2926 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
2931 pSMB
->BufferFormat
= 0x04;
2932 pSMB
->Tid2
= target_tid
;
2934 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
2936 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2937 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2938 fromName
, PATH_MAX
, nls_codepage
,
2940 name_len
++; /* trailing null */
2942 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2943 /* protocol requires ASCII signature byte on Unicode string */
2944 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2946 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2947 toName
, PATH_MAX
, nls_codepage
, remap
);
2948 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2949 name_len2
*= 2; /* convert to bytes */
2951 name_len
= copy_path_name(pSMB
->OldFileName
, fromName
);
2952 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2953 name_len2
= copy_path_name(pSMB
->OldFileName
+name_len
+1, toName
);
2954 name_len2
++; /* signature byte */
2957 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2958 inc_rfc1001_len(pSMB
, count
);
2959 pSMB
->ByteCount
= cpu_to_le16(count
);
2961 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2962 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2964 cifs_dbg(FYI
, "Send error in copy = %d with %d files copied\n",
2965 rc
, le16_to_cpu(pSMBr
->CopyCount
));
2967 cifs_buf_release(pSMB
);
2976 CIFSUnixCreateSymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2977 const char *fromName
, const char *toName
,
2978 const struct nls_table
*nls_codepage
, int remap
)
2980 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2981 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2984 int name_len_target
;
2986 int bytes_returned
= 0;
2987 __u16 params
, param_offset
, offset
, byte_count
;
2989 cifs_dbg(FYI
, "In Symlink Unix style\n");
2991 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2996 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2998 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fromName
,
2999 /* find define for this maxpathcomponent */
3000 PATH_MAX
, nls_codepage
, remap
);
3001 name_len
++; /* trailing null */
3005 name_len
= copy_path_name(pSMB
->FileName
, fromName
);
3007 params
= 6 + name_len
;
3008 pSMB
->MaxSetupCount
= 0;
3012 pSMB
->Reserved2
= 0;
3013 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3014 InformationLevel
) - 4;
3015 offset
= param_offset
+ params
;
3017 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
3018 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3020 cifsConvertToUTF16((__le16
*) data_offset
, toName
,
3021 /* find define for this maxpathcomponent */
3022 PATH_MAX
, nls_codepage
, remap
);
3023 name_len_target
++; /* trailing null */
3024 name_len_target
*= 2;
3026 name_len_target
= copy_path_name(data_offset
, toName
);
3029 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3030 /* BB find exact max on data count below from sess */
3031 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3032 pSMB
->SetupCount
= 1;
3033 pSMB
->Reserved3
= 0;
3034 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3035 byte_count
= 3 /* pad */ + params
+ name_len_target
;
3036 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
3037 pSMB
->ParameterCount
= cpu_to_le16(params
);
3038 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3039 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3040 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3041 pSMB
->DataOffset
= cpu_to_le16(offset
);
3042 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
3043 pSMB
->Reserved4
= 0;
3044 inc_rfc1001_len(pSMB
, byte_count
);
3045 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3046 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3047 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3048 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_symlinks
);
3050 cifs_dbg(FYI
, "Send error in SetPathInfo create symlink = %d\n",
3053 cifs_buf_release(pSMB
);
3056 goto createSymLinkRetry
;
3062 CIFSUnixCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3063 const char *fromName
, const char *toName
,
3064 const struct nls_table
*nls_codepage
, int remap
)
3066 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
3067 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
3070 int name_len_target
;
3072 int bytes_returned
= 0;
3073 __u16 params
, param_offset
, offset
, byte_count
;
3075 cifs_dbg(FYI
, "In Create Hard link Unix style\n");
3076 createHardLinkRetry
:
3077 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3082 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3083 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->FileName
, toName
,
3084 PATH_MAX
, nls_codepage
, remap
);
3085 name_len
++; /* trailing null */
3089 name_len
= copy_path_name(pSMB
->FileName
, toName
);
3091 params
= 6 + name_len
;
3092 pSMB
->MaxSetupCount
= 0;
3096 pSMB
->Reserved2
= 0;
3097 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3098 InformationLevel
) - 4;
3099 offset
= param_offset
+ params
;
3101 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
3102 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3104 cifsConvertToUTF16((__le16
*) data_offset
, fromName
,
3105 PATH_MAX
, nls_codepage
, remap
);
3106 name_len_target
++; /* trailing null */
3107 name_len_target
*= 2;
3109 name_len_target
= copy_path_name(data_offset
, fromName
);
3112 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3113 /* BB find exact max on data count below from sess*/
3114 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3115 pSMB
->SetupCount
= 1;
3116 pSMB
->Reserved3
= 0;
3117 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3118 byte_count
= 3 /* pad */ + params
+ name_len_target
;
3119 pSMB
->ParameterCount
= cpu_to_le16(params
);
3120 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3121 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
3122 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3123 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3124 pSMB
->DataOffset
= cpu_to_le16(offset
);
3125 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
3126 pSMB
->Reserved4
= 0;
3127 inc_rfc1001_len(pSMB
, byte_count
);
3128 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3129 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3130 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3131 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3133 cifs_dbg(FYI
, "Send error in SetPathInfo (hard link) = %d\n",
3136 cifs_buf_release(pSMB
);
3138 goto createHardLinkRetry
;
3144 CIFSCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3145 const char *from_name
, const char *to_name
,
3146 struct cifs_sb_info
*cifs_sb
)
3149 NT_RENAME_REQ
*pSMB
= NULL
;
3150 RENAME_RSP
*pSMBr
= NULL
;
3152 int name_len
, name_len2
;
3154 int remap
= cifs_remap(cifs_sb
);
3156 cifs_dbg(FYI
, "In CIFSCreateHardLink\n");
3157 winCreateHardLinkRetry
:
3159 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
3164 pSMB
->SearchAttributes
=
3165 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
3167 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
3168 pSMB
->ClusterCount
= 0;
3170 pSMB
->BufferFormat
= 0x04;
3172 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3174 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, from_name
,
3175 PATH_MAX
, cifs_sb
->local_nls
, remap
);
3176 name_len
++; /* trailing null */
3179 /* protocol specifies ASCII buffer format (0x04) for unicode */
3180 pSMB
->OldFileName
[name_len
] = 0x04;
3181 pSMB
->OldFileName
[name_len
+ 1] = 0x00; /* pad */
3183 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
3184 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
3186 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
3187 name_len2
*= 2; /* convert to bytes */
3189 name_len
= copy_path_name(pSMB
->OldFileName
, from_name
);
3190 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
3191 name_len2
= copy_path_name(pSMB
->OldFileName
+name_len
+1, to_name
);
3192 name_len2
++; /* signature byte */
3195 count
= 1 /* string type byte */ + name_len
+ name_len2
;
3196 inc_rfc1001_len(pSMB
, count
);
3197 pSMB
->ByteCount
= cpu_to_le16(count
);
3199 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3200 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3201 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3203 cifs_dbg(FYI
, "Send error in hard link (NT rename) = %d\n", rc
);
3205 cifs_buf_release(pSMB
);
3207 goto winCreateHardLinkRetry
;
3213 CIFSSMBUnixQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3214 const unsigned char *searchName
, char **symlinkinfo
,
3215 const struct nls_table
*nls_codepage
, int remap
)
3217 /* SMB_QUERY_FILE_UNIX_LINK */
3218 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3219 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3223 __u16 params
, byte_count
;
3226 cifs_dbg(FYI
, "In QPathSymLinkInfo (Unix) for path %s\n", searchName
);
3229 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3234 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3236 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3237 searchName
, PATH_MAX
, nls_codepage
,
3239 name_len
++; /* trailing null */
3242 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
3245 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3246 pSMB
->TotalDataCount
= 0;
3247 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3248 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3249 pSMB
->MaxSetupCount
= 0;
3253 pSMB
->Reserved2
= 0;
3254 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3255 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3256 pSMB
->DataCount
= 0;
3257 pSMB
->DataOffset
= 0;
3258 pSMB
->SetupCount
= 1;
3259 pSMB
->Reserved3
= 0;
3260 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3261 byte_count
= params
+ 1 /* pad */ ;
3262 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3263 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3264 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
3265 pSMB
->Reserved4
= 0;
3266 inc_rfc1001_len(pSMB
, byte_count
);
3267 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3269 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3270 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3272 cifs_dbg(FYI
, "Send error in QuerySymLinkInfo = %d\n", rc
);
3274 /* decode response */
3276 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3277 /* BB also check enough total bytes returned */
3278 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3282 u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3284 data_start
= ((char *) &pSMBr
->hdr
.Protocol
) +
3285 le16_to_cpu(pSMBr
->t2
.DataOffset
);
3287 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3292 /* BB FIXME investigate remapping reserved chars here */
3293 *symlinkinfo
= cifs_strndup_from_utf16(data_start
,
3294 count
, is_unicode
, nls_codepage
);
3299 cifs_buf_release(pSMB
);
3301 goto querySymLinkRetry
;
3306 * Recent Windows versions now create symlinks more frequently
3307 * and they use the "reparse point" mechanism below. We can of course
3308 * do symlinks nicely to Samba and other servers which support the
3309 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3310 * "MF" symlinks optionally, but for recent Windows we really need to
3311 * reenable the code below and fix the cifs_symlink callers to handle this.
3312 * In the interim this code has been moved to its own config option so
3313 * it is not compiled in by default until callers fixed up and more tested.
3316 CIFSSMBQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3317 __u16 fid
, char **symlinkinfo
,
3318 const struct nls_table
*nls_codepage
)
3322 struct smb_com_transaction_ioctl_req
*pSMB
;
3323 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3325 unsigned int sub_len
;
3327 struct reparse_symlink_data
*reparse_buf
;
3328 struct reparse_posix_data
*posix_buf
;
3329 __u32 data_offset
, data_count
;
3332 cifs_dbg(FYI
, "In Windows reparse style QueryLink for fid %u\n", fid
);
3333 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3338 pSMB
->TotalParameterCount
= 0 ;
3339 pSMB
->TotalDataCount
= 0;
3340 pSMB
->MaxParameterCount
= cpu_to_le32(2);
3341 /* BB find exact data count max from sess structure BB */
3342 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3343 pSMB
->MaxSetupCount
= 4;
3345 pSMB
->ParameterOffset
= 0;
3346 pSMB
->DataCount
= 0;
3347 pSMB
->DataOffset
= 0;
3348 pSMB
->SetupCount
= 4;
3349 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3350 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3351 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
3352 pSMB
->IsFsctl
= 1; /* FSCTL */
3353 pSMB
->IsRootFlag
= 0;
3354 pSMB
->Fid
= fid
; /* file handle always le */
3355 pSMB
->ByteCount
= 0;
3357 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3358 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3360 cifs_dbg(FYI
, "Send error in QueryReparseLinkInfo = %d\n", rc
);
3364 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3365 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3366 if (get_bcc(&pSMBr
->hdr
) < 2 || data_offset
> 512) {
3367 /* BB also check enough total bytes returned */
3368 rc
= -EIO
; /* bad smb */
3371 if (!data_count
|| (data_count
> 2048)) {
3373 cifs_dbg(FYI
, "Invalid return data count on get reparse info ioctl\n");
3376 end_of_smb
= 2 + get_bcc(&pSMBr
->hdr
) + (char *)&pSMBr
->ByteCount
;
3377 reparse_buf
= (struct reparse_symlink_data
*)
3378 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
3379 if ((char *)reparse_buf
>= end_of_smb
) {
3383 if (reparse_buf
->ReparseTag
== cpu_to_le32(IO_REPARSE_TAG_NFS
)) {
3384 cifs_dbg(FYI
, "NFS style reparse tag\n");
3385 posix_buf
= (struct reparse_posix_data
*)reparse_buf
;
3387 if (posix_buf
->InodeType
!= cpu_to_le64(NFS_SPECFILE_LNK
)) {
3388 cifs_dbg(FYI
, "unsupported file type 0x%llx\n",
3389 le64_to_cpu(posix_buf
->InodeType
));
3394 sub_len
= le16_to_cpu(reparse_buf
->ReparseDataLength
);
3395 if (posix_buf
->PathBuffer
+ sub_len
> end_of_smb
) {
3396 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3400 *symlinkinfo
= cifs_strndup_from_utf16(posix_buf
->PathBuffer
,
3401 sub_len
, is_unicode
, nls_codepage
);
3403 } else if (reparse_buf
->ReparseTag
!=
3404 cpu_to_le32(IO_REPARSE_TAG_SYMLINK
)) {
3409 /* Reparse tag is NTFS symlink */
3410 sub_start
= le16_to_cpu(reparse_buf
->SubstituteNameOffset
) +
3411 reparse_buf
->PathBuffer
;
3412 sub_len
= le16_to_cpu(reparse_buf
->SubstituteNameLength
);
3413 if (sub_start
+ sub_len
> end_of_smb
) {
3414 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3418 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3423 /* BB FIXME investigate remapping reserved chars here */
3424 *symlinkinfo
= cifs_strndup_from_utf16(sub_start
, sub_len
, is_unicode
,
3429 cifs_buf_release(pSMB
);
3432 * Note: On -EAGAIN error only caller can retry on handle based calls
3433 * since file handle passed in no longer valid.
3439 CIFSSMB_set_compression(const unsigned int xid
, struct cifs_tcon
*tcon
,
3444 struct smb_com_transaction_compr_ioctl_req
*pSMB
;
3445 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3447 cifs_dbg(FYI
, "Set compression for %u\n", fid
);
3448 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3453 pSMB
->compression_state
= cpu_to_le16(COMPRESSION_FORMAT_DEFAULT
);
3455 pSMB
->TotalParameterCount
= 0;
3456 pSMB
->TotalDataCount
= cpu_to_le32(2);
3457 pSMB
->MaxParameterCount
= 0;
3458 pSMB
->MaxDataCount
= 0;
3459 pSMB
->MaxSetupCount
= 4;
3461 pSMB
->ParameterOffset
= 0;
3462 pSMB
->DataCount
= cpu_to_le32(2);
3464 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req
,
3465 compression_state
) - 4); /* 84 */
3466 pSMB
->SetupCount
= 4;
3467 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3468 pSMB
->ParameterCount
= 0;
3469 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_SET_COMPRESSION
);
3470 pSMB
->IsFsctl
= 1; /* FSCTL */
3471 pSMB
->IsRootFlag
= 0;
3472 pSMB
->Fid
= fid
; /* file handle always le */
3473 /* 3 byte pad, followed by 2 byte compress state */
3474 pSMB
->ByteCount
= cpu_to_le16(5);
3475 inc_rfc1001_len(pSMB
, 5);
3477 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3478 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3480 cifs_dbg(FYI
, "Send error in SetCompression = %d\n", rc
);
3482 cifs_buf_release(pSMB
);
3485 * Note: On -EAGAIN error only caller can retry on handle based calls
3486 * since file handle passed in no longer valid.
3492 #ifdef CONFIG_CIFS_POSIX
3494 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3495 static void cifs_convert_ace(struct posix_acl_xattr_entry
*ace
,
3496 struct cifs_posix_ace
*cifs_ace
)
3498 /* u8 cifs fields do not need le conversion */
3499 ace
->e_perm
= cpu_to_le16(cifs_ace
->cifs_e_perm
);
3500 ace
->e_tag
= cpu_to_le16(cifs_ace
->cifs_e_tag
);
3501 ace
->e_id
= cpu_to_le32(le64_to_cpu(cifs_ace
->cifs_uid
));
3503 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3504 ace->e_perm, ace->e_tag, ace->e_id);
3510 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3511 static int cifs_copy_posix_acl(char *trgt
, char *src
, const int buflen
,
3512 const int acl_type
, const int size_of_data_area
)
3517 struct cifs_posix_ace
*pACE
;
3518 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)src
;
3519 struct posix_acl_xattr_header
*local_acl
= (void *)trgt
;
3521 if (le16_to_cpu(cifs_acl
->version
) != CIFS_ACL_VERSION
)
3524 if (acl_type
== ACL_TYPE_ACCESS
) {
3525 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3526 pACE
= &cifs_acl
->ace_array
[0];
3527 size
= sizeof(struct cifs_posix_acl
);
3528 size
+= sizeof(struct cifs_posix_ace
) * count
;
3529 /* check if we would go beyond end of SMB */
3530 if (size_of_data_area
< size
) {
3531 cifs_dbg(FYI
, "bad CIFS POSIX ACL size %d vs. %d\n",
3532 size_of_data_area
, size
);
3535 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3536 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3537 size
= sizeof(struct cifs_posix_acl
);
3538 size
+= sizeof(struct cifs_posix_ace
) * count
;
3539 /* skip past access ACEs to get to default ACEs */
3540 pACE
= &cifs_acl
->ace_array
[count
];
3541 count
= le16_to_cpu(cifs_acl
->default_entry_count
);
3542 size
+= sizeof(struct cifs_posix_ace
) * count
;
3543 /* check if we would go beyond end of SMB */
3544 if (size_of_data_area
< size
)
3551 size
= posix_acl_xattr_size(count
);
3552 if ((buflen
== 0) || (local_acl
== NULL
)) {
3553 /* used to query ACL EA size */
3554 } else if (size
> buflen
) {
3556 } else /* buffer big enough */ {
3557 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3559 local_acl
->a_version
= cpu_to_le32(POSIX_ACL_XATTR_VERSION
);
3560 for (i
= 0; i
< count
; i
++) {
3561 cifs_convert_ace(&ace
[i
], pACE
);
3568 static void convert_ace_to_cifs_ace(struct cifs_posix_ace
*cifs_ace
,
3569 const struct posix_acl_xattr_entry
*local_ace
)
3571 cifs_ace
->cifs_e_perm
= le16_to_cpu(local_ace
->e_perm
);
3572 cifs_ace
->cifs_e_tag
= le16_to_cpu(local_ace
->e_tag
);
3573 /* BB is there a better way to handle the large uid? */
3574 if (local_ace
->e_id
== cpu_to_le32(-1)) {
3575 /* Probably no need to le convert -1 on any arch but can not hurt */
3576 cifs_ace
->cifs_uid
= cpu_to_le64(-1);
3578 cifs_ace
->cifs_uid
= cpu_to_le64(le32_to_cpu(local_ace
->e_id
));
3580 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3581 ace->e_perm, ace->e_tag, ace->e_id);
3585 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3586 static __u16
ACL_to_cifs_posix(char *parm_data
, const char *pACL
,
3587 const int buflen
, const int acl_type
)
3590 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)parm_data
;
3591 struct posix_acl_xattr_header
*local_acl
= (void *)pACL
;
3592 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3596 if ((buflen
== 0) || (pACL
== NULL
) || (cifs_acl
== NULL
))
3599 count
= posix_acl_xattr_count((size_t)buflen
);
3600 cifs_dbg(FYI
, "setting acl with %d entries from buf of length %d and version of %d\n",
3601 count
, buflen
, le32_to_cpu(local_acl
->a_version
));
3602 if (le32_to_cpu(local_acl
->a_version
) != 2) {
3603 cifs_dbg(FYI
, "unknown POSIX ACL version %d\n",
3604 le32_to_cpu(local_acl
->a_version
));
3607 cifs_acl
->version
= cpu_to_le16(1);
3608 if (acl_type
== ACL_TYPE_ACCESS
) {
3609 cifs_acl
->access_entry_count
= cpu_to_le16(count
);
3610 cifs_acl
->default_entry_count
= cpu_to_le16(0xFFFF);
3611 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3612 cifs_acl
->default_entry_count
= cpu_to_le16(count
);
3613 cifs_acl
->access_entry_count
= cpu_to_le16(0xFFFF);
3615 cifs_dbg(FYI
, "unknown ACL type %d\n", acl_type
);
3618 for (i
= 0; i
< count
; i
++)
3619 convert_ace_to_cifs_ace(&cifs_acl
->ace_array
[i
], &ace
[i
]);
3621 rc
= (__u16
)(count
* sizeof(struct cifs_posix_ace
));
3622 rc
+= sizeof(struct cifs_posix_acl
);
3623 /* BB add check to make sure ACL does not overflow SMB */
3629 CIFSSMBGetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3630 const unsigned char *searchName
,
3631 char *acl_inf
, const int buflen
, const int acl_type
,
3632 const struct nls_table
*nls_codepage
, int remap
)
3634 /* SMB_QUERY_POSIX_ACL */
3635 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3636 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3640 __u16 params
, byte_count
;
3642 cifs_dbg(FYI
, "In GetPosixACL (Unix) for path %s\n", searchName
);
3645 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3650 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3652 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3653 searchName
, PATH_MAX
, nls_codepage
,
3655 name_len
++; /* trailing null */
3657 pSMB
->FileName
[name_len
] = 0;
3658 pSMB
->FileName
[name_len
+1] = 0;
3660 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
3663 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3664 pSMB
->TotalDataCount
= 0;
3665 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3666 /* BB find exact max data count below from sess structure BB */
3667 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3668 pSMB
->MaxSetupCount
= 0;
3672 pSMB
->Reserved2
= 0;
3673 pSMB
->ParameterOffset
= cpu_to_le16(
3674 offsetof(struct smb_com_transaction2_qpi_req
,
3675 InformationLevel
) - 4);
3676 pSMB
->DataCount
= 0;
3677 pSMB
->DataOffset
= 0;
3678 pSMB
->SetupCount
= 1;
3679 pSMB
->Reserved3
= 0;
3680 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3681 byte_count
= params
+ 1 /* pad */ ;
3682 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3683 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3684 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_ACL
);
3685 pSMB
->Reserved4
= 0;
3686 inc_rfc1001_len(pSMB
, byte_count
);
3687 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3689 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3690 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3691 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3693 cifs_dbg(FYI
, "Send error in Query POSIX ACL = %d\n", rc
);
3695 /* decode response */
3697 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3698 /* BB also check enough total bytes returned */
3699 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3700 rc
= -EIO
; /* bad smb */
3702 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3703 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3704 rc
= cifs_copy_posix_acl(acl_inf
,
3705 (char *)&pSMBr
->hdr
.Protocol
+data_offset
,
3706 buflen
, acl_type
, count
);
3709 cifs_buf_release(pSMB
);
3716 CIFSSMBSetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3717 const unsigned char *fileName
,
3718 const char *local_acl
, const int buflen
,
3720 const struct nls_table
*nls_codepage
, int remap
)
3722 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3723 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3727 int bytes_returned
= 0;
3728 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
3730 cifs_dbg(FYI
, "In SetPosixACL (Unix) for path %s\n", fileName
);
3732 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3736 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3738 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
3739 PATH_MAX
, nls_codepage
, remap
);
3740 name_len
++; /* trailing null */
3743 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
3745 params
= 6 + name_len
;
3746 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3747 /* BB find max SMB size from sess */
3748 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3749 pSMB
->MaxSetupCount
= 0;
3753 pSMB
->Reserved2
= 0;
3754 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3755 InformationLevel
) - 4;
3756 offset
= param_offset
+ params
;
3757 parm_data
= ((char *) &pSMB
->hdr
.Protocol
) + offset
;
3758 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3760 /* convert to on the wire format for POSIX ACL */
3761 data_count
= ACL_to_cifs_posix(parm_data
, local_acl
, buflen
, acl_type
);
3763 if (data_count
== 0) {
3765 goto setACLerrorExit
;
3767 pSMB
->DataOffset
= cpu_to_le16(offset
);
3768 pSMB
->SetupCount
= 1;
3769 pSMB
->Reserved3
= 0;
3770 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3771 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_ACL
);
3772 byte_count
= 3 /* pad */ + params
+ data_count
;
3773 pSMB
->DataCount
= cpu_to_le16(data_count
);
3774 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3775 pSMB
->ParameterCount
= cpu_to_le16(params
);
3776 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3777 pSMB
->Reserved4
= 0;
3778 inc_rfc1001_len(pSMB
, byte_count
);
3779 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3780 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3781 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3783 cifs_dbg(FYI
, "Set POSIX ACL returned %d\n", rc
);
3786 cifs_buf_release(pSMB
);
3792 /* BB fix tabs in this function FIXME BB */
3794 CIFSGetExtAttr(const unsigned int xid
, struct cifs_tcon
*tcon
,
3795 const int netfid
, __u64
*pExtAttrBits
, __u64
*pMask
)
3798 struct smb_t2_qfi_req
*pSMB
= NULL
;
3799 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3801 __u16 params
, byte_count
;
3803 cifs_dbg(FYI
, "In GetExtAttr\n");
3808 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3813 params
= 2 /* level */ + 2 /* fid */;
3814 pSMB
->t2
.TotalDataCount
= 0;
3815 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3816 /* BB find exact max data count below from sess structure BB */
3817 pSMB
->t2
.MaxDataCount
= cpu_to_le16(4000);
3818 pSMB
->t2
.MaxSetupCount
= 0;
3819 pSMB
->t2
.Reserved
= 0;
3821 pSMB
->t2
.Timeout
= 0;
3822 pSMB
->t2
.Reserved2
= 0;
3823 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3825 pSMB
->t2
.DataCount
= 0;
3826 pSMB
->t2
.DataOffset
= 0;
3827 pSMB
->t2
.SetupCount
= 1;
3828 pSMB
->t2
.Reserved3
= 0;
3829 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3830 byte_count
= params
+ 1 /* pad */ ;
3831 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3832 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3833 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_ATTR_FLAGS
);
3836 inc_rfc1001_len(pSMB
, byte_count
);
3837 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3839 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3840 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3842 cifs_dbg(FYI
, "error %d in GetExtAttr\n", rc
);
3844 /* decode response */
3845 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3846 /* BB also check enough total bytes returned */
3847 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3848 /* If rc should we check for EOPNOSUPP and
3849 disable the srvino flag? or in caller? */
3850 rc
= -EIO
; /* bad smb */
3852 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3853 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3854 struct file_chattr_info
*pfinfo
;
3855 /* BB Do we need a cast or hash here ? */
3857 cifs_dbg(FYI
, "Illegal size ret in GetExtAttr\n");
3861 pfinfo
= (struct file_chattr_info
*)
3862 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
3863 *pExtAttrBits
= le64_to_cpu(pfinfo
->mode
);
3864 *pMask
= le64_to_cpu(pfinfo
->mask
);
3868 cifs_buf_release(pSMB
);
3870 goto GetExtAttrRetry
;
3874 #endif /* CONFIG_POSIX */
3877 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3878 * all NT TRANSACTS that we init here have total parm and data under about 400
3879 * bytes (to fit in small cifs buffer size), which is the case so far, it
3880 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3881 * returned setup area) and MaxParameterCount (returned parms size) must be set
3885 smb_init_nttransact(const __u16 sub_command
, const int setup_count
,
3886 const int parm_len
, struct cifs_tcon
*tcon
,
3891 struct smb_com_ntransact_req
*pSMB
;
3893 rc
= small_smb_init(SMB_COM_NT_TRANSACT
, 19 + setup_count
, tcon
,
3897 *ret_buf
= (void *)pSMB
;
3899 pSMB
->TotalParameterCount
= cpu_to_le32(parm_len
);
3900 pSMB
->TotalDataCount
= 0;
3901 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3902 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3903 pSMB
->DataCount
= pSMB
->TotalDataCount
;
3904 temp_offset
= offsetof(struct smb_com_ntransact_req
, Parms
) +
3905 (setup_count
* 2) - 4 /* for rfc1001 length itself */;
3906 pSMB
->ParameterOffset
= cpu_to_le32(temp_offset
);
3907 pSMB
->DataOffset
= cpu_to_le32(temp_offset
+ parm_len
);
3908 pSMB
->SetupCount
= setup_count
; /* no need to le convert byte fields */
3909 pSMB
->SubCommand
= cpu_to_le16(sub_command
);
3914 validate_ntransact(char *buf
, char **ppparm
, char **ppdata
,
3915 __u32
*pparmlen
, __u32
*pdatalen
)
3918 __u32 data_count
, data_offset
, parm_count
, parm_offset
;
3919 struct smb_com_ntransact_rsp
*pSMBr
;
3928 pSMBr
= (struct smb_com_ntransact_rsp
*)buf
;
3930 bcc
= get_bcc(&pSMBr
->hdr
);
3931 end_of_smb
= 2 /* sizeof byte count */ + bcc
+
3932 (char *)&pSMBr
->ByteCount
;
3934 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3935 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3936 parm_offset
= le32_to_cpu(pSMBr
->ParameterOffset
);
3937 parm_count
= le32_to_cpu(pSMBr
->ParameterCount
);
3939 *ppparm
= (char *)&pSMBr
->hdr
.Protocol
+ parm_offset
;
3940 *ppdata
= (char *)&pSMBr
->hdr
.Protocol
+ data_offset
;
3942 /* should we also check that parm and data areas do not overlap? */
3943 if (*ppparm
> end_of_smb
) {
3944 cifs_dbg(FYI
, "parms start after end of smb\n");
3946 } else if (parm_count
+ *ppparm
> end_of_smb
) {
3947 cifs_dbg(FYI
, "parm end after end of smb\n");
3949 } else if (*ppdata
> end_of_smb
) {
3950 cifs_dbg(FYI
, "data starts after end of smb\n");
3952 } else if (data_count
+ *ppdata
> end_of_smb
) {
3953 cifs_dbg(FYI
, "data %p + count %d (%p) past smb end %p start %p\n",
3954 *ppdata
, data_count
, (data_count
+ *ppdata
),
3957 } else if (parm_count
+ data_count
> bcc
) {
3958 cifs_dbg(FYI
, "parm count and data count larger than SMB\n");
3961 *pdatalen
= data_count
;
3962 *pparmlen
= parm_count
;
3966 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3968 CIFSSMBGetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3969 struct cifs_ntsd
**acl_inf
, __u32
*pbuflen
)
3973 QUERY_SEC_DESC_REQ
*pSMB
;
3975 struct kvec rsp_iov
;
3977 cifs_dbg(FYI
, "GetCifsACL\n");
3982 rc
= smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC
, 0,
3983 8 /* parm len */, tcon
, (void **) &pSMB
);
3987 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3988 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3989 pSMB
->MaxSetupCount
= 0;
3990 pSMB
->Fid
= fid
; /* file handle always le */
3991 pSMB
->AclFlags
= cpu_to_le32(CIFS_ACL_OWNER
| CIFS_ACL_GROUP
|
3993 pSMB
->ByteCount
= cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3994 inc_rfc1001_len(pSMB
, 11);
3995 iov
[0].iov_base
= (char *)pSMB
;
3996 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
3998 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovec */, &buf_type
,
4000 cifs_small_buf_release(pSMB
);
4001 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
4003 cifs_dbg(FYI
, "Send error in QuerySecDesc = %d\n", rc
);
4004 } else { /* decode response */
4008 struct smb_com_ntransact_rsp
*pSMBr
;
4011 /* validate_nttransact */
4012 rc
= validate_ntransact(rsp_iov
.iov_base
, (char **)&parm
,
4013 &pdata
, &parm_len
, pbuflen
);
4016 pSMBr
= (struct smb_com_ntransact_rsp
*)rsp_iov
.iov_base
;
4018 cifs_dbg(FYI
, "smb %p parm %p data %p\n",
4019 pSMBr
, parm
, *acl_inf
);
4021 if (le32_to_cpu(pSMBr
->ParameterCount
) != 4) {
4022 rc
= -EIO
; /* bad smb */
4027 /* BB check that data area is minimum length and as big as acl_len */
4029 acl_len
= le32_to_cpu(*parm
);
4030 if (acl_len
!= *pbuflen
) {
4031 cifs_dbg(VFS
, "acl length %d does not match %d\n",
4033 if (*pbuflen
> acl_len
)
4037 /* check if buffer is big enough for the acl
4038 header followed by the smallest SID */
4039 if ((*pbuflen
< sizeof(struct cifs_ntsd
) + 8) ||
4040 (*pbuflen
>= 64 * 1024)) {
4041 cifs_dbg(VFS
, "bad acl length %d\n", *pbuflen
);
4045 *acl_inf
= kmemdup(pdata
, *pbuflen
, GFP_KERNEL
);
4046 if (*acl_inf
== NULL
) {
4053 free_rsp_buf(buf_type
, rsp_iov
.iov_base
);
4058 CIFSSMBSetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
4059 struct cifs_ntsd
*pntsd
, __u32 acllen
, int aclflag
)
4061 __u16 byte_count
, param_count
, data_count
, param_offset
, data_offset
;
4063 int bytes_returned
= 0;
4064 SET_SEC_DESC_REQ
*pSMB
= NULL
;
4068 rc
= smb_init(SMB_COM_NT_TRANSACT
, 19, tcon
, (void **) &pSMB
, &pSMBr
);
4072 pSMB
->MaxSetupCount
= 0;
4076 param_offset
= offsetof(struct smb_com_transaction_ssec_req
, Fid
) - 4;
4077 data_count
= acllen
;
4078 data_offset
= param_offset
+ param_count
;
4079 byte_count
= 3 /* pad */ + param_count
;
4081 pSMB
->DataCount
= cpu_to_le32(data_count
);
4082 pSMB
->TotalDataCount
= pSMB
->DataCount
;
4083 pSMB
->MaxParameterCount
= cpu_to_le32(4);
4084 pSMB
->MaxDataCount
= cpu_to_le32(16384);
4085 pSMB
->ParameterCount
= cpu_to_le32(param_count
);
4086 pSMB
->ParameterOffset
= cpu_to_le32(param_offset
);
4087 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4088 pSMB
->DataOffset
= cpu_to_le32(data_offset
);
4089 pSMB
->SetupCount
= 0;
4090 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC
);
4091 pSMB
->ByteCount
= cpu_to_le16(byte_count
+data_count
);
4093 pSMB
->Fid
= fid
; /* file handle always le */
4094 pSMB
->Reserved2
= 0;
4095 pSMB
->AclFlags
= cpu_to_le32(aclflag
);
4097 if (pntsd
&& acllen
) {
4098 memcpy((char *)pSMBr
+ offsetof(struct smb_hdr
, Protocol
) +
4099 data_offset
, pntsd
, acllen
);
4100 inc_rfc1001_len(pSMB
, byte_count
+ data_count
);
4102 inc_rfc1001_len(pSMB
, byte_count
);
4104 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4105 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4107 cifs_dbg(FYI
, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4108 bytes_returned
, rc
);
4110 cifs_dbg(FYI
, "Set CIFS ACL returned %d\n", rc
);
4111 cifs_buf_release(pSMB
);
4114 goto setCifsAclRetry
;
4120 /* Legacy Query Path Information call for lookup to old servers such
4123 SMBQueryInformation(const unsigned int xid
, struct cifs_tcon
*tcon
,
4124 const char *search_name
, FILE_ALL_INFO
*data
,
4125 const struct nls_table
*nls_codepage
, int remap
)
4127 QUERY_INFORMATION_REQ
*pSMB
;
4128 QUERY_INFORMATION_RSP
*pSMBr
;
4133 cifs_dbg(FYI
, "In SMBQPath path %s\n", search_name
);
4135 rc
= smb_init(SMB_COM_QUERY_INFORMATION
, 0, tcon
, (void **) &pSMB
,
4140 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4142 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4143 search_name
, PATH_MAX
, nls_codepage
,
4145 name_len
++; /* trailing null */
4148 name_len
= copy_path_name(pSMB
->FileName
, search_name
);
4150 pSMB
->BufferFormat
= 0x04;
4151 name_len
++; /* account for buffer type byte */
4152 inc_rfc1001_len(pSMB
, (__u16
)name_len
);
4153 pSMB
->ByteCount
= cpu_to_le16(name_len
);
4155 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4156 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4158 cifs_dbg(FYI
, "Send error in QueryInfo = %d\n", rc
);
4160 struct timespec64 ts
;
4161 __u32 time
= le32_to_cpu(pSMBr
->last_write_time
);
4163 /* decode response */
4164 /* BB FIXME - add time zone adjustment BB */
4165 memset(data
, 0, sizeof(FILE_ALL_INFO
));
4168 /* decode time fields */
4169 data
->ChangeTime
= cpu_to_le64(cifs_UnixTimeToNT(ts
));
4170 data
->LastWriteTime
= data
->ChangeTime
;
4171 data
->LastAccessTime
= 0;
4172 data
->AllocationSize
=
4173 cpu_to_le64(le32_to_cpu(pSMBr
->size
));
4174 data
->EndOfFile
= data
->AllocationSize
;
4176 cpu_to_le32(le16_to_cpu(pSMBr
->attr
));
4178 rc
= -EIO
; /* bad buffer passed in */
4180 cifs_buf_release(pSMB
);
4189 CIFSSMBQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4190 u16 netfid
, FILE_ALL_INFO
*pFindData
)
4192 struct smb_t2_qfi_req
*pSMB
= NULL
;
4193 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4196 __u16 params
, byte_count
;
4199 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4204 params
= 2 /* level */ + 2 /* fid */;
4205 pSMB
->t2
.TotalDataCount
= 0;
4206 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4207 /* BB find exact max data count below from sess structure BB */
4208 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4209 pSMB
->t2
.MaxSetupCount
= 0;
4210 pSMB
->t2
.Reserved
= 0;
4212 pSMB
->t2
.Timeout
= 0;
4213 pSMB
->t2
.Reserved2
= 0;
4214 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4216 pSMB
->t2
.DataCount
= 0;
4217 pSMB
->t2
.DataOffset
= 0;
4218 pSMB
->t2
.SetupCount
= 1;
4219 pSMB
->t2
.Reserved3
= 0;
4220 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4221 byte_count
= params
+ 1 /* pad */ ;
4222 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4223 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4224 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4227 inc_rfc1001_len(pSMB
, byte_count
);
4228 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4230 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4231 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4233 cifs_dbg(FYI
, "Send error in QFileInfo = %d", rc
);
4234 } else { /* decode response */
4235 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4237 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4239 else if (get_bcc(&pSMBr
->hdr
) < 40)
4240 rc
= -EIO
; /* bad smb */
4241 else if (pFindData
) {
4242 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4243 memcpy((char *) pFindData
,
4244 (char *) &pSMBr
->hdr
.Protocol
+
4245 data_offset
, sizeof(FILE_ALL_INFO
));
4249 cifs_buf_release(pSMB
);
4251 goto QFileInfoRetry
;
4257 CIFSSMBQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4258 const char *search_name
, FILE_ALL_INFO
*data
,
4259 int legacy
/* old style infolevel */,
4260 const struct nls_table
*nls_codepage
, int remap
)
4262 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4263 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4264 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4268 __u16 params
, byte_count
;
4270 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4272 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4277 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4279 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, search_name
,
4280 PATH_MAX
, nls_codepage
, remap
);
4281 name_len
++; /* trailing null */
4284 name_len
= copy_path_name(pSMB
->FileName
, search_name
);
4287 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4288 pSMB
->TotalDataCount
= 0;
4289 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4290 /* BB find exact max SMB PDU from sess structure BB */
4291 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4292 pSMB
->MaxSetupCount
= 0;
4296 pSMB
->Reserved2
= 0;
4297 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4298 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4299 pSMB
->DataCount
= 0;
4300 pSMB
->DataOffset
= 0;
4301 pSMB
->SetupCount
= 1;
4302 pSMB
->Reserved3
= 0;
4303 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4304 byte_count
= params
+ 1 /* pad */ ;
4305 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4306 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4308 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
4310 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4311 pSMB
->Reserved4
= 0;
4312 inc_rfc1001_len(pSMB
, byte_count
);
4313 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4315 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4316 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4318 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4319 } else { /* decode response */
4320 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4322 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4324 else if (!legacy
&& get_bcc(&pSMBr
->hdr
) < 40)
4325 rc
= -EIO
; /* bad smb */
4326 else if (legacy
&& get_bcc(&pSMBr
->hdr
) < 24)
4327 rc
= -EIO
; /* 24 or 26 expected but we do not read
4331 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4334 * On legacy responses we do not read the last field,
4335 * EAsize, fortunately since it varies by subdialect and
4336 * also note it differs on Set vs Get, ie two bytes or 4
4337 * bytes depending but we don't care here.
4340 size
= sizeof(FILE_INFO_STANDARD
);
4342 size
= sizeof(FILE_ALL_INFO
);
4343 memcpy((char *) data
, (char *) &pSMBr
->hdr
.Protocol
+
4348 cifs_buf_release(pSMB
);
4350 goto QPathInfoRetry
;
4356 CIFSSMBUnixQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4357 u16 netfid
, FILE_UNIX_BASIC_INFO
*pFindData
)
4359 struct smb_t2_qfi_req
*pSMB
= NULL
;
4360 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4363 __u16 params
, byte_count
;
4366 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4371 params
= 2 /* level */ + 2 /* fid */;
4372 pSMB
->t2
.TotalDataCount
= 0;
4373 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4374 /* BB find exact max data count below from sess structure BB */
4375 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4376 pSMB
->t2
.MaxSetupCount
= 0;
4377 pSMB
->t2
.Reserved
= 0;
4379 pSMB
->t2
.Timeout
= 0;
4380 pSMB
->t2
.Reserved2
= 0;
4381 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4383 pSMB
->t2
.DataCount
= 0;
4384 pSMB
->t2
.DataOffset
= 0;
4385 pSMB
->t2
.SetupCount
= 1;
4386 pSMB
->t2
.Reserved3
= 0;
4387 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4388 byte_count
= params
+ 1 /* pad */ ;
4389 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4390 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4391 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4394 inc_rfc1001_len(pSMB
, byte_count
);
4395 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4397 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4398 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4400 cifs_dbg(FYI
, "Send error in UnixQFileInfo = %d", rc
);
4401 } else { /* decode response */
4402 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4404 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4405 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4406 rc
= -EIO
; /* bad smb */
4408 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4409 memcpy((char *) pFindData
,
4410 (char *) &pSMBr
->hdr
.Protocol
+
4412 sizeof(FILE_UNIX_BASIC_INFO
));
4416 cifs_buf_release(pSMB
);
4418 goto UnixQFileInfoRetry
;
4424 CIFSSMBUnixQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4425 const unsigned char *searchName
,
4426 FILE_UNIX_BASIC_INFO
*pFindData
,
4427 const struct nls_table
*nls_codepage
, int remap
)
4429 /* SMB_QUERY_FILE_UNIX_BASIC */
4430 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4431 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4433 int bytes_returned
= 0;
4435 __u16 params
, byte_count
;
4437 cifs_dbg(FYI
, "In QPathInfo (Unix) the path %s\n", searchName
);
4439 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4444 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4446 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4447 PATH_MAX
, nls_codepage
, remap
);
4448 name_len
++; /* trailing null */
4451 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
4454 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4455 pSMB
->TotalDataCount
= 0;
4456 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4457 /* BB find exact max SMB PDU from sess structure BB */
4458 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4459 pSMB
->MaxSetupCount
= 0;
4463 pSMB
->Reserved2
= 0;
4464 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4465 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4466 pSMB
->DataCount
= 0;
4467 pSMB
->DataOffset
= 0;
4468 pSMB
->SetupCount
= 1;
4469 pSMB
->Reserved3
= 0;
4470 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4471 byte_count
= params
+ 1 /* pad */ ;
4472 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4473 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4474 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4475 pSMB
->Reserved4
= 0;
4476 inc_rfc1001_len(pSMB
, byte_count
);
4477 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4479 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4480 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4482 cifs_dbg(FYI
, "Send error in UnixQPathInfo = %d", rc
);
4483 } else { /* decode response */
4484 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4486 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4487 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4488 rc
= -EIO
; /* bad smb */
4490 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4491 memcpy((char *) pFindData
,
4492 (char *) &pSMBr
->hdr
.Protocol
+
4494 sizeof(FILE_UNIX_BASIC_INFO
));
4497 cifs_buf_release(pSMB
);
4499 goto UnixQPathInfoRetry
;
4504 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4506 CIFSFindFirst(const unsigned int xid
, struct cifs_tcon
*tcon
,
4507 const char *searchName
, struct cifs_sb_info
*cifs_sb
,
4508 __u16
*pnetfid
, __u16 search_flags
,
4509 struct cifs_search_info
*psrch_inf
, bool msearch
)
4511 /* level 257 SMB_ */
4512 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
4513 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
4514 T2_FFIRST_RSP_PARMS
*parms
;
4516 int bytes_returned
= 0;
4517 int name_len
, remap
;
4518 __u16 params
, byte_count
;
4519 struct nls_table
*nls_codepage
;
4521 cifs_dbg(FYI
, "In FindFirst for %s\n", searchName
);
4524 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4529 nls_codepage
= cifs_sb
->local_nls
;
4530 remap
= cifs_remap(cifs_sb
);
4532 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4534 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4535 PATH_MAX
, nls_codepage
, remap
);
4536 /* We can not add the asterik earlier in case
4537 it got remapped to 0xF03A as if it were part of the
4538 directory name instead of a wildcard */
4541 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4542 pSMB
->FileName
[name_len
+1] = 0;
4543 pSMB
->FileName
[name_len
+2] = '*';
4544 pSMB
->FileName
[name_len
+3] = 0;
4545 name_len
+= 4; /* now the trailing null */
4546 /* null terminate just in case */
4547 pSMB
->FileName
[name_len
] = 0;
4548 pSMB
->FileName
[name_len
+1] = 0;
4552 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
4554 if (WARN_ON_ONCE(name_len
> PATH_MAX
-2))
4555 name_len
= PATH_MAX
-2;
4556 /* overwrite nul byte */
4557 pSMB
->FileName
[name_len
-1] = CIFS_DIR_SEP(cifs_sb
);
4558 pSMB
->FileName
[name_len
] = '*';
4559 pSMB
->FileName
[name_len
+1] = 0;
4564 params
= 12 + name_len
/* includes null */ ;
4565 pSMB
->TotalDataCount
= 0; /* no EAs */
4566 pSMB
->MaxParameterCount
= cpu_to_le16(10);
4567 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4568 pSMB
->MaxSetupCount
= 0;
4572 pSMB
->Reserved2
= 0;
4573 byte_count
= params
+ 1 /* pad */ ;
4574 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4575 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4576 pSMB
->ParameterOffset
= cpu_to_le16(
4577 offsetof(struct smb_com_transaction2_ffirst_req
, SearchAttributes
)
4579 pSMB
->DataCount
= 0;
4580 pSMB
->DataOffset
= 0;
4581 pSMB
->SetupCount
= 1; /* one byte, no need to make endian neutral */
4582 pSMB
->Reserved3
= 0;
4583 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
4584 pSMB
->SearchAttributes
=
4585 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
4587 pSMB
->SearchCount
= cpu_to_le16(CIFSMaxBufSize
/sizeof(FILE_UNIX_INFO
));
4588 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4589 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4591 /* BB what should we set StorageType to? Does it matter? BB */
4592 pSMB
->SearchStorageType
= 0;
4593 inc_rfc1001_len(pSMB
, byte_count
);
4594 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4596 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4597 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4598 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_ffirst
);
4600 if (rc
) {/* BB add logic to retry regular search if Unix search
4601 rejected unexpectedly by server */
4602 /* BB Add code to handle unsupported level rc */
4603 cifs_dbg(FYI
, "Error in FindFirst = %d\n", rc
);
4605 cifs_buf_release(pSMB
);
4607 /* BB eventually could optimize out free and realloc of buf */
4610 goto findFirstRetry
;
4611 } else { /* decode response */
4612 /* BB remember to free buffer if error BB */
4613 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4617 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4618 psrch_inf
->unicode
= true;
4620 psrch_inf
->unicode
= false;
4622 psrch_inf
->ntwrk_buf_start
= (char *)pSMBr
;
4623 psrch_inf
->smallBuf
= false;
4624 psrch_inf
->srch_entries_start
=
4625 (char *) &pSMBr
->hdr
.Protocol
+
4626 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4627 parms
= (T2_FFIRST_RSP_PARMS
*)((char *) &pSMBr
->hdr
.Protocol
+
4628 le16_to_cpu(pSMBr
->t2
.ParameterOffset
));
4630 if (parms
->EndofSearch
)
4631 psrch_inf
->endOfSearch
= true;
4633 psrch_inf
->endOfSearch
= false;
4635 psrch_inf
->entries_in_buffer
=
4636 le16_to_cpu(parms
->SearchCount
);
4637 psrch_inf
->index_of_last_entry
= 2 /* skip . and .. */ +
4638 psrch_inf
->entries_in_buffer
;
4639 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4640 if (CIFSMaxBufSize
< lnoff
) {
4641 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4642 psrch_inf
->last_entry
= NULL
;
4646 psrch_inf
->last_entry
= psrch_inf
->srch_entries_start
+
4650 *pnetfid
= parms
->SearchHandle
;
4652 cifs_buf_release(pSMB
);
4659 int CIFSFindNext(const unsigned int xid
, struct cifs_tcon
*tcon
,
4660 __u16 searchHandle
, __u16 search_flags
,
4661 struct cifs_search_info
*psrch_inf
)
4663 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
4664 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
4665 T2_FNEXT_RSP_PARMS
*parms
;
4666 char *response_data
;
4669 unsigned int name_len
;
4670 __u16 params
, byte_count
;
4672 cifs_dbg(FYI
, "In FindNext\n");
4674 if (psrch_inf
->endOfSearch
)
4677 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4682 params
= 14; /* includes 2 bytes of null string, converted to LE below*/
4684 pSMB
->TotalDataCount
= 0; /* no EAs */
4685 pSMB
->MaxParameterCount
= cpu_to_le16(8);
4686 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4687 pSMB
->MaxSetupCount
= 0;
4691 pSMB
->Reserved2
= 0;
4692 pSMB
->ParameterOffset
= cpu_to_le16(
4693 offsetof(struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
4694 pSMB
->DataCount
= 0;
4695 pSMB
->DataOffset
= 0;
4696 pSMB
->SetupCount
= 1;
4697 pSMB
->Reserved3
= 0;
4698 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
4699 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
4701 cpu_to_le16(CIFSMaxBufSize
/ sizeof(FILE_UNIX_INFO
));
4702 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4703 pSMB
->ResumeKey
= psrch_inf
->resume_key
;
4704 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4706 name_len
= psrch_inf
->resume_name_len
;
4708 if (name_len
< PATH_MAX
) {
4709 memcpy(pSMB
->ResumeFileName
, psrch_inf
->presume_name
, name_len
);
4710 byte_count
+= name_len
;
4711 /* 14 byte parm len above enough for 2 byte null terminator */
4712 pSMB
->ResumeFileName
[name_len
] = 0;
4713 pSMB
->ResumeFileName
[name_len
+1] = 0;
4716 goto FNext2_err_exit
;
4718 byte_count
= params
+ 1 /* pad */ ;
4719 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4720 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4721 inc_rfc1001_len(pSMB
, byte_count
);
4722 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4724 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4725 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4726 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fnext
);
4729 psrch_inf
->endOfSearch
= true;
4730 cifs_buf_release(pSMB
);
4731 rc
= 0; /* search probably was closed at end of search*/
4733 cifs_dbg(FYI
, "FindNext returned = %d\n", rc
);
4734 } else { /* decode response */
4735 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4740 /* BB fixme add lock for file (srch_info) struct here */
4741 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4742 psrch_inf
->unicode
= true;
4744 psrch_inf
->unicode
= false;
4745 response_data
= (char *) &pSMBr
->hdr
.Protocol
+
4746 le16_to_cpu(pSMBr
->t2
.ParameterOffset
);
4747 parms
= (T2_FNEXT_RSP_PARMS
*)response_data
;
4748 response_data
= (char *)&pSMBr
->hdr
.Protocol
+
4749 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4750 if (psrch_inf
->smallBuf
)
4751 cifs_small_buf_release(
4752 psrch_inf
->ntwrk_buf_start
);
4754 cifs_buf_release(psrch_inf
->ntwrk_buf_start
);
4755 psrch_inf
->srch_entries_start
= response_data
;
4756 psrch_inf
->ntwrk_buf_start
= (char *)pSMB
;
4757 psrch_inf
->smallBuf
= false;
4758 if (parms
->EndofSearch
)
4759 psrch_inf
->endOfSearch
= true;
4761 psrch_inf
->endOfSearch
= false;
4762 psrch_inf
->entries_in_buffer
=
4763 le16_to_cpu(parms
->SearchCount
);
4764 psrch_inf
->index_of_last_entry
+=
4765 psrch_inf
->entries_in_buffer
;
4766 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4767 if (CIFSMaxBufSize
< lnoff
) {
4768 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4769 psrch_inf
->last_entry
= NULL
;
4772 psrch_inf
->last_entry
=
4773 psrch_inf
->srch_entries_start
+ lnoff
;
4775 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4776 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4778 /* BB fixme add unlock here */
4783 /* BB On error, should we leave previous search buf (and count and
4784 last entry fields) intact or free the previous one? */
4786 /* Note: On -EAGAIN error only caller can retry on handle based calls
4787 since file handle passed in no longer valid */
4790 cifs_buf_release(pSMB
);
4795 CIFSFindClose(const unsigned int xid
, struct cifs_tcon
*tcon
,
4796 const __u16 searchHandle
)
4799 FINDCLOSE_REQ
*pSMB
= NULL
;
4801 cifs_dbg(FYI
, "In CIFSSMBFindClose\n");
4802 rc
= small_smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **)&pSMB
);
4804 /* no sense returning error if session restarted
4805 as file handle has been closed */
4811 pSMB
->FileID
= searchHandle
;
4812 pSMB
->ByteCount
= 0;
4813 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
4814 cifs_small_buf_release(pSMB
);
4816 cifs_dbg(VFS
, "Send error in FindClose = %d\n", rc
);
4818 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fclose
);
4820 /* Since session is dead, search handle closed on server already */
4828 CIFSGetSrvInodeNumber(const unsigned int xid
, struct cifs_tcon
*tcon
,
4829 const char *search_name
, __u64
*inode_number
,
4830 const struct nls_table
*nls_codepage
, int remap
)
4833 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4834 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4835 int name_len
, bytes_returned
;
4836 __u16 params
, byte_count
;
4838 cifs_dbg(FYI
, "In GetSrvInodeNum for %s\n", search_name
);
4842 GetInodeNumberRetry
:
4843 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4848 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4850 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4851 search_name
, PATH_MAX
, nls_codepage
,
4853 name_len
++; /* trailing null */
4856 name_len
= copy_path_name(pSMB
->FileName
, search_name
);
4859 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
4860 pSMB
->TotalDataCount
= 0;
4861 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4862 /* BB find exact max data count below from sess structure BB */
4863 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4864 pSMB
->MaxSetupCount
= 0;
4868 pSMB
->Reserved2
= 0;
4869 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4870 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4871 pSMB
->DataCount
= 0;
4872 pSMB
->DataOffset
= 0;
4873 pSMB
->SetupCount
= 1;
4874 pSMB
->Reserved3
= 0;
4875 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4876 byte_count
= params
+ 1 /* pad */ ;
4877 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4878 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4879 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO
);
4880 pSMB
->Reserved4
= 0;
4881 inc_rfc1001_len(pSMB
, byte_count
);
4882 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4884 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4885 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4887 cifs_dbg(FYI
, "error %d in QueryInternalInfo\n", rc
);
4889 /* decode response */
4890 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4891 /* BB also check enough total bytes returned */
4892 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
4893 /* If rc should we check for EOPNOSUPP and
4894 disable the srvino flag? or in caller? */
4895 rc
= -EIO
; /* bad smb */
4897 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4898 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
4899 struct file_internal_info
*pfinfo
;
4900 /* BB Do we need a cast or hash here ? */
4902 cifs_dbg(FYI
, "Illegal size ret in QryIntrnlInf\n");
4904 goto GetInodeNumOut
;
4906 pfinfo
= (struct file_internal_info
*)
4907 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
4908 *inode_number
= le64_to_cpu(pfinfo
->UniqueId
);
4912 cifs_buf_release(pSMB
);
4914 goto GetInodeNumberRetry
;
4919 CIFSGetDFSRefer(const unsigned int xid
, struct cifs_ses
*ses
,
4920 const char *search_name
, struct dfs_info3_param
**target_nodes
,
4921 unsigned int *num_of_nodes
,
4922 const struct nls_table
*nls_codepage
, int remap
)
4924 /* TRANS2_GET_DFS_REFERRAL */
4925 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
4926 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
4930 __u16 params
, byte_count
;
4932 *target_nodes
= NULL
;
4934 cifs_dbg(FYI
, "In GetDFSRefer the path %s\n", search_name
);
4935 if (ses
== NULL
|| ses
->tcon_ipc
== NULL
)
4939 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, ses
->tcon_ipc
, (void **) &pSMB
,
4944 /* server pointer checked in called function,
4945 but should never be null here anyway */
4946 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
4947 pSMB
->hdr
.Tid
= ses
->tcon_ipc
->tid
;
4948 pSMB
->hdr
.Uid
= ses
->Suid
;
4949 if (ses
->capabilities
& CAP_STATUS32
)
4950 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
4951 if (ses
->capabilities
& CAP_DFS
)
4952 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
4954 if (ses
->capabilities
& CAP_UNICODE
) {
4955 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
4957 cifsConvertToUTF16((__le16
*) pSMB
->RequestFileName
,
4958 search_name
, PATH_MAX
, nls_codepage
,
4960 name_len
++; /* trailing null */
4962 } else { /* BB improve the check for buffer overruns BB */
4963 name_len
= copy_path_name(pSMB
->RequestFileName
, search_name
);
4966 if (ses
->server
->sign
)
4967 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
4969 pSMB
->hdr
.Uid
= ses
->Suid
;
4971 params
= 2 /* level */ + name_len
/*includes null */ ;
4972 pSMB
->TotalDataCount
= 0;
4973 pSMB
->DataCount
= 0;
4974 pSMB
->DataOffset
= 0;
4975 pSMB
->MaxParameterCount
= 0;
4976 /* BB find exact max SMB PDU from sess structure BB */
4977 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4978 pSMB
->MaxSetupCount
= 0;
4982 pSMB
->Reserved2
= 0;
4983 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4984 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
4985 pSMB
->SetupCount
= 1;
4986 pSMB
->Reserved3
= 0;
4987 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
4988 byte_count
= params
+ 3 /* pad */ ;
4989 pSMB
->ParameterCount
= cpu_to_le16(params
);
4990 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4991 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
4992 inc_rfc1001_len(pSMB
, byte_count
);
4993 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4995 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
4996 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4998 cifs_dbg(FYI
, "Send error in GetDFSRefer = %d\n", rc
);
5001 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5003 /* BB Also check if enough total bytes returned? */
5004 if (rc
|| get_bcc(&pSMBr
->hdr
) < 17) {
5005 rc
= -EIO
; /* bad smb */
5009 cifs_dbg(FYI
, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
5010 get_bcc(&pSMBr
->hdr
), le16_to_cpu(pSMBr
->t2
.DataOffset
));
5012 /* parse returned result into more usable form */
5013 rc
= parse_dfs_referrals(&pSMBr
->dfs_data
,
5014 le16_to_cpu(pSMBr
->t2
.DataCount
),
5015 num_of_nodes
, target_nodes
, nls_codepage
,
5017 (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) != 0);
5020 cifs_buf_release(pSMB
);
5028 /* Query File System Info such as free space to old servers such as Win 9x */
5030 SMBOldQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5031 struct kstatfs
*FSData
)
5033 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
5034 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5035 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5036 FILE_SYSTEM_ALLOC_INFO
*response_data
;
5038 int bytes_returned
= 0;
5039 __u16 params
, byte_count
;
5041 cifs_dbg(FYI
, "OldQFSInfo\n");
5043 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5048 params
= 2; /* level */
5049 pSMB
->TotalDataCount
= 0;
5050 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5051 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5052 pSMB
->MaxSetupCount
= 0;
5056 pSMB
->Reserved2
= 0;
5057 byte_count
= params
+ 1 /* pad */ ;
5058 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5059 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5060 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5061 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5062 pSMB
->DataCount
= 0;
5063 pSMB
->DataOffset
= 0;
5064 pSMB
->SetupCount
= 1;
5065 pSMB
->Reserved3
= 0;
5066 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5067 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_ALLOCATION
);
5068 inc_rfc1001_len(pSMB
, byte_count
);
5069 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5071 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5072 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5074 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5075 } else { /* decode response */
5076 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5078 if (rc
|| get_bcc(&pSMBr
->hdr
) < 18)
5079 rc
= -EIO
; /* bad smb */
5081 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5082 cifs_dbg(FYI
, "qfsinf resp BCC: %d Offset %d\n",
5083 get_bcc(&pSMBr
->hdr
), data_offset
);
5085 response_data
= (FILE_SYSTEM_ALLOC_INFO
*)
5086 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
5088 le16_to_cpu(response_data
->BytesPerSector
) *
5089 le32_to_cpu(response_data
->
5090 SectorsPerAllocationUnit
);
5092 * much prefer larger but if server doesn't report
5093 * a valid size than 4K is a reasonable minimum
5095 if (FSData
->f_bsize
< 512)
5096 FSData
->f_bsize
= 4096;
5099 le32_to_cpu(response_data
->TotalAllocationUnits
);
5100 FSData
->f_bfree
= FSData
->f_bavail
=
5101 le32_to_cpu(response_data
->FreeAllocationUnits
);
5102 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5103 (unsigned long long)FSData
->f_blocks
,
5104 (unsigned long long)FSData
->f_bfree
,
5108 cifs_buf_release(pSMB
);
5111 goto oldQFSInfoRetry
;
5117 CIFSSMBQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5118 struct kstatfs
*FSData
)
5120 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5121 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5122 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5123 FILE_SYSTEM_INFO
*response_data
;
5125 int bytes_returned
= 0;
5126 __u16 params
, byte_count
;
5128 cifs_dbg(FYI
, "In QFSInfo\n");
5130 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5135 params
= 2; /* level */
5136 pSMB
->TotalDataCount
= 0;
5137 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5138 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5139 pSMB
->MaxSetupCount
= 0;
5143 pSMB
->Reserved2
= 0;
5144 byte_count
= params
+ 1 /* pad */ ;
5145 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5146 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5147 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5148 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5149 pSMB
->DataCount
= 0;
5150 pSMB
->DataOffset
= 0;
5151 pSMB
->SetupCount
= 1;
5152 pSMB
->Reserved3
= 0;
5153 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5154 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
5155 inc_rfc1001_len(pSMB
, byte_count
);
5156 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5158 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5159 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5161 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5162 } else { /* decode response */
5163 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5165 if (rc
|| get_bcc(&pSMBr
->hdr
) < 24)
5166 rc
= -EIO
; /* bad smb */
5168 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5172 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5175 le32_to_cpu(response_data
->BytesPerSector
) *
5176 le32_to_cpu(response_data
->
5177 SectorsPerAllocationUnit
);
5179 * much prefer larger but if server doesn't report
5180 * a valid size than 4K is a reasonable minimum
5182 if (FSData
->f_bsize
< 512)
5183 FSData
->f_bsize
= 4096;
5186 le64_to_cpu(response_data
->TotalAllocationUnits
);
5187 FSData
->f_bfree
= FSData
->f_bavail
=
5188 le64_to_cpu(response_data
->FreeAllocationUnits
);
5189 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5190 (unsigned long long)FSData
->f_blocks
,
5191 (unsigned long long)FSData
->f_bfree
,
5195 cifs_buf_release(pSMB
);
5204 CIFSSMBQFSAttributeInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5206 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5207 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5208 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5209 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
5211 int bytes_returned
= 0;
5212 __u16 params
, byte_count
;
5214 cifs_dbg(FYI
, "In QFSAttributeInfo\n");
5216 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5221 params
= 2; /* level */
5222 pSMB
->TotalDataCount
= 0;
5223 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5224 /* BB find exact max SMB PDU from sess structure BB */
5225 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5226 pSMB
->MaxSetupCount
= 0;
5230 pSMB
->Reserved2
= 0;
5231 byte_count
= params
+ 1 /* pad */ ;
5232 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5233 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5234 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5235 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5236 pSMB
->DataCount
= 0;
5237 pSMB
->DataOffset
= 0;
5238 pSMB
->SetupCount
= 1;
5239 pSMB
->Reserved3
= 0;
5240 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5241 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
5242 inc_rfc1001_len(pSMB
, byte_count
);
5243 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5245 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5246 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5248 cifs_dbg(VFS
, "Send error in QFSAttributeInfo = %d\n", rc
);
5249 } else { /* decode response */
5250 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5252 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5253 /* BB also check if enough bytes returned */
5254 rc
= -EIO
; /* bad smb */
5256 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5258 (FILE_SYSTEM_ATTRIBUTE_INFO
5259 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5261 memcpy(&tcon
->fsAttrInfo
, response_data
,
5262 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO
));
5265 cifs_buf_release(pSMB
);
5268 goto QFSAttributeRetry
;
5274 CIFSSMBQFSDeviceInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5276 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5277 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5278 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5279 FILE_SYSTEM_DEVICE_INFO
*response_data
;
5281 int bytes_returned
= 0;
5282 __u16 params
, byte_count
;
5284 cifs_dbg(FYI
, "In QFSDeviceInfo\n");
5286 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5291 params
= 2; /* level */
5292 pSMB
->TotalDataCount
= 0;
5293 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5294 /* BB find exact max SMB PDU from sess structure BB */
5295 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5296 pSMB
->MaxSetupCount
= 0;
5300 pSMB
->Reserved2
= 0;
5301 byte_count
= params
+ 1 /* pad */ ;
5302 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5303 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5304 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5305 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5307 pSMB
->DataCount
= 0;
5308 pSMB
->DataOffset
= 0;
5309 pSMB
->SetupCount
= 1;
5310 pSMB
->Reserved3
= 0;
5311 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5312 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
5313 inc_rfc1001_len(pSMB
, byte_count
);
5314 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5316 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5317 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5319 cifs_dbg(FYI
, "Send error in QFSDeviceInfo = %d\n", rc
);
5320 } else { /* decode response */
5321 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5323 if (rc
|| get_bcc(&pSMBr
->hdr
) <
5324 sizeof(FILE_SYSTEM_DEVICE_INFO
))
5325 rc
= -EIO
; /* bad smb */
5327 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5329 (FILE_SYSTEM_DEVICE_INFO
*)
5330 (((char *) &pSMBr
->hdr
.Protocol
) +
5332 memcpy(&tcon
->fsDevInfo
, response_data
,
5333 sizeof(FILE_SYSTEM_DEVICE_INFO
));
5336 cifs_buf_release(pSMB
);
5339 goto QFSDeviceRetry
;
5345 CIFSSMBQFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5347 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5348 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5349 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5350 FILE_SYSTEM_UNIX_INFO
*response_data
;
5352 int bytes_returned
= 0;
5353 __u16 params
, byte_count
;
5355 cifs_dbg(FYI
, "In QFSUnixInfo\n");
5357 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5358 (void **) &pSMB
, (void **) &pSMBr
);
5362 params
= 2; /* level */
5363 pSMB
->TotalDataCount
= 0;
5364 pSMB
->DataCount
= 0;
5365 pSMB
->DataOffset
= 0;
5366 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5367 /* BB find exact max SMB PDU from sess structure BB */
5368 pSMB
->MaxDataCount
= cpu_to_le16(100);
5369 pSMB
->MaxSetupCount
= 0;
5373 pSMB
->Reserved2
= 0;
5374 byte_count
= params
+ 1 /* pad */ ;
5375 pSMB
->ParameterCount
= cpu_to_le16(params
);
5376 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5377 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5378 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5379 pSMB
->SetupCount
= 1;
5380 pSMB
->Reserved3
= 0;
5381 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5382 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
5383 inc_rfc1001_len(pSMB
, byte_count
);
5384 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5386 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5387 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5389 cifs_dbg(VFS
, "Send error in QFSUnixInfo = %d\n", rc
);
5390 } else { /* decode response */
5391 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5393 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5394 rc
= -EIO
; /* bad smb */
5396 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5398 (FILE_SYSTEM_UNIX_INFO
5399 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5401 memcpy(&tcon
->fsUnixInfo
, response_data
,
5402 sizeof(FILE_SYSTEM_UNIX_INFO
));
5405 cifs_buf_release(pSMB
);
5415 CIFSSMBSetFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
, __u64 cap
)
5417 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5418 TRANSACTION2_SETFSI_REQ
*pSMB
= NULL
;
5419 TRANSACTION2_SETFSI_RSP
*pSMBr
= NULL
;
5421 int bytes_returned
= 0;
5422 __u16 params
, param_offset
, offset
, byte_count
;
5424 cifs_dbg(FYI
, "In SETFSUnixInfo\n");
5426 /* BB switch to small buf init to save memory */
5427 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5428 (void **) &pSMB
, (void **) &pSMBr
);
5432 params
= 4; /* 2 bytes zero followed by info level. */
5433 pSMB
->MaxSetupCount
= 0;
5437 pSMB
->Reserved2
= 0;
5438 param_offset
= offsetof(struct smb_com_transaction2_setfsi_req
, FileNum
)
5440 offset
= param_offset
+ params
;
5442 pSMB
->MaxParameterCount
= cpu_to_le16(4);
5443 /* BB find exact max SMB PDU from sess structure BB */
5444 pSMB
->MaxDataCount
= cpu_to_le16(100);
5445 pSMB
->SetupCount
= 1;
5446 pSMB
->Reserved3
= 0;
5447 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FS_INFORMATION
);
5448 byte_count
= 1 /* pad */ + params
+ 12;
5450 pSMB
->DataCount
= cpu_to_le16(12);
5451 pSMB
->ParameterCount
= cpu_to_le16(params
);
5452 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5453 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5454 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5455 pSMB
->DataOffset
= cpu_to_le16(offset
);
5459 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_CIFS_UNIX_INFO
);
5462 pSMB
->ClientUnixMajor
= cpu_to_le16(CIFS_UNIX_MAJOR_VERSION
);
5463 pSMB
->ClientUnixMinor
= cpu_to_le16(CIFS_UNIX_MINOR_VERSION
);
5464 pSMB
->ClientUnixCap
= cpu_to_le64(cap
);
5466 inc_rfc1001_len(pSMB
, byte_count
);
5467 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5469 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5470 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5472 cifs_dbg(VFS
, "Send error in SETFSUnixInfo = %d\n", rc
);
5473 } else { /* decode response */
5474 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5476 rc
= -EIO
; /* bad smb */
5478 cifs_buf_release(pSMB
);
5481 goto SETFSUnixRetry
;
5489 CIFSSMBQFSPosixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5490 struct kstatfs
*FSData
)
5492 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5493 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5494 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5495 FILE_SYSTEM_POSIX_INFO
*response_data
;
5497 int bytes_returned
= 0;
5498 __u16 params
, byte_count
;
5500 cifs_dbg(FYI
, "In QFSPosixInfo\n");
5502 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5507 params
= 2; /* level */
5508 pSMB
->TotalDataCount
= 0;
5509 pSMB
->DataCount
= 0;
5510 pSMB
->DataOffset
= 0;
5511 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5512 /* BB find exact max SMB PDU from sess structure BB */
5513 pSMB
->MaxDataCount
= cpu_to_le16(100);
5514 pSMB
->MaxSetupCount
= 0;
5518 pSMB
->Reserved2
= 0;
5519 byte_count
= params
+ 1 /* pad */ ;
5520 pSMB
->ParameterCount
= cpu_to_le16(params
);
5521 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5522 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5523 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5524 pSMB
->SetupCount
= 1;
5525 pSMB
->Reserved3
= 0;
5526 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5527 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_FS_INFO
);
5528 inc_rfc1001_len(pSMB
, byte_count
);
5529 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5531 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5532 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5534 cifs_dbg(FYI
, "Send error in QFSUnixInfo = %d\n", rc
);
5535 } else { /* decode response */
5536 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5538 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5539 rc
= -EIO
; /* bad smb */
5541 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5543 (FILE_SYSTEM_POSIX_INFO
5544 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5547 le32_to_cpu(response_data
->BlockSize
);
5549 * much prefer larger but if server doesn't report
5550 * a valid size than 4K is a reasonable minimum
5552 if (FSData
->f_bsize
< 512)
5553 FSData
->f_bsize
= 4096;
5556 le64_to_cpu(response_data
->TotalBlocks
);
5558 le64_to_cpu(response_data
->BlocksAvail
);
5559 if (response_data
->UserBlocksAvail
== cpu_to_le64(-1)) {
5560 FSData
->f_bavail
= FSData
->f_bfree
;
5563 le64_to_cpu(response_data
->UserBlocksAvail
);
5565 if (response_data
->TotalFileNodes
!= cpu_to_le64(-1))
5567 le64_to_cpu(response_data
->TotalFileNodes
);
5568 if (response_data
->FreeFileNodes
!= cpu_to_le64(-1))
5570 le64_to_cpu(response_data
->FreeFileNodes
);
5573 cifs_buf_release(pSMB
);
5583 * We can not use write of zero bytes trick to set file size due to need for
5584 * large file support. Also note that this SetPathInfo is preferred to
5585 * SetFileInfo based method in next routine which is only needed to work around
5586 * a sharing violation bugin Samba which this routine can run into.
5589 CIFSSMBSetEOF(const unsigned int xid
, struct cifs_tcon
*tcon
,
5590 const char *file_name
, __u64 size
, struct cifs_sb_info
*cifs_sb
,
5591 bool set_allocation
)
5593 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5594 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5595 struct file_end_of_file_info
*parm_data
;
5598 int bytes_returned
= 0;
5599 int remap
= cifs_remap(cifs_sb
);
5601 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
5603 cifs_dbg(FYI
, "In SetEOF\n");
5605 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5610 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5612 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5613 PATH_MAX
, cifs_sb
->local_nls
, remap
);
5614 name_len
++; /* trailing null */
5617 name_len
= copy_path_name(pSMB
->FileName
, file_name
);
5619 params
= 6 + name_len
;
5620 data_count
= sizeof(struct file_end_of_file_info
);
5621 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5622 pSMB
->MaxDataCount
= cpu_to_le16(4100);
5623 pSMB
->MaxSetupCount
= 0;
5627 pSMB
->Reserved2
= 0;
5628 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5629 InformationLevel
) - 4;
5630 offset
= param_offset
+ params
;
5631 if (set_allocation
) {
5632 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5633 pSMB
->InformationLevel
=
5634 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5636 pSMB
->InformationLevel
=
5637 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5638 } else /* Set File Size */ {
5639 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5640 pSMB
->InformationLevel
=
5641 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5643 pSMB
->InformationLevel
=
5644 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5648 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
5650 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5651 pSMB
->DataOffset
= cpu_to_le16(offset
);
5652 pSMB
->SetupCount
= 1;
5653 pSMB
->Reserved3
= 0;
5654 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5655 byte_count
= 3 /* pad */ + params
+ data_count
;
5656 pSMB
->DataCount
= cpu_to_le16(data_count
);
5657 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5658 pSMB
->ParameterCount
= cpu_to_le16(params
);
5659 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5660 pSMB
->Reserved4
= 0;
5661 inc_rfc1001_len(pSMB
, byte_count
);
5662 parm_data
->FileSize
= cpu_to_le64(size
);
5663 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5664 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5665 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5667 cifs_dbg(FYI
, "SetPathInfo (file size) returned %d\n", rc
);
5669 cifs_buf_release(pSMB
);
5678 CIFSSMBSetFileSize(const unsigned int xid
, struct cifs_tcon
*tcon
,
5679 struct cifsFileInfo
*cfile
, __u64 size
, bool set_allocation
)
5681 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5682 struct file_end_of_file_info
*parm_data
;
5684 __u16 params
, param_offset
, offset
, byte_count
, count
;
5686 cifs_dbg(FYI
, "SetFileSize (via SetFileInfo) %lld\n",
5688 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5693 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)cfile
->pid
);
5694 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(cfile
->pid
>> 16));
5697 pSMB
->MaxSetupCount
= 0;
5701 pSMB
->Reserved2
= 0;
5702 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5703 offset
= param_offset
+ params
;
5705 count
= sizeof(struct file_end_of_file_info
);
5706 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5707 /* BB find exact max SMB PDU from sess structure BB */
5708 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5709 pSMB
->SetupCount
= 1;
5710 pSMB
->Reserved3
= 0;
5711 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5712 byte_count
= 3 /* pad */ + params
+ count
;
5713 pSMB
->DataCount
= cpu_to_le16(count
);
5714 pSMB
->ParameterCount
= cpu_to_le16(params
);
5715 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5716 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5717 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5719 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
)
5721 pSMB
->DataOffset
= cpu_to_le16(offset
);
5722 parm_data
->FileSize
= cpu_to_le64(size
);
5723 pSMB
->Fid
= cfile
->fid
.netfid
;
5724 if (set_allocation
) {
5725 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5726 pSMB
->InformationLevel
=
5727 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5729 pSMB
->InformationLevel
=
5730 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5731 } else /* Set File Size */ {
5732 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5733 pSMB
->InformationLevel
=
5734 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5736 pSMB
->InformationLevel
=
5737 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5739 pSMB
->Reserved4
= 0;
5740 inc_rfc1001_len(pSMB
, byte_count
);
5741 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5742 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5743 cifs_small_buf_release(pSMB
);
5745 cifs_dbg(FYI
, "Send error in SetFileInfo (SetFileSize) = %d\n",
5749 /* Note: On -EAGAIN error only caller can retry on handle based calls
5750 since file handle passed in no longer valid */
5755 /* Some legacy servers such as NT4 require that the file times be set on
5756 an open handle, rather than by pathname - this is awkward due to
5757 potential access conflicts on the open, but it is unavoidable for these
5758 old servers since the only other choice is to go from 100 nanosecond DCE
5759 time and resort to the original setpathinfo level which takes the ancient
5760 DOS time format with 2 second granularity */
5762 CIFSSMBSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5763 const FILE_BASIC_INFO
*data
, __u16 fid
, __u32 pid_of_opener
)
5765 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5768 __u16 params
, param_offset
, offset
, byte_count
, count
;
5770 cifs_dbg(FYI
, "Set Times (via SetFileInfo)\n");
5771 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5776 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5777 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5780 pSMB
->MaxSetupCount
= 0;
5784 pSMB
->Reserved2
= 0;
5785 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5786 offset
= param_offset
+ params
;
5788 data_offset
= (char *)pSMB
+
5789 offsetof(struct smb_hdr
, Protocol
) + offset
;
5791 count
= sizeof(FILE_BASIC_INFO
);
5792 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5793 /* BB find max SMB PDU from sess */
5794 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5795 pSMB
->SetupCount
= 1;
5796 pSMB
->Reserved3
= 0;
5797 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5798 byte_count
= 3 /* pad */ + params
+ count
;
5799 pSMB
->DataCount
= cpu_to_le16(count
);
5800 pSMB
->ParameterCount
= cpu_to_le16(params
);
5801 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5802 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5803 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5804 pSMB
->DataOffset
= cpu_to_le16(offset
);
5806 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5807 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5809 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5810 pSMB
->Reserved4
= 0;
5811 inc_rfc1001_len(pSMB
, byte_count
);
5812 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5813 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5814 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5815 cifs_small_buf_release(pSMB
);
5817 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5820 /* Note: On -EAGAIN error only caller can retry on handle based calls
5821 since file handle passed in no longer valid */
5827 CIFSSMBSetFileDisposition(const unsigned int xid
, struct cifs_tcon
*tcon
,
5828 bool delete_file
, __u16 fid
, __u32 pid_of_opener
)
5830 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5833 __u16 params
, param_offset
, offset
, byte_count
, count
;
5835 cifs_dbg(FYI
, "Set File Disposition (via SetFileInfo)\n");
5836 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5841 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5842 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5845 pSMB
->MaxSetupCount
= 0;
5849 pSMB
->Reserved2
= 0;
5850 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5851 offset
= param_offset
+ params
;
5853 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5856 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5857 /* BB find max SMB PDU from sess */
5858 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5859 pSMB
->SetupCount
= 1;
5860 pSMB
->Reserved3
= 0;
5861 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5862 byte_count
= 3 /* pad */ + params
+ count
;
5863 pSMB
->DataCount
= cpu_to_le16(count
);
5864 pSMB
->ParameterCount
= cpu_to_le16(params
);
5865 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5866 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5867 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5868 pSMB
->DataOffset
= cpu_to_le16(offset
);
5870 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO
);
5871 pSMB
->Reserved4
= 0;
5872 inc_rfc1001_len(pSMB
, byte_count
);
5873 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5874 *data_offset
= delete_file
? 1 : 0;
5875 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5876 cifs_small_buf_release(pSMB
);
5878 cifs_dbg(FYI
, "Send error in SetFileDisposition = %d\n", rc
);
5884 CIFSSMBSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5885 const char *fileName
, const FILE_BASIC_INFO
*data
,
5886 const struct nls_table
*nls_codepage
, int remap
)
5888 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5889 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5892 int bytes_returned
= 0;
5894 __u16 params
, param_offset
, offset
, byte_count
, count
;
5896 cifs_dbg(FYI
, "In SetTimes\n");
5899 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5904 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5906 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5907 PATH_MAX
, nls_codepage
, remap
);
5908 name_len
++; /* trailing null */
5911 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
5914 params
= 6 + name_len
;
5915 count
= sizeof(FILE_BASIC_INFO
);
5916 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5917 /* BB find max SMB PDU from sess structure BB */
5918 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5919 pSMB
->MaxSetupCount
= 0;
5923 pSMB
->Reserved2
= 0;
5924 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5925 InformationLevel
) - 4;
5926 offset
= param_offset
+ params
;
5927 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5928 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5929 pSMB
->DataOffset
= cpu_to_le16(offset
);
5930 pSMB
->SetupCount
= 1;
5931 pSMB
->Reserved3
= 0;
5932 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5933 byte_count
= 3 /* pad */ + params
+ count
;
5935 pSMB
->DataCount
= cpu_to_le16(count
);
5936 pSMB
->ParameterCount
= cpu_to_le16(params
);
5937 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5938 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5939 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5940 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5942 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5943 pSMB
->Reserved4
= 0;
5944 inc_rfc1001_len(pSMB
, byte_count
);
5945 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5946 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5947 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5948 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5950 cifs_dbg(FYI
, "SetPathInfo (times) returned %d\n", rc
);
5952 cifs_buf_release(pSMB
);
5960 /* Can not be used to set time stamps yet (due to old DOS time format) */
5961 /* Can be used to set attributes */
5962 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5963 handling it anyway and NT4 was what we thought it would be needed for
5964 Do not delete it until we prove whether needed for Win9x though */
5966 CIFSSMBSetAttrLegacy(unsigned int xid
, struct cifs_tcon
*tcon
, char *fileName
,
5967 __u16 dos_attrs
, const struct nls_table
*nls_codepage
)
5969 SETATTR_REQ
*pSMB
= NULL
;
5970 SETATTR_RSP
*pSMBr
= NULL
;
5975 cifs_dbg(FYI
, "In SetAttrLegacy\n");
5978 rc
= smb_init(SMB_COM_SETATTR
, 8, tcon
, (void **) &pSMB
,
5983 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5985 ConvertToUTF16((__le16
*) pSMB
->fileName
, fileName
,
5986 PATH_MAX
, nls_codepage
);
5987 name_len
++; /* trailing null */
5990 name_len
= copy_path_name(pSMB
->fileName
, fileName
);
5992 pSMB
->attr
= cpu_to_le16(dos_attrs
);
5993 pSMB
->BufferFormat
= 0x04;
5994 inc_rfc1001_len(pSMB
, name_len
+ 1);
5995 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
5996 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5997 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5999 cifs_dbg(FYI
, "Error in LegacySetAttr = %d\n", rc
);
6001 cifs_buf_release(pSMB
);
6004 goto SetAttrLgcyRetry
;
6008 #endif /* temporarily unneeded SetAttr legacy function */
6011 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO
*data_offset
,
6012 const struct cifs_unix_set_info_args
*args
)
6014 u64 uid
= NO_CHANGE_64
, gid
= NO_CHANGE_64
;
6015 u64 mode
= args
->mode
;
6017 if (uid_valid(args
->uid
))
6018 uid
= from_kuid(&init_user_ns
, args
->uid
);
6019 if (gid_valid(args
->gid
))
6020 gid
= from_kgid(&init_user_ns
, args
->gid
);
6023 * Samba server ignores set of file size to zero due to bugs in some
6024 * older clients, but we should be precise - we use SetFileSize to
6025 * set file size and do not want to truncate file size to zero
6026 * accidentally as happened on one Samba server beta by putting
6027 * zero instead of -1 here
6029 data_offset
->EndOfFile
= cpu_to_le64(NO_CHANGE_64
);
6030 data_offset
->NumOfBytes
= cpu_to_le64(NO_CHANGE_64
);
6031 data_offset
->LastStatusChange
= cpu_to_le64(args
->ctime
);
6032 data_offset
->LastAccessTime
= cpu_to_le64(args
->atime
);
6033 data_offset
->LastModificationTime
= cpu_to_le64(args
->mtime
);
6034 data_offset
->Uid
= cpu_to_le64(uid
);
6035 data_offset
->Gid
= cpu_to_le64(gid
);
6036 /* better to leave device as zero when it is */
6037 data_offset
->DevMajor
= cpu_to_le64(MAJOR(args
->device
));
6038 data_offset
->DevMinor
= cpu_to_le64(MINOR(args
->device
));
6039 data_offset
->Permissions
= cpu_to_le64(mode
);
6042 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
6043 else if (S_ISDIR(mode
))
6044 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
6045 else if (S_ISLNK(mode
))
6046 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
6047 else if (S_ISCHR(mode
))
6048 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
6049 else if (S_ISBLK(mode
))
6050 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
6051 else if (S_ISFIFO(mode
))
6052 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
6053 else if (S_ISSOCK(mode
))
6054 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
6058 CIFSSMBUnixSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6059 const struct cifs_unix_set_info_args
*args
,
6060 u16 fid
, u32 pid_of_opener
)
6062 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
6065 u16 params
, param_offset
, offset
, byte_count
, count
;
6067 cifs_dbg(FYI
, "Set Unix Info (via SetFileInfo)\n");
6068 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
6073 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
6074 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
6077 pSMB
->MaxSetupCount
= 0;
6081 pSMB
->Reserved2
= 0;
6082 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
6083 offset
= param_offset
+ params
;
6085 data_offset
= (char *)pSMB
+
6086 offsetof(struct smb_hdr
, Protocol
) + offset
;
6088 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6090 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6091 /* BB find max SMB PDU from sess */
6092 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6093 pSMB
->SetupCount
= 1;
6094 pSMB
->Reserved3
= 0;
6095 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
6096 byte_count
= 3 /* pad */ + params
+ count
;
6097 pSMB
->DataCount
= cpu_to_le16(count
);
6098 pSMB
->ParameterCount
= cpu_to_le16(params
);
6099 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6100 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6101 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6102 pSMB
->DataOffset
= cpu_to_le16(offset
);
6104 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6105 pSMB
->Reserved4
= 0;
6106 inc_rfc1001_len(pSMB
, byte_count
);
6107 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6109 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO
*)data_offset
, args
);
6111 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
6112 cifs_small_buf_release(pSMB
);
6114 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
6117 /* Note: On -EAGAIN error only caller can retry on handle based calls
6118 since file handle passed in no longer valid */
6124 CIFSSMBUnixSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6125 const char *file_name
,
6126 const struct cifs_unix_set_info_args
*args
,
6127 const struct nls_table
*nls_codepage
, int remap
)
6129 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
6130 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
6133 int bytes_returned
= 0;
6134 FILE_UNIX_BASIC_INFO
*data_offset
;
6135 __u16 params
, param_offset
, offset
, count
, byte_count
;
6137 cifs_dbg(FYI
, "In SetUID/GID/Mode\n");
6139 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6144 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6146 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
6147 PATH_MAX
, nls_codepage
, remap
);
6148 name_len
++; /* trailing null */
6151 name_len
= copy_path_name(pSMB
->FileName
, file_name
);
6154 params
= 6 + name_len
;
6155 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6156 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6157 /* BB find max SMB PDU from sess structure BB */
6158 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6159 pSMB
->MaxSetupCount
= 0;
6163 pSMB
->Reserved2
= 0;
6164 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6165 InformationLevel
) - 4;
6166 offset
= param_offset
+ params
;
6168 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
6170 memset(data_offset
, 0, count
);
6171 pSMB
->DataOffset
= cpu_to_le16(offset
);
6172 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6173 pSMB
->SetupCount
= 1;
6174 pSMB
->Reserved3
= 0;
6175 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6176 byte_count
= 3 /* pad */ + params
+ count
;
6177 pSMB
->ParameterCount
= cpu_to_le16(params
);
6178 pSMB
->DataCount
= cpu_to_le16(count
);
6179 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6180 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6181 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6182 pSMB
->Reserved4
= 0;
6183 inc_rfc1001_len(pSMB
, byte_count
);
6185 cifs_fill_unix_set_info(data_offset
, args
);
6187 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6188 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6189 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6191 cifs_dbg(FYI
, "SetPathInfo (perms) returned %d\n", rc
);
6193 cifs_buf_release(pSMB
);
6199 #ifdef CONFIG_CIFS_XATTR
6201 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6202 * function used by listxattr and getxattr type calls. When ea_name is set,
6203 * it looks for that attribute name and stuffs that value into the EAData
6204 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6205 * buffer. In both cases, the return value is either the length of the
6206 * resulting data or a negative error code. If EAData is a NULL pointer then
6207 * the data isn't copied to it, but the length is returned.
6210 CIFSSMBQAllEAs(const unsigned int xid
, struct cifs_tcon
*tcon
,
6211 const unsigned char *searchName
, const unsigned char *ea_name
,
6212 char *EAData
, size_t buf_size
,
6213 struct cifs_sb_info
*cifs_sb
)
6215 /* BB assumes one setup word */
6216 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
6217 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
6218 int remap
= cifs_remap(cifs_sb
);
6219 struct nls_table
*nls_codepage
= cifs_sb
->local_nls
;
6223 struct fealist
*ea_response_data
;
6224 struct fea
*temp_fea
;
6227 __u16 params
, byte_count
, data_offset
;
6228 unsigned int ea_name_len
= ea_name
? strlen(ea_name
) : 0;
6230 cifs_dbg(FYI
, "In Query All EAs path %s\n", searchName
);
6232 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6237 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6239 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
6240 PATH_MAX
, nls_codepage
, remap
);
6241 list_len
++; /* trailing null */
6244 list_len
= copy_path_name(pSMB
->FileName
, searchName
);
6247 params
= 2 /* level */ + 4 /* reserved */ + list_len
/* includes NUL */;
6248 pSMB
->TotalDataCount
= 0;
6249 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6250 /* BB find exact max SMB PDU from sess structure BB */
6251 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
6252 pSMB
->MaxSetupCount
= 0;
6256 pSMB
->Reserved2
= 0;
6257 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
6258 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
6259 pSMB
->DataCount
= 0;
6260 pSMB
->DataOffset
= 0;
6261 pSMB
->SetupCount
= 1;
6262 pSMB
->Reserved3
= 0;
6263 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
6264 byte_count
= params
+ 1 /* pad */ ;
6265 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
6266 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6267 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
6268 pSMB
->Reserved4
= 0;
6269 inc_rfc1001_len(pSMB
, byte_count
);
6270 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6272 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6273 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6275 cifs_dbg(FYI
, "Send error in QueryAllEAs = %d\n", rc
);
6280 /* BB also check enough total bytes returned */
6281 /* BB we need to improve the validity checking
6282 of these trans2 responses */
6284 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
6285 if (rc
|| get_bcc(&pSMBr
->hdr
) < 4) {
6286 rc
= -EIO
; /* bad smb */
6290 /* check that length of list is not more than bcc */
6291 /* check that each entry does not go beyond length
6293 /* check that each element of each entry does not
6294 go beyond end of list */
6295 /* validate_trans2_offsets() */
6296 /* BB check if start of smb + data_offset > &bcc+ bcc */
6298 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
6299 ea_response_data
= (struct fealist
*)
6300 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
6302 list_len
= le32_to_cpu(ea_response_data
->list_len
);
6303 cifs_dbg(FYI
, "ea length %d\n", list_len
);
6304 if (list_len
<= 8) {
6305 cifs_dbg(FYI
, "empty EA list returned from server\n");
6306 /* didn't find the named attribute */
6312 /* make sure list_len doesn't go past end of SMB */
6313 end_of_smb
= (char *)pByteArea(&pSMBr
->hdr
) + get_bcc(&pSMBr
->hdr
);
6314 if ((char *)ea_response_data
+ list_len
> end_of_smb
) {
6315 cifs_dbg(FYI
, "EA list appears to go beyond SMB\n");
6320 /* account for ea list len */
6322 temp_fea
= ea_response_data
->list
;
6323 temp_ptr
= (char *)temp_fea
;
6324 while (list_len
> 0) {
6325 unsigned int name_len
;
6330 /* make sure we can read name_len and value_len */
6332 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6337 name_len
= temp_fea
->name_len
;
6338 value_len
= le16_to_cpu(temp_fea
->value_len
);
6339 list_len
-= name_len
+ 1 + value_len
;
6341 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6347 if (ea_name_len
== name_len
&&
6348 memcmp(ea_name
, temp_ptr
, name_len
) == 0) {
6349 temp_ptr
+= name_len
+ 1;
6353 if ((size_t)value_len
> buf_size
) {
6357 memcpy(EAData
, temp_ptr
, value_len
);
6361 /* account for prefix user. and trailing null */
6362 rc
+= (5 + 1 + name_len
);
6363 if (rc
< (int) buf_size
) {
6364 memcpy(EAData
, "user.", 5);
6366 memcpy(EAData
, temp_ptr
, name_len
);
6368 /* null terminate name */
6371 } else if (buf_size
== 0) {
6372 /* skip copy - calc size only */
6374 /* stop before overrun buffer */
6379 temp_ptr
+= name_len
+ 1 + value_len
;
6380 temp_fea
= (struct fea
*)temp_ptr
;
6383 /* didn't find the named attribute */
6388 cifs_buf_release(pSMB
);
6396 CIFSSMBSetEA(const unsigned int xid
, struct cifs_tcon
*tcon
,
6397 const char *fileName
, const char *ea_name
, const void *ea_value
,
6398 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
,
6399 struct cifs_sb_info
*cifs_sb
)
6401 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
6402 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
6403 struct fealist
*parm_data
;
6406 int bytes_returned
= 0;
6407 __u16 params
, param_offset
, byte_count
, offset
, count
;
6408 int remap
= cifs_remap(cifs_sb
);
6410 cifs_dbg(FYI
, "In SetEA\n");
6412 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6417 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6419 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
6420 PATH_MAX
, nls_codepage
, remap
);
6421 name_len
++; /* trailing null */
6424 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
6427 params
= 6 + name_len
;
6429 /* done calculating parms using name_len of file name,
6430 now use name_len to calculate length of ea name
6431 we are going to create in the inode xattrs */
6432 if (ea_name
== NULL
)
6435 name_len
= strnlen(ea_name
, 255);
6437 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
;
6438 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6439 /* BB find max SMB PDU from sess */
6440 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6441 pSMB
->MaxSetupCount
= 0;
6445 pSMB
->Reserved2
= 0;
6446 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6447 InformationLevel
) - 4;
6448 offset
= param_offset
+ params
;
6449 pSMB
->InformationLevel
=
6450 cpu_to_le16(SMB_SET_FILE_EA
);
6452 parm_data
= (void *)pSMB
+ offsetof(struct smb_hdr
, Protocol
) + offset
;
6453 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6454 pSMB
->DataOffset
= cpu_to_le16(offset
);
6455 pSMB
->SetupCount
= 1;
6456 pSMB
->Reserved3
= 0;
6457 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6458 byte_count
= 3 /* pad */ + params
+ count
;
6459 pSMB
->DataCount
= cpu_to_le16(count
);
6460 parm_data
->list_len
= cpu_to_le32(count
);
6461 parm_data
->list
[0].EA_flags
= 0;
6462 /* we checked above that name len is less than 255 */
6463 parm_data
->list
[0].name_len
= (__u8
)name_len
;
6464 /* EA names are always ASCII */
6466 strncpy(parm_data
->list
[0].name
, ea_name
, name_len
);
6467 parm_data
->list
[0].name
[name_len
] = 0;
6468 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
6469 /* caller ensures that ea_value_len is less than 64K but
6470 we need to ensure that it fits within the smb */
6472 /*BB add length check to see if it would fit in
6473 negotiated SMB buffer size BB */
6474 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6476 memcpy(parm_data
->list
[0].name
+name_len
+1,
6477 ea_value
, ea_value_len
);
6479 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6480 pSMB
->ParameterCount
= cpu_to_le16(params
);
6481 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6482 pSMB
->Reserved4
= 0;
6483 inc_rfc1001_len(pSMB
, byte_count
);
6484 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6485 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6486 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6488 cifs_dbg(FYI
, "SetPathInfo (EA) returned %d\n", rc
);
6490 cifs_buf_release(pSMB
);