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"
46 #include "smbdirect.h"
47 #ifdef CONFIG_CIFS_DFS_UPCALL
48 #include "dfs_cache.h"
51 #ifdef CONFIG_CIFS_POSIX
56 #ifdef CONFIG_CIFS_WEAK_PW_HASH
57 {LANMAN_PROT
, "\2LM1.2X002"},
58 {LANMAN2_PROT
, "\2LANMAN2.1"},
59 #endif /* weak password hashing for legacy clients */
60 {CIFS_PROT
, "\2NT LM 0.12"},
61 {POSIX_PROT
, "\2POSIX 2"},
69 #ifdef CONFIG_CIFS_WEAK_PW_HASH
70 {LANMAN_PROT
, "\2LM1.2X002"},
71 {LANMAN2_PROT
, "\2LANMAN2.1"},
72 #endif /* weak password hashing for legacy clients */
73 {CIFS_PROT
, "\2NT LM 0.12"},
78 /* define the number of elements in the cifs dialect array */
79 #ifdef CONFIG_CIFS_POSIX
80 #ifdef CONFIG_CIFS_WEAK_PW_HASH
81 #define CIFS_NUM_PROT 4
83 #define CIFS_NUM_PROT 2
84 #endif /* CIFS_WEAK_PW_HASH */
86 #ifdef CONFIG_CIFS_WEAK_PW_HASH
87 #define CIFS_NUM_PROT 3
89 #define CIFS_NUM_PROT 1
90 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
91 #endif /* CIFS_POSIX */
94 * Mark as invalid, all open files on tree connections since they
95 * were closed when session to server was lost.
98 cifs_mark_open_files_invalid(struct cifs_tcon
*tcon
)
100 struct cifsFileInfo
*open_file
= NULL
;
101 struct list_head
*tmp
;
102 struct list_head
*tmp1
;
104 /* list all files open on tree connection and mark them invalid */
105 spin_lock(&tcon
->open_file_lock
);
106 list_for_each_safe(tmp
, tmp1
, &tcon
->openFileList
) {
107 open_file
= list_entry(tmp
, struct cifsFileInfo
, tlist
);
108 open_file
->invalidHandle
= true;
109 open_file
->oplock_break_cancelled
= true;
111 spin_unlock(&tcon
->open_file_lock
);
113 mutex_lock(&tcon
->crfid
.fid_mutex
);
114 tcon
->crfid
.is_valid
= false;
115 memset(tcon
->crfid
.fid
, 0, sizeof(struct cifs_fid
));
116 mutex_unlock(&tcon
->crfid
.fid_mutex
);
119 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
124 #ifdef CONFIG_CIFS_DFS_UPCALL
125 static int __cifs_reconnect_tcon(const struct nls_table
*nlsc
,
126 struct cifs_tcon
*tcon
)
129 struct dfs_cache_tgt_list tl
;
130 struct dfs_cache_tgt_iterator
*it
= NULL
;
131 char tree
[MAX_TREE_SIZE
+ 1];
132 const char *tcp_host
;
134 const char *dfs_host
;
138 snprintf(tree
, sizeof(tree
), "\\\\%s\\IPC$",
139 tcon
->ses
->server
->hostname
);
140 return CIFSTCon(0, tcon
->ses
, tree
, tcon
, nlsc
);
144 return CIFSTCon(0, tcon
->ses
, tcon
->treeName
, tcon
, nlsc
);
146 rc
= dfs_cache_noreq_find(tcon
->dfs_path
+ 1, NULL
, &tl
);
150 extract_unc_hostname(tcon
->ses
->server
->hostname
, &tcp_host
,
153 for (it
= dfs_cache_get_tgt_iterator(&tl
); it
;
154 it
= dfs_cache_get_next_tgt(&tl
, it
)) {
155 const char *tgt
= dfs_cache_get_tgt_name(it
);
157 extract_unc_hostname(tgt
, &dfs_host
, &dfs_host_len
);
159 if (dfs_host_len
!= tcp_host_len
160 || strncasecmp(dfs_host
, tcp_host
, dfs_host_len
) != 0) {
161 cifs_dbg(FYI
, "%s: skipping %.*s, doesn't match %.*s",
163 (int)dfs_host_len
, dfs_host
,
164 (int)tcp_host_len
, tcp_host
);
168 snprintf(tree
, sizeof(tree
), "\\%s", tgt
);
170 rc
= CIFSTCon(0, tcon
->ses
, tree
, tcon
, nlsc
);
179 rc
= dfs_cache_noreq_update_tgthint(tcon
->dfs_path
+ 1,
184 dfs_cache_free_tgts(&tl
);
188 static inline int __cifs_reconnect_tcon(const struct nls_table
*nlsc
,
189 struct cifs_tcon
*tcon
)
191 return CIFSTCon(0, tcon
->ses
, tcon
->treeName
, tcon
, nlsc
);
195 /* reconnect the socket, tcon, and smb session if needed */
197 cifs_reconnect_tcon(struct cifs_tcon
*tcon
, int smb_command
)
200 struct cifs_ses
*ses
;
201 struct TCP_Server_Info
*server
;
202 struct nls_table
*nls_codepage
;
206 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
207 * tcp and smb session status done differently for those three - in the
214 server
= ses
->server
;
217 * only tree disconnect, open, and write, (and ulogoff which does not
218 * have tcon) are allowed as we start force umount
220 if (tcon
->tidStatus
== CifsExiting
) {
221 if (smb_command
!= SMB_COM_WRITE_ANDX
&&
222 smb_command
!= SMB_COM_OPEN_ANDX
&&
223 smb_command
!= SMB_COM_TREE_DISCONNECT
) {
224 cifs_dbg(FYI
, "can not send cmd %d while umounting\n",
230 retries
= server
->nr_targets
;
233 * Give demultiplex thread up to 10 seconds to each target available for
234 * reconnect -- should be greater than cifs socket timeout which is 7
237 while (server
->tcpStatus
== CifsNeedReconnect
) {
238 rc
= wait_event_interruptible_timeout(server
->response_q
,
239 (server
->tcpStatus
!= CifsNeedReconnect
),
242 cifs_dbg(FYI
, "%s: aborting reconnect due to a received"
243 " signal by the process\n", __func__
);
247 /* are we still trying to reconnect? */
248 if (server
->tcpStatus
!= CifsNeedReconnect
)
255 * on "soft" mounts we wait once. Hard mounts keep
256 * retrying until process is killed or server comes
260 cifs_dbg(FYI
, "gave up waiting on reconnect in smb_init\n");
263 retries
= server
->nr_targets
;
266 if (!ses
->need_reconnect
&& !tcon
->need_reconnect
)
269 nls_codepage
= load_nls_default();
272 * need to prevent multiple threads trying to simultaneously
273 * reconnect the same SMB session
275 mutex_lock(&ses
->session_mutex
);
278 * Recheck after acquire mutex. If another thread is negotiating
279 * and the server never sends an answer the socket will be closed
280 * and tcpStatus set to reconnect.
282 if (server
->tcpStatus
== CifsNeedReconnect
) {
284 mutex_unlock(&ses
->session_mutex
);
288 rc
= cifs_negotiate_protocol(0, ses
);
289 if (rc
== 0 && ses
->need_reconnect
)
290 rc
= cifs_setup_session(0, ses
, nls_codepage
);
292 /* do we need to reconnect tcon? */
293 if (rc
|| !tcon
->need_reconnect
) {
294 mutex_unlock(&ses
->session_mutex
);
298 cifs_mark_open_files_invalid(tcon
);
299 rc
= __cifs_reconnect_tcon(nls_codepage
, tcon
);
300 mutex_unlock(&ses
->session_mutex
);
301 cifs_dbg(FYI
, "reconnect tcon rc = %d\n", rc
);
304 printk_once(KERN_WARNING
"reconnect tcon failed rc = %d\n", rc
);
308 atomic_inc(&tconInfoReconnectCount
);
310 /* tell server Unix caps we support */
311 if (ses
->capabilities
& CAP_UNIX
)
312 reset_cifs_unix_caps(0, tcon
, NULL
, NULL
);
315 * Removed call to reopen open files here. It is safer (and faster) to
316 * reopen files one at a time as needed in read and write.
318 * FIXME: what about file locks? don't we need to reclaim them ASAP?
323 * Check if handle based operation so we know whether we can continue
324 * or not without returning to caller to reset file handle
326 switch (smb_command
) {
327 case SMB_COM_READ_ANDX
:
328 case SMB_COM_WRITE_ANDX
:
330 case SMB_COM_FIND_CLOSE2
:
331 case SMB_COM_LOCKING_ANDX
:
335 unload_nls(nls_codepage
);
339 /* Allocate and return pointer to an SMB request buffer, and set basic
340 SMB information in the SMB header. If the return code is zero, this
341 function must have filled in request_buf pointer */
343 small_smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
348 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
352 *request_buf
= cifs_small_buf_get();
353 if (*request_buf
== NULL
) {
354 /* BB should we add a retry in here if not a writepage? */
358 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
,
362 cifs_stats_inc(&tcon
->num_smbs_sent
);
368 small_smb_init_no_tc(const int smb_command
, const int wct
,
369 struct cifs_ses
*ses
, void **request_buf
)
372 struct smb_hdr
*buffer
;
374 rc
= small_smb_init(smb_command
, wct
, NULL
, request_buf
);
378 buffer
= (struct smb_hdr
*)*request_buf
;
379 buffer
->Mid
= get_next_mid(ses
->server
);
380 if (ses
->capabilities
& CAP_UNICODE
)
381 buffer
->Flags2
|= SMBFLG2_UNICODE
;
382 if (ses
->capabilities
& CAP_STATUS32
)
383 buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
385 /* uid, tid can stay at zero as set in header assemble */
387 /* BB add support for turning on the signing when
388 this function is used after 1st of session setup requests */
393 /* If the return code is zero, this function must fill in request_buf pointer */
395 __smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
396 void **request_buf
, void **response_buf
)
398 *request_buf
= cifs_buf_get();
399 if (*request_buf
== NULL
) {
400 /* BB should we add a retry in here if not a writepage? */
403 /* Although the original thought was we needed the response buf for */
404 /* potential retries of smb operations it turns out we can determine */
405 /* from the mid flags when the request buffer can be resent without */
406 /* having to use a second distinct buffer for the response */
408 *response_buf
= *request_buf
;
410 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
, tcon
,
414 cifs_stats_inc(&tcon
->num_smbs_sent
);
419 /* If the return code is zero, this function must fill in request_buf pointer */
421 smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
422 void **request_buf
, void **response_buf
)
426 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
430 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
434 smb_init_no_reconnect(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
435 void **request_buf
, void **response_buf
)
437 if (tcon
->ses
->need_reconnect
|| tcon
->need_reconnect
)
440 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
443 static int validate_t2(struct smb_t2_rsp
*pSMB
)
445 unsigned int total_size
;
447 /* check for plausible wct */
448 if (pSMB
->hdr
.WordCount
< 10)
451 /* check for parm and data offset going beyond end of smb */
452 if (get_unaligned_le16(&pSMB
->t2_rsp
.ParameterOffset
) > 1024 ||
453 get_unaligned_le16(&pSMB
->t2_rsp
.DataOffset
) > 1024)
456 total_size
= get_unaligned_le16(&pSMB
->t2_rsp
.ParameterCount
);
457 if (total_size
>= 512)
460 /* check that bcc is at least as big as parms + data, and that it is
461 * less than negotiated smb buffer
463 total_size
+= get_unaligned_le16(&pSMB
->t2_rsp
.DataCount
);
464 if (total_size
> get_bcc(&pSMB
->hdr
) ||
465 total_size
>= CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
)
470 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB
,
471 sizeof(struct smb_t2_rsp
) + 16);
476 decode_ext_sec_blob(struct cifs_ses
*ses
, NEGOTIATE_RSP
*pSMBr
)
480 char *guid
= pSMBr
->u
.extended_response
.GUID
;
481 struct TCP_Server_Info
*server
= ses
->server
;
483 count
= get_bcc(&pSMBr
->hdr
);
484 if (count
< SMB1_CLIENT_GUID_SIZE
)
487 spin_lock(&cifs_tcp_ses_lock
);
488 if (server
->srv_count
> 1) {
489 spin_unlock(&cifs_tcp_ses_lock
);
490 if (memcmp(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
) != 0) {
491 cifs_dbg(FYI
, "server UID changed\n");
492 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
495 spin_unlock(&cifs_tcp_ses_lock
);
496 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
499 if (count
== SMB1_CLIENT_GUID_SIZE
) {
500 server
->sec_ntlmssp
= true;
502 count
-= SMB1_CLIENT_GUID_SIZE
;
503 rc
= decode_negTokenInit(
504 pSMBr
->u
.extended_response
.SecurityBlob
, count
, server
);
513 cifs_enable_signing(struct TCP_Server_Info
*server
, bool mnt_sign_required
)
515 bool srv_sign_required
= server
->sec_mode
& server
->vals
->signing_required
;
516 bool srv_sign_enabled
= server
->sec_mode
& server
->vals
->signing_enabled
;
517 bool mnt_sign_enabled
= global_secflags
& CIFSSEC_MAY_SIGN
;
520 * Is signing required by mnt options? If not then check
521 * global_secflags to see if it is there.
523 if (!mnt_sign_required
)
524 mnt_sign_required
= ((global_secflags
& CIFSSEC_MUST_SIGN
) ==
528 * If signing is required then it's automatically enabled too,
529 * otherwise, check to see if the secflags allow it.
531 mnt_sign_enabled
= mnt_sign_required
? mnt_sign_required
:
532 (global_secflags
& CIFSSEC_MAY_SIGN
);
534 /* If server requires signing, does client allow it? */
535 if (srv_sign_required
) {
536 if (!mnt_sign_enabled
) {
537 cifs_dbg(VFS
, "Server requires signing, but it's disabled in SecurityFlags!");
543 /* If client requires signing, does server allow it? */
544 if (mnt_sign_required
) {
545 if (!srv_sign_enabled
) {
546 cifs_dbg(VFS
, "Server does not support signing!");
552 if (cifs_rdma_enabled(server
) && server
->sign
)
553 cifs_dbg(VFS
, "Signing is enabled, and RDMA read/write will be disabled");
558 #ifdef CONFIG_CIFS_WEAK_PW_HASH
560 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
563 struct lanman_neg_rsp
*rsp
= (struct lanman_neg_rsp
*)pSMBr
;
565 if (server
->dialect
!= LANMAN_PROT
&& server
->dialect
!= LANMAN2_PROT
)
568 server
->sec_mode
= le16_to_cpu(rsp
->SecurityMode
);
569 server
->maxReq
= min_t(unsigned int,
570 le16_to_cpu(rsp
->MaxMpxCount
),
572 set_credits(server
, server
->maxReq
);
573 server
->maxBuf
= le16_to_cpu(rsp
->MaxBufSize
);
574 /* even though we do not use raw we might as well set this
575 accurately, in case we ever find a need for it */
576 if ((le16_to_cpu(rsp
->RawMode
) & RAW_ENABLE
) == RAW_ENABLE
) {
577 server
->max_rw
= 0xFF00;
578 server
->capabilities
= CAP_MPX_MODE
| CAP_RAW_MODE
;
580 server
->max_rw
= 0;/* do not need to use raw anyway */
581 server
->capabilities
= CAP_MPX_MODE
;
583 tmp
= (__s16
)le16_to_cpu(rsp
->ServerTimeZone
);
585 /* OS/2 often does not set timezone therefore
586 * we must use server time to calc time zone.
587 * Could deviate slightly from the right zone.
588 * Smallest defined timezone difference is 15 minutes
589 * (i.e. Nepal). Rounding up/down is done to match
592 int val
, seconds
, remain
, result
;
593 struct timespec64 ts
;
594 time64_t utc
= ktime_get_real_seconds();
595 ts
= cnvrtDosUnixTm(rsp
->SrvTime
.Date
,
596 rsp
->SrvTime
.Time
, 0);
597 cifs_dbg(FYI
, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n",
600 val
= (int)(utc
- ts
.tv_sec
);
602 result
= (seconds
/ MIN_TZ_ADJ
) * MIN_TZ_ADJ
;
603 remain
= seconds
% MIN_TZ_ADJ
;
604 if (remain
>= (MIN_TZ_ADJ
/ 2))
605 result
+= MIN_TZ_ADJ
;
608 server
->timeAdj
= result
;
610 server
->timeAdj
= (int)tmp
;
611 server
->timeAdj
*= 60; /* also in seconds */
613 cifs_dbg(FYI
, "server->timeAdj: %d seconds\n", server
->timeAdj
);
616 /* BB get server time for time conversions and add
617 code to use it and timezone since this is not UTC */
619 if (rsp
->EncryptionKeyLength
==
620 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE
)) {
621 memcpy(server
->cryptkey
, rsp
->EncryptionKey
,
622 CIFS_CRYPTO_KEY_SIZE
);
623 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
624 return -EIO
; /* need cryptkey unless plain text */
627 cifs_dbg(FYI
, "LANMAN negotiated\n");
632 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
634 cifs_dbg(VFS
, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
640 should_set_ext_sec_flag(enum securityEnum sectype
)
647 if (global_secflags
&
648 (CIFSSEC_MAY_KRB5
| CIFSSEC_MAY_NTLMSSP
))
657 CIFSSMBNegotiate(const unsigned int xid
, struct cifs_ses
*ses
)
660 NEGOTIATE_RSP
*pSMBr
;
664 struct TCP_Server_Info
*server
= ses
->server
;
668 WARN(1, "%s: server is NULL!\n", __func__
);
672 rc
= smb_init(SMB_COM_NEGOTIATE
, 0, NULL
/* no tcon yet */ ,
673 (void **) &pSMB
, (void **) &pSMBr
);
677 pSMB
->hdr
.Mid
= get_next_mid(server
);
678 pSMB
->hdr
.Flags2
|= (SMBFLG2_UNICODE
| SMBFLG2_ERR_STATUS
);
680 if (should_set_ext_sec_flag(ses
->sectype
)) {
681 cifs_dbg(FYI
, "Requesting extended security.");
682 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
687 * We know that all the name entries in the protocols array
688 * are short (< 16 bytes anyway) and are NUL terminated.
690 for (i
= 0; i
< CIFS_NUM_PROT
; i
++) {
691 size_t len
= strlen(protocols
[i
].name
) + 1;
693 memcpy(pSMB
->DialectsArray
+count
, protocols
[i
].name
, len
);
696 inc_rfc1001_len(pSMB
, count
);
697 pSMB
->ByteCount
= cpu_to_le16(count
);
699 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
700 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
704 server
->dialect
= le16_to_cpu(pSMBr
->DialectIndex
);
705 cifs_dbg(FYI
, "Dialect: %d\n", server
->dialect
);
706 /* Check wct = 1 error case */
707 if ((pSMBr
->hdr
.WordCount
< 13) || (server
->dialect
== BAD_PROT
)) {
708 /* core returns wct = 1, but we do not ask for core - otherwise
709 small wct just comes when dialect index is -1 indicating we
710 could not negotiate a common dialect */
713 } else if (pSMBr
->hdr
.WordCount
== 13) {
714 server
->negflavor
= CIFS_NEGFLAVOR_LANMAN
;
715 rc
= decode_lanman_negprot_rsp(server
, pSMBr
);
717 } else if (pSMBr
->hdr
.WordCount
!= 17) {
722 /* else wct == 17, NTLM or better */
724 server
->sec_mode
= pSMBr
->SecurityMode
;
725 if ((server
->sec_mode
& SECMODE_USER
) == 0)
726 cifs_dbg(FYI
, "share mode security\n");
728 /* one byte, so no need to convert this or EncryptionKeyLen from
730 server
->maxReq
= min_t(unsigned int, le16_to_cpu(pSMBr
->MaxMpxCount
),
732 set_credits(server
, server
->maxReq
);
733 /* probably no need to store and check maxvcs */
734 server
->maxBuf
= le32_to_cpu(pSMBr
->MaxBufferSize
);
735 server
->max_rw
= le32_to_cpu(pSMBr
->MaxRawSize
);
736 cifs_dbg(NOISY
, "Max buf = %d\n", ses
->server
->maxBuf
);
737 server
->capabilities
= le32_to_cpu(pSMBr
->Capabilities
);
738 server
->timeAdj
= (int)(__s16
)le16_to_cpu(pSMBr
->ServerTimeZone
);
739 server
->timeAdj
*= 60;
741 if (pSMBr
->EncryptionKeyLength
== CIFS_CRYPTO_KEY_SIZE
) {
742 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
743 memcpy(ses
->server
->cryptkey
, pSMBr
->u
.EncryptionKey
,
744 CIFS_CRYPTO_KEY_SIZE
);
745 } else if (pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
||
746 server
->capabilities
& CAP_EXTENDED_SECURITY
) {
747 server
->negflavor
= CIFS_NEGFLAVOR_EXTENDED
;
748 rc
= decode_ext_sec_blob(ses
, pSMBr
);
749 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
750 rc
= -EIO
; /* no crypt key only if plain text pwd */
752 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
753 server
->capabilities
&= ~CAP_EXTENDED_SECURITY
;
758 rc
= cifs_enable_signing(server
, ses
->sign
);
760 cifs_buf_release(pSMB
);
762 cifs_dbg(FYI
, "negprot rc %d\n", rc
);
767 CIFSSMBTDis(const unsigned int xid
, struct cifs_tcon
*tcon
)
769 struct smb_hdr
*smb_buffer
;
772 cifs_dbg(FYI
, "In tree disconnect\n");
774 /* BB: do we need to check this? These should never be NULL. */
775 if ((tcon
->ses
== NULL
) || (tcon
->ses
->server
== NULL
))
779 * No need to return error on this operation if tid invalidated and
780 * closed on server already e.g. due to tcp session crashing. Also,
781 * the tcon is no longer on the list, so no need to take lock before
784 if ((tcon
->need_reconnect
) || (tcon
->ses
->need_reconnect
))
787 rc
= small_smb_init(SMB_COM_TREE_DISCONNECT
, 0, tcon
,
788 (void **)&smb_buffer
);
792 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)smb_buffer
, 0);
793 cifs_small_buf_release(smb_buffer
);
795 cifs_dbg(FYI
, "Tree disconnect failed %d\n", rc
);
797 /* No need to return error on this operation if tid invalidated and
798 closed on server already e.g. due to tcp session crashing */
806 * This is a no-op for now. We're not really interested in the reply, but
807 * rather in the fact that the server sent one and that server->lstrp
810 * FIXME: maybe we should consider checking that the reply matches request?
813 cifs_echo_callback(struct mid_q_entry
*mid
)
815 struct TCP_Server_Info
*server
= mid
->callback_data
;
817 DeleteMidQEntry(mid
);
818 add_credits(server
, 1, CIFS_ECHO_OP
);
822 CIFSSMBEcho(struct TCP_Server_Info
*server
)
827 struct smb_rqst rqst
= { .rq_iov
= iov
,
830 cifs_dbg(FYI
, "In echo request\n");
832 rc
= small_smb_init(SMB_COM_ECHO
, 0, NULL
, (void **)&smb
);
836 if (server
->capabilities
& CAP_UNICODE
)
837 smb
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
839 /* set up echo request */
840 smb
->hdr
.Tid
= 0xffff;
841 smb
->hdr
.WordCount
= 1;
842 put_unaligned_le16(1, &smb
->EchoCount
);
843 put_bcc(1, &smb
->hdr
);
845 inc_rfc1001_len(smb
, 3);
848 iov
[0].iov_base
= smb
;
849 iov
[1].iov_len
= get_rfc1002_length(smb
);
850 iov
[1].iov_base
= (char *)smb
+ 4;
852 rc
= cifs_call_async(server
, &rqst
, NULL
, cifs_echo_callback
, NULL
,
853 server
, CIFS_ASYNC_OP
| CIFS_ECHO_OP
);
855 cifs_dbg(FYI
, "Echo request failed: %d\n", rc
);
857 cifs_small_buf_release(smb
);
863 CIFSSMBLogoff(const unsigned int xid
, struct cifs_ses
*ses
)
865 LOGOFF_ANDX_REQ
*pSMB
;
868 cifs_dbg(FYI
, "In SMBLogoff for session disconnect\n");
871 * BB: do we need to check validity of ses and server? They should
872 * always be valid since we have an active reference. If not, that
873 * should probably be a BUG()
875 if (!ses
|| !ses
->server
)
878 mutex_lock(&ses
->session_mutex
);
879 if (ses
->need_reconnect
)
880 goto session_already_dead
; /* no need to send SMBlogoff if uid
881 already closed due to reconnect */
882 rc
= small_smb_init(SMB_COM_LOGOFF_ANDX
, 2, NULL
, (void **)&pSMB
);
884 mutex_unlock(&ses
->session_mutex
);
888 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
890 if (ses
->server
->sign
)
891 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
893 pSMB
->hdr
.Uid
= ses
->Suid
;
895 pSMB
->AndXCommand
= 0xFF;
896 rc
= SendReceiveNoRsp(xid
, ses
, (char *) pSMB
, 0);
897 cifs_small_buf_release(pSMB
);
898 session_already_dead
:
899 mutex_unlock(&ses
->session_mutex
);
901 /* if session dead then we do not need to do ulogoff,
902 since server closed smb session, no sense reporting
910 CIFSPOSIXDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
,
911 const char *fileName
, __u16 type
,
912 const struct nls_table
*nls_codepage
, int remap
)
914 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
915 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
916 struct unlink_psx_rq
*pRqD
;
919 int bytes_returned
= 0;
920 __u16 params
, param_offset
, offset
, byte_count
;
922 cifs_dbg(FYI
, "In POSIX delete\n");
924 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
929 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
931 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
932 PATH_MAX
, nls_codepage
, remap
);
933 name_len
++; /* trailing null */
935 } else { /* BB add path length overrun check */
936 name_len
= strnlen(fileName
, PATH_MAX
);
937 name_len
++; /* trailing null */
938 strncpy(pSMB
->FileName
, fileName
, name_len
);
941 params
= 6 + name_len
;
942 pSMB
->MaxParameterCount
= cpu_to_le16(2);
943 pSMB
->MaxDataCount
= 0; /* BB double check this with jra */
944 pSMB
->MaxSetupCount
= 0;
949 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
950 InformationLevel
) - 4;
951 offset
= param_offset
+ params
;
953 /* Setup pointer to Request Data (inode type) */
954 pRqD
= (struct unlink_psx_rq
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
955 pRqD
->type
= cpu_to_le16(type
);
956 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
957 pSMB
->DataOffset
= cpu_to_le16(offset
);
958 pSMB
->SetupCount
= 1;
960 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
961 byte_count
= 3 /* pad */ + params
+ sizeof(struct unlink_psx_rq
);
963 pSMB
->DataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
964 pSMB
->TotalDataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
965 pSMB
->ParameterCount
= cpu_to_le16(params
);
966 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
967 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_UNLINK
);
969 inc_rfc1001_len(pSMB
, byte_count
);
970 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
971 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
972 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
974 cifs_dbg(FYI
, "Posix delete returned %d\n", rc
);
975 cifs_buf_release(pSMB
);
977 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
986 CIFSSMBDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
987 struct cifs_sb_info
*cifs_sb
)
989 DELETE_FILE_REQ
*pSMB
= NULL
;
990 DELETE_FILE_RSP
*pSMBr
= NULL
;
994 int remap
= cifs_remap(cifs_sb
);
997 rc
= smb_init(SMB_COM_DELETE
, 1, tcon
, (void **) &pSMB
,
1002 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1003 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->fileName
, name
,
1004 PATH_MAX
, cifs_sb
->local_nls
,
1006 name_len
++; /* trailing null */
1008 } else { /* BB improve check for buffer overruns BB */
1009 name_len
= strnlen(name
, PATH_MAX
);
1010 name_len
++; /* trailing null */
1011 strncpy(pSMB
->fileName
, name
, name_len
);
1013 pSMB
->SearchAttributes
=
1014 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
);
1015 pSMB
->BufferFormat
= 0x04;
1016 inc_rfc1001_len(pSMB
, name_len
+ 1);
1017 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1018 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1019 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1020 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
1022 cifs_dbg(FYI
, "Error in RMFile = %d\n", rc
);
1024 cifs_buf_release(pSMB
);
1032 CIFSSMBRmDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
1033 struct cifs_sb_info
*cifs_sb
)
1035 DELETE_DIRECTORY_REQ
*pSMB
= NULL
;
1036 DELETE_DIRECTORY_RSP
*pSMBr
= NULL
;
1040 int remap
= cifs_remap(cifs_sb
);
1042 cifs_dbg(FYI
, "In CIFSSMBRmDir\n");
1044 rc
= smb_init(SMB_COM_DELETE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
1049 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1050 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
1051 PATH_MAX
, cifs_sb
->local_nls
,
1053 name_len
++; /* trailing null */
1055 } else { /* BB improve check for buffer overruns BB */
1056 name_len
= strnlen(name
, PATH_MAX
);
1057 name_len
++; /* trailing null */
1058 strncpy(pSMB
->DirName
, name
, name_len
);
1061 pSMB
->BufferFormat
= 0x04;
1062 inc_rfc1001_len(pSMB
, name_len
+ 1);
1063 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1064 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1065 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1066 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_rmdirs
);
1068 cifs_dbg(FYI
, "Error in RMDir = %d\n", rc
);
1070 cifs_buf_release(pSMB
);
1077 CIFSSMBMkDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
1078 struct cifs_sb_info
*cifs_sb
)
1081 CREATE_DIRECTORY_REQ
*pSMB
= NULL
;
1082 CREATE_DIRECTORY_RSP
*pSMBr
= NULL
;
1085 int remap
= cifs_remap(cifs_sb
);
1087 cifs_dbg(FYI
, "In CIFSSMBMkDir\n");
1089 rc
= smb_init(SMB_COM_CREATE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
1094 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1095 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
1096 PATH_MAX
, cifs_sb
->local_nls
,
1098 name_len
++; /* trailing null */
1100 } else { /* BB improve check for buffer overruns BB */
1101 name_len
= strnlen(name
, PATH_MAX
);
1102 name_len
++; /* trailing null */
1103 strncpy(pSMB
->DirName
, name
, name_len
);
1106 pSMB
->BufferFormat
= 0x04;
1107 inc_rfc1001_len(pSMB
, name_len
+ 1);
1108 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1109 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1110 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1111 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_mkdirs
);
1113 cifs_dbg(FYI
, "Error in Mkdir = %d\n", rc
);
1115 cifs_buf_release(pSMB
);
1122 CIFSPOSIXCreate(const unsigned int xid
, struct cifs_tcon
*tcon
,
1123 __u32 posix_flags
, __u64 mode
, __u16
*netfid
,
1124 FILE_UNIX_BASIC_INFO
*pRetData
, __u32
*pOplock
,
1125 const char *name
, const struct nls_table
*nls_codepage
,
1128 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
1129 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
1132 int bytes_returned
= 0;
1133 __u16 params
, param_offset
, offset
, byte_count
, count
;
1134 OPEN_PSX_REQ
*pdata
;
1135 OPEN_PSX_RSP
*psx_rsp
;
1137 cifs_dbg(FYI
, "In POSIX Create\n");
1139 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1144 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1146 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, name
,
1147 PATH_MAX
, nls_codepage
, remap
);
1148 name_len
++; /* trailing null */
1150 } else { /* BB improve the check for buffer overruns BB */
1151 name_len
= strnlen(name
, PATH_MAX
);
1152 name_len
++; /* trailing null */
1153 strncpy(pSMB
->FileName
, name
, name_len
);
1156 params
= 6 + name_len
;
1157 count
= sizeof(OPEN_PSX_REQ
);
1158 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1159 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* large enough */
1160 pSMB
->MaxSetupCount
= 0;
1164 pSMB
->Reserved2
= 0;
1165 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
1166 InformationLevel
) - 4;
1167 offset
= param_offset
+ params
;
1168 pdata
= (OPEN_PSX_REQ
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
1169 pdata
->Level
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
1170 pdata
->Permissions
= cpu_to_le64(mode
);
1171 pdata
->PosixOpenFlags
= cpu_to_le32(posix_flags
);
1172 pdata
->OpenFlags
= cpu_to_le32(*pOplock
);
1173 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
1174 pSMB
->DataOffset
= cpu_to_le16(offset
);
1175 pSMB
->SetupCount
= 1;
1176 pSMB
->Reserved3
= 0;
1177 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
1178 byte_count
= 3 /* pad */ + params
+ count
;
1180 pSMB
->DataCount
= cpu_to_le16(count
);
1181 pSMB
->ParameterCount
= cpu_to_le16(params
);
1182 pSMB
->TotalDataCount
= pSMB
->DataCount
;
1183 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1184 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_OPEN
);
1185 pSMB
->Reserved4
= 0;
1186 inc_rfc1001_len(pSMB
, byte_count
);
1187 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1188 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1189 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1191 cifs_dbg(FYI
, "Posix create returned %d\n", rc
);
1192 goto psx_create_err
;
1195 cifs_dbg(FYI
, "copying inode info\n");
1196 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
1198 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)) {
1199 rc
= -EIO
; /* bad smb */
1200 goto psx_create_err
;
1203 /* copy return information to pRetData */
1204 psx_rsp
= (OPEN_PSX_RSP
*)((char *) &pSMBr
->hdr
.Protocol
1205 + le16_to_cpu(pSMBr
->t2
.DataOffset
));
1207 *pOplock
= le16_to_cpu(psx_rsp
->OplockFlags
);
1209 *netfid
= psx_rsp
->Fid
; /* cifs fid stays in le */
1210 /* Let caller know file was created so we can set the mode. */
1211 /* Do we care about the CreateAction in any other cases? */
1212 if (cpu_to_le32(FILE_CREATE
) == psx_rsp
->CreateAction
)
1213 *pOplock
|= CIFS_CREATE_ACTION
;
1214 /* check to make sure response data is there */
1215 if (psx_rsp
->ReturnedLevel
!= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
)) {
1216 pRetData
->Type
= cpu_to_le32(-1); /* unknown */
1217 cifs_dbg(NOISY
, "unknown type\n");
1219 if (get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)
1220 + sizeof(FILE_UNIX_BASIC_INFO
)) {
1221 cifs_dbg(VFS
, "Open response data too small\n");
1222 pRetData
->Type
= cpu_to_le32(-1);
1223 goto psx_create_err
;
1225 memcpy((char *) pRetData
,
1226 (char *)psx_rsp
+ sizeof(OPEN_PSX_RSP
),
1227 sizeof(FILE_UNIX_BASIC_INFO
));
1231 cifs_buf_release(pSMB
);
1233 if (posix_flags
& SMB_O_DIRECTORY
)
1234 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixmkdirs
);
1236 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixopens
);
1244 static __u16
convert_disposition(int disposition
)
1248 switch (disposition
) {
1249 case FILE_SUPERSEDE
:
1250 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1253 ofun
= SMBOPEN_OAPPEND
;
1256 ofun
= SMBOPEN_OCREATE
;
1259 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OAPPEND
;
1261 case FILE_OVERWRITE
:
1262 ofun
= SMBOPEN_OTRUNC
;
1264 case FILE_OVERWRITE_IF
:
1265 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1268 cifs_dbg(FYI
, "unknown disposition %d\n", disposition
);
1269 ofun
= SMBOPEN_OAPPEND
; /* regular open */
1275 access_flags_to_smbopen_mode(const int access_flags
)
1277 int masked_flags
= access_flags
& (GENERIC_READ
| GENERIC_WRITE
);
1279 if (masked_flags
== GENERIC_READ
)
1280 return SMBOPEN_READ
;
1281 else if (masked_flags
== GENERIC_WRITE
)
1282 return SMBOPEN_WRITE
;
1284 /* just go for read/write */
1285 return SMBOPEN_READWRITE
;
1289 SMBLegacyOpen(const unsigned int xid
, struct cifs_tcon
*tcon
,
1290 const char *fileName
, const int openDisposition
,
1291 const int access_flags
, const int create_options
, __u16
*netfid
,
1292 int *pOplock
, FILE_ALL_INFO
*pfile_info
,
1293 const struct nls_table
*nls_codepage
, int remap
)
1296 OPENX_REQ
*pSMB
= NULL
;
1297 OPENX_RSP
*pSMBr
= NULL
;
1303 rc
= smb_init(SMB_COM_OPEN_ANDX
, 15, tcon
, (void **) &pSMB
,
1308 pSMB
->AndXCommand
= 0xFF; /* none */
1310 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1311 count
= 1; /* account for one byte pad to word boundary */
1313 cifsConvertToUTF16((__le16
*) (pSMB
->fileName
+ 1),
1314 fileName
, PATH_MAX
, nls_codepage
, remap
);
1315 name_len
++; /* trailing null */
1317 } else { /* BB improve check for buffer overruns BB */
1318 count
= 0; /* no pad */
1319 name_len
= strnlen(fileName
, PATH_MAX
);
1320 name_len
++; /* trailing null */
1321 strncpy(pSMB
->fileName
, fileName
, name_len
);
1323 if (*pOplock
& REQ_OPLOCK
)
1324 pSMB
->OpenFlags
= cpu_to_le16(REQ_OPLOCK
);
1325 else if (*pOplock
& REQ_BATCHOPLOCK
)
1326 pSMB
->OpenFlags
= cpu_to_le16(REQ_BATCHOPLOCK
);
1328 pSMB
->OpenFlags
|= cpu_to_le16(REQ_MORE_INFO
);
1329 pSMB
->Mode
= cpu_to_le16(access_flags_to_smbopen_mode(access_flags
));
1330 pSMB
->Mode
|= cpu_to_le16(0x40); /* deny none */
1331 /* set file as system file if special file such
1332 as fifo and server expecting SFU style and
1333 no Unix extensions */
1335 if (create_options
& CREATE_OPTION_SPECIAL
)
1336 pSMB
->FileAttributes
= cpu_to_le16(ATTR_SYSTEM
);
1337 else /* BB FIXME BB */
1338 pSMB
->FileAttributes
= cpu_to_le16(0/*ATTR_NORMAL*/);
1340 if (create_options
& CREATE_OPTION_READONLY
)
1341 pSMB
->FileAttributes
|= cpu_to_le16(ATTR_READONLY
);
1344 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1345 CREATE_OPTIONS_MASK); */
1346 /* BB FIXME END BB */
1348 pSMB
->Sattr
= cpu_to_le16(ATTR_HIDDEN
| ATTR_SYSTEM
| ATTR_DIRECTORY
);
1349 pSMB
->OpenFunction
= cpu_to_le16(convert_disposition(openDisposition
));
1351 inc_rfc1001_len(pSMB
, count
);
1353 pSMB
->ByteCount
= cpu_to_le16(count
);
1354 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1355 (struct smb_hdr
*)pSMBr
, &bytes_returned
, 0);
1356 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1358 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1360 /* BB verify if wct == 15 */
1362 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1364 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
1365 /* Let caller know file was created so we can set the mode. */
1366 /* Do we care about the CreateAction in any other cases? */
1368 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1369 *pOplock |= CIFS_CREATE_ACTION; */
1373 pfile_info
->CreationTime
= 0; /* BB convert CreateTime*/
1374 pfile_info
->LastAccessTime
= 0; /* BB fixme */
1375 pfile_info
->LastWriteTime
= 0; /* BB fixme */
1376 pfile_info
->ChangeTime
= 0; /* BB fixme */
1377 pfile_info
->Attributes
=
1378 cpu_to_le32(le16_to_cpu(pSMBr
->FileAttributes
));
1379 /* the file_info buf is endian converted by caller */
1380 pfile_info
->AllocationSize
=
1381 cpu_to_le64(le32_to_cpu(pSMBr
->EndOfFile
));
1382 pfile_info
->EndOfFile
= pfile_info
->AllocationSize
;
1383 pfile_info
->NumberOfLinks
= cpu_to_le32(1);
1384 pfile_info
->DeletePending
= 0;
1388 cifs_buf_release(pSMB
);
1395 CIFS_open(const unsigned int xid
, struct cifs_open_parms
*oparms
, int *oplock
,
1399 OPEN_REQ
*req
= NULL
;
1400 OPEN_RSP
*rsp
= NULL
;
1404 struct cifs_sb_info
*cifs_sb
= oparms
->cifs_sb
;
1405 struct cifs_tcon
*tcon
= oparms
->tcon
;
1406 int remap
= cifs_remap(cifs_sb
);
1407 const struct nls_table
*nls
= cifs_sb
->local_nls
;
1408 int create_options
= oparms
->create_options
;
1409 int desired_access
= oparms
->desired_access
;
1410 int disposition
= oparms
->disposition
;
1411 const char *path
= oparms
->path
;
1414 rc
= smb_init(SMB_COM_NT_CREATE_ANDX
, 24, tcon
, (void **)&req
,
1419 /* no commands go after this */
1420 req
->AndXCommand
= 0xFF;
1422 if (req
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1423 /* account for one byte pad to word boundary */
1425 name_len
= cifsConvertToUTF16((__le16
*)(req
->fileName
+ 1),
1426 path
, PATH_MAX
, nls
, remap
);
1430 req
->NameLength
= cpu_to_le16(name_len
);
1432 /* BB improve check for buffer overruns BB */
1435 name_len
= strnlen(path
, PATH_MAX
);
1438 req
->NameLength
= cpu_to_le16(name_len
);
1439 strncpy(req
->fileName
, path
, name_len
);
1442 if (*oplock
& REQ_OPLOCK
)
1443 req
->OpenFlags
= cpu_to_le32(REQ_OPLOCK
);
1444 else if (*oplock
& REQ_BATCHOPLOCK
)
1445 req
->OpenFlags
= cpu_to_le32(REQ_BATCHOPLOCK
);
1447 req
->DesiredAccess
= cpu_to_le32(desired_access
);
1448 req
->AllocationSize
= 0;
1451 * Set file as system file if special file such as fifo and server
1452 * expecting SFU style and no Unix extensions.
1454 if (create_options
& CREATE_OPTION_SPECIAL
)
1455 req
->FileAttributes
= cpu_to_le32(ATTR_SYSTEM
);
1457 req
->FileAttributes
= cpu_to_le32(ATTR_NORMAL
);
1460 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1461 * sensitive checks for other servers such as Samba.
1463 if (tcon
->ses
->capabilities
& CAP_UNIX
)
1464 req
->FileAttributes
|= cpu_to_le32(ATTR_POSIX_SEMANTICS
);
1466 if (create_options
& CREATE_OPTION_READONLY
)
1467 req
->FileAttributes
|= cpu_to_le32(ATTR_READONLY
);
1469 req
->ShareAccess
= cpu_to_le32(FILE_SHARE_ALL
);
1470 req
->CreateDisposition
= cpu_to_le32(disposition
);
1471 req
->CreateOptions
= cpu_to_le32(create_options
& CREATE_OPTIONS_MASK
);
1473 /* BB Expirement with various impersonation levels and verify */
1474 req
->ImpersonationLevel
= cpu_to_le32(SECURITY_IMPERSONATION
);
1475 req
->SecurityFlags
= SECURITY_CONTEXT_TRACKING
|SECURITY_EFFECTIVE_ONLY
;
1478 inc_rfc1001_len(req
, count
);
1480 req
->ByteCount
= cpu_to_le16(count
);
1481 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*)req
,
1482 (struct smb_hdr
*)rsp
, &bytes_returned
, 0);
1483 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1485 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1486 cifs_buf_release(req
);
1492 /* 1 byte no need to le_to_cpu */
1493 *oplock
= rsp
->OplockLevel
;
1494 /* cifs fid stays in le */
1495 oparms
->fid
->netfid
= rsp
->Fid
;
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
)
1546 struct cifs_readdata
*rdata
= mid
->callback_data
;
1548 length
= cifs_discard_remaining_data(server
);
1549 dequeue_mid(mid
, rdata
->result
);
1550 mid
->resp_buf
= server
->smallbuf
;
1551 server
->smallbuf
= NULL
;
1556 cifs_readv_receive(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1559 unsigned int data_offset
, data_len
;
1560 struct cifs_readdata
*rdata
= mid
->callback_data
;
1561 char *buf
= server
->smallbuf
;
1562 unsigned int buflen
= server
->pdu_size
+
1563 server
->vals
->header_preamble_size
;
1564 bool use_rdma_mr
= false;
1566 cifs_dbg(FYI
, "%s: mid=%llu offset=%llu bytes=%u\n",
1567 __func__
, mid
->mid
, rdata
->offset
, rdata
->bytes
);
1570 * read the rest of READ_RSP header (sans Data array), or whatever we
1571 * can if there's not enough data. At this point, we've read down to
1574 len
= min_t(unsigned int, buflen
, server
->vals
->read_rsp_size
) -
1575 HEADER_SIZE(server
) + 1;
1577 length
= cifs_read_from_socket(server
,
1578 buf
+ HEADER_SIZE(server
) - 1, len
);
1581 server
->total_read
+= length
;
1583 if (server
->ops
->is_session_expired
&&
1584 server
->ops
->is_session_expired(buf
)) {
1585 cifs_reconnect(server
);
1586 wake_up(&server
->response_q
);
1590 if (server
->ops
->is_status_pending
&&
1591 server
->ops
->is_status_pending(buf
, server
, 0)) {
1592 cifs_discard_remaining_data(server
);
1596 /* Was the SMB read successful? */
1597 rdata
->result
= server
->ops
->map_error(buf
, false);
1598 if (rdata
->result
!= 0) {
1599 cifs_dbg(FYI
, "%s: server returned error %d\n",
1600 __func__
, rdata
->result
);
1601 return cifs_readv_discard(server
, mid
);
1604 /* Is there enough to get to the rest of the READ_RSP header? */
1605 if (server
->total_read
< server
->vals
->read_rsp_size
) {
1606 cifs_dbg(FYI
, "%s: server returned short header. got=%u expected=%zu\n",
1607 __func__
, server
->total_read
,
1608 server
->vals
->read_rsp_size
);
1609 rdata
->result
= -EIO
;
1610 return cifs_readv_discard(server
, mid
);
1613 data_offset
= server
->ops
->read_data_offset(buf
) +
1614 server
->vals
->header_preamble_size
;
1615 if (data_offset
< server
->total_read
) {
1617 * win2k8 sometimes sends an offset of 0 when the read
1618 * is beyond the EOF. Treat it as if the data starts just after
1621 cifs_dbg(FYI
, "%s: data offset (%u) inside read response header\n",
1622 __func__
, data_offset
);
1623 data_offset
= server
->total_read
;
1624 } else if (data_offset
> MAX_CIFS_SMALL_BUFFER_SIZE
) {
1625 /* data_offset is beyond the end of smallbuf */
1626 cifs_dbg(FYI
, "%s: data offset (%u) beyond end of smallbuf\n",
1627 __func__
, data_offset
);
1628 rdata
->result
= -EIO
;
1629 return cifs_readv_discard(server
, mid
);
1632 cifs_dbg(FYI
, "%s: total_read=%u data_offset=%u\n",
1633 __func__
, server
->total_read
, data_offset
);
1635 len
= data_offset
- server
->total_read
;
1637 /* read any junk before data into the rest of smallbuf */
1638 length
= cifs_read_from_socket(server
,
1639 buf
+ server
->total_read
, len
);
1642 server
->total_read
+= length
;
1645 /* set up first iov for signature check */
1646 rdata
->iov
[0].iov_base
= buf
;
1647 rdata
->iov
[0].iov_len
= 4;
1648 rdata
->iov
[1].iov_base
= buf
+ 4;
1649 rdata
->iov
[1].iov_len
= server
->total_read
- 4;
1650 cifs_dbg(FYI
, "0: iov_base=%p iov_len=%u\n",
1651 rdata
->iov
[0].iov_base
, server
->total_read
);
1653 /* how much data is in the response? */
1654 #ifdef CONFIG_CIFS_SMB_DIRECT
1655 use_rdma_mr
= rdata
->mr
;
1657 data_len
= server
->ops
->read_data_length(buf
, use_rdma_mr
);
1658 if (!use_rdma_mr
&& (data_offset
+ data_len
> buflen
)) {
1659 /* data_len is corrupt -- discard frame */
1660 rdata
->result
= -EIO
;
1661 return cifs_readv_discard(server
, mid
);
1664 length
= rdata
->read_into_pages(server
, rdata
, data_len
);
1668 server
->total_read
+= length
;
1670 cifs_dbg(FYI
, "total_read=%u buflen=%u remaining=%u\n",
1671 server
->total_read
, buflen
, data_len
);
1673 /* discard anything left over */
1674 if (server
->total_read
< buflen
)
1675 return cifs_readv_discard(server
, mid
);
1677 dequeue_mid(mid
, false);
1678 mid
->resp_buf
= server
->smallbuf
;
1679 server
->smallbuf
= NULL
;
1684 cifs_readv_callback(struct mid_q_entry
*mid
)
1686 struct cifs_readdata
*rdata
= mid
->callback_data
;
1687 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1688 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
1689 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1691 .rq_pages
= rdata
->pages
,
1692 .rq_offset
= rdata
->page_offset
,
1693 .rq_npages
= rdata
->nr_pages
,
1694 .rq_pagesz
= rdata
->pagesz
,
1695 .rq_tailsz
= rdata
->tailsz
};
1697 cifs_dbg(FYI
, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1698 __func__
, mid
->mid
, mid
->mid_state
, rdata
->result
,
1701 switch (mid
->mid_state
) {
1702 case MID_RESPONSE_RECEIVED
:
1703 /* result already set, check signature */
1707 rc
= cifs_verify_signature(&rqst
, server
,
1708 mid
->sequence_number
);
1710 cifs_dbg(VFS
, "SMB signature verification returned error = %d\n",
1713 /* FIXME: should this be counted toward the initiating task? */
1714 task_io_account_read(rdata
->got_bytes
);
1715 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1717 case MID_REQUEST_SUBMITTED
:
1718 case MID_RETRY_NEEDED
:
1719 rdata
->result
= -EAGAIN
;
1720 if (server
->sign
&& rdata
->got_bytes
)
1721 /* reset bytes number since we can not check a sign */
1722 rdata
->got_bytes
= 0;
1723 /* FIXME: should this be counted toward the initiating task? */
1724 task_io_account_read(rdata
->got_bytes
);
1725 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1728 rdata
->result
= -EIO
;
1731 queue_work(cifsiod_wq
, &rdata
->work
);
1732 DeleteMidQEntry(mid
);
1733 add_credits(server
, 1, 0);
1736 /* cifs_async_readv - send an async write, and set up mid to handle result */
1738 cifs_async_readv(struct cifs_readdata
*rdata
)
1741 READ_REQ
*smb
= NULL
;
1743 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1744 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1747 cifs_dbg(FYI
, "%s: offset=%llu bytes=%u\n",
1748 __func__
, rdata
->offset
, rdata
->bytes
);
1750 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1753 wct
= 10; /* old style read */
1754 if ((rdata
->offset
>> 32) > 0) {
1755 /* can not handle this big offset for old */
1760 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **)&smb
);
1764 smb
->hdr
.Pid
= cpu_to_le16((__u16
)rdata
->pid
);
1765 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(rdata
->pid
>> 16));
1767 smb
->AndXCommand
= 0xFF; /* none */
1768 smb
->Fid
= rdata
->cfile
->fid
.netfid
;
1769 smb
->OffsetLow
= cpu_to_le32(rdata
->offset
& 0xFFFFFFFF);
1771 smb
->OffsetHigh
= cpu_to_le32(rdata
->offset
>> 32);
1773 smb
->MaxCount
= cpu_to_le16(rdata
->bytes
& 0xFFFF);
1774 smb
->MaxCountHigh
= cpu_to_le32(rdata
->bytes
>> 16);
1778 /* old style read */
1779 struct smb_com_readx_req
*smbr
=
1780 (struct smb_com_readx_req
*)smb
;
1781 smbr
->ByteCount
= 0;
1784 /* 4 for RFC1001 length + 1 for BCC */
1785 rdata
->iov
[0].iov_base
= smb
;
1786 rdata
->iov
[0].iov_len
= 4;
1787 rdata
->iov
[1].iov_base
= (char *)smb
+ 4;
1788 rdata
->iov
[1].iov_len
= get_rfc1002_length(smb
);
1790 kref_get(&rdata
->refcount
);
1791 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, cifs_readv_receive
,
1792 cifs_readv_callback
, NULL
, rdata
, 0);
1795 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1797 kref_put(&rdata
->refcount
, cifs_readdata_release
);
1799 cifs_small_buf_release(smb
);
1804 CIFSSMBRead(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1805 unsigned int *nbytes
, char **buf
, int *pbuf_type
)
1808 READ_REQ
*pSMB
= NULL
;
1809 READ_RSP
*pSMBr
= NULL
;
1810 char *pReadData
= NULL
;
1812 int resp_buf_type
= 0;
1814 struct kvec rsp_iov
;
1815 __u32 pid
= io_parms
->pid
;
1816 __u16 netfid
= io_parms
->netfid
;
1817 __u64 offset
= io_parms
->offset
;
1818 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1819 unsigned int count
= io_parms
->length
;
1821 cifs_dbg(FYI
, "Reading %d bytes on fid %d\n", count
, netfid
);
1822 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1825 wct
= 10; /* old style read */
1826 if ((offset
>> 32) > 0) {
1827 /* can not handle this big offset for old */
1833 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **) &pSMB
);
1837 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1838 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1840 /* tcon and ses pointer are checked in smb_init */
1841 if (tcon
->ses
->server
== NULL
)
1842 return -ECONNABORTED
;
1844 pSMB
->AndXCommand
= 0xFF; /* none */
1846 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1848 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1850 pSMB
->Remaining
= 0;
1851 pSMB
->MaxCount
= cpu_to_le16(count
& 0xFFFF);
1852 pSMB
->MaxCountHigh
= cpu_to_le32(count
>> 16);
1854 pSMB
->ByteCount
= 0; /* no need to do le conversion since 0 */
1856 /* old style read */
1857 struct smb_com_readx_req
*pSMBW
=
1858 (struct smb_com_readx_req
*)pSMB
;
1859 pSMBW
->ByteCount
= 0;
1862 iov
[0].iov_base
= (char *)pSMB
;
1863 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
1864 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1, &resp_buf_type
,
1865 CIFS_LOG_ERROR
, &rsp_iov
);
1866 cifs_small_buf_release(pSMB
);
1867 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1868 pSMBr
= (READ_RSP
*)rsp_iov
.iov_base
;
1870 cifs_dbg(VFS
, "Send error in read = %d\n", rc
);
1872 int data_length
= le16_to_cpu(pSMBr
->DataLengthHigh
);
1873 data_length
= data_length
<< 16;
1874 data_length
+= le16_to_cpu(pSMBr
->DataLength
);
1875 *nbytes
= data_length
;
1877 /*check that DataLength would not go beyond end of SMB */
1878 if ((data_length
> CIFSMaxBufSize
)
1879 || (data_length
> count
)) {
1880 cifs_dbg(FYI
, "bad length %d for count %d\n",
1881 data_length
, count
);
1885 pReadData
= (char *) (&pSMBr
->hdr
.Protocol
) +
1886 le16_to_cpu(pSMBr
->DataOffset
);
1887 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1888 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1890 }*/ /* can not use copy_to_user when using page cache*/
1892 memcpy(*buf
, pReadData
, data_length
);
1897 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
1898 } else if (resp_buf_type
!= CIFS_NO_BUFFER
) {
1899 /* return buffer to caller to free */
1900 *buf
= rsp_iov
.iov_base
;
1901 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1902 *pbuf_type
= CIFS_SMALL_BUFFER
;
1903 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1904 *pbuf_type
= CIFS_LARGE_BUFFER
;
1905 } /* else no valid buffer on return - leave as null */
1907 /* Note: On -EAGAIN error only caller can retry on handle based calls
1908 since file handle passed in no longer valid */
1914 CIFSSMBWrite(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1915 unsigned int *nbytes
, const char *buf
)
1918 WRITE_REQ
*pSMB
= NULL
;
1919 WRITE_RSP
*pSMBr
= NULL
;
1920 int bytes_returned
, wct
;
1923 __u32 pid
= io_parms
->pid
;
1924 __u16 netfid
= io_parms
->netfid
;
1925 __u64 offset
= io_parms
->offset
;
1926 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1927 unsigned int count
= io_parms
->length
;
1931 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1932 if (tcon
->ses
== NULL
)
1933 return -ECONNABORTED
;
1935 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1939 if ((offset
>> 32) > 0) {
1940 /* can not handle big offset for old srv */
1945 rc
= smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
,
1950 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1951 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1953 /* tcon and ses pointer are checked in smb_init */
1954 if (tcon
->ses
->server
== NULL
)
1955 return -ECONNABORTED
;
1957 pSMB
->AndXCommand
= 0xFF; /* none */
1959 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1961 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1963 pSMB
->Reserved
= 0xFFFFFFFF;
1964 pSMB
->WriteMode
= 0;
1965 pSMB
->Remaining
= 0;
1967 /* Can increase buffer size if buffer is big enough in some cases ie we
1968 can send more if LARGE_WRITE_X capability returned by the server and if
1969 our buffer is big enough or if we convert to iovecs on socket writes
1970 and eliminate the copy to the CIFS buffer */
1971 if (tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
) {
1972 bytes_sent
= min_t(const unsigned int, CIFSMaxBufSize
, count
);
1974 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
)
1978 if (bytes_sent
> count
)
1981 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1983 memcpy(pSMB
->Data
, buf
, bytes_sent
);
1984 else if (count
!= 0) {
1986 cifs_buf_release(pSMB
);
1988 } /* else setting file size with write of zero bytes */
1990 byte_count
= bytes_sent
+ 1; /* pad */
1991 else /* wct == 12 */
1992 byte_count
= bytes_sent
+ 5; /* bigger pad, smaller smb hdr */
1994 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
& 0xFFFF);
1995 pSMB
->DataLengthHigh
= cpu_to_le16(bytes_sent
>> 16);
1996 inc_rfc1001_len(pSMB
, byte_count
);
1999 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2000 else { /* old style write has byte count 4 bytes earlier
2002 struct smb_com_writex_req
*pSMBW
=
2003 (struct smb_com_writex_req
*)pSMB
;
2004 pSMBW
->ByteCount
= cpu_to_le16(byte_count
);
2007 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2008 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2009 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2011 cifs_dbg(FYI
, "Send error in write = %d\n", rc
);
2013 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2014 *nbytes
= (*nbytes
) << 16;
2015 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2018 * Mask off high 16 bits when bytes written as returned by the
2019 * server is greater than bytes requested by the client. Some
2020 * OS/2 servers are known to set incorrect CountHigh values.
2022 if (*nbytes
> count
)
2026 cifs_buf_release(pSMB
);
2028 /* Note: On -EAGAIN error only caller can retry on handle based calls
2029 since file handle passed in no longer valid */
2035 cifs_writedata_release(struct kref
*refcount
)
2037 struct cifs_writedata
*wdata
= container_of(refcount
,
2038 struct cifs_writedata
, refcount
);
2039 #ifdef CONFIG_CIFS_SMB_DIRECT
2041 smbd_deregister_mr(wdata
->mr
);
2047 cifsFileInfo_put(wdata
->cfile
);
2049 kvfree(wdata
->pages
);
2054 * Write failed with a retryable error. Resend the write request. It's also
2055 * possible that the page was redirtied so re-clean the page.
2058 cifs_writev_requeue(struct cifs_writedata
*wdata
)
2061 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
2062 struct TCP_Server_Info
*server
;
2063 unsigned int rest_len
;
2065 server
= tlink_tcon(wdata
->cfile
->tlink
)->ses
->server
;
2067 rest_len
= wdata
->bytes
;
2069 struct cifs_writedata
*wdata2
;
2070 unsigned int j
, nr_pages
, wsize
, tailsz
, cur_len
;
2072 wsize
= server
->ops
->wp_retry_size(inode
);
2073 if (wsize
< rest_len
) {
2074 nr_pages
= wsize
/ PAGE_SIZE
;
2079 cur_len
= nr_pages
* PAGE_SIZE
;
2082 nr_pages
= DIV_ROUND_UP(rest_len
, PAGE_SIZE
);
2084 tailsz
= rest_len
- (nr_pages
- 1) * PAGE_SIZE
;
2087 wdata2
= cifs_writedata_alloc(nr_pages
, cifs_writev_complete
);
2093 for (j
= 0; j
< nr_pages
; j
++) {
2094 wdata2
->pages
[j
] = wdata
->pages
[i
+ j
];
2095 lock_page(wdata2
->pages
[j
]);
2096 clear_page_dirty_for_io(wdata2
->pages
[j
]);
2099 wdata2
->sync_mode
= wdata
->sync_mode
;
2100 wdata2
->nr_pages
= nr_pages
;
2101 wdata2
->offset
= page_offset(wdata2
->pages
[0]);
2102 wdata2
->pagesz
= PAGE_SIZE
;
2103 wdata2
->tailsz
= tailsz
;
2104 wdata2
->bytes
= cur_len
;
2106 wdata2
->cfile
= find_writable_file(CIFS_I(inode
), false);
2107 if (!wdata2
->cfile
) {
2108 cifs_dbg(VFS
, "No writable handles for inode\n");
2112 wdata2
->pid
= wdata2
->cfile
->pid
;
2113 rc
= server
->ops
->async_writev(wdata2
, cifs_writedata_release
);
2115 for (j
= 0; j
< nr_pages
; j
++) {
2116 unlock_page(wdata2
->pages
[j
]);
2117 if (rc
!= 0 && rc
!= -EAGAIN
) {
2118 SetPageError(wdata2
->pages
[j
]);
2119 end_page_writeback(wdata2
->pages
[j
]);
2120 put_page(wdata2
->pages
[j
]);
2125 kref_put(&wdata2
->refcount
, cifs_writedata_release
);
2131 rest_len
-= cur_len
;
2133 } while (i
< wdata
->nr_pages
);
2135 mapping_set_error(inode
->i_mapping
, rc
);
2136 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2140 cifs_writev_complete(struct work_struct
*work
)
2142 struct cifs_writedata
*wdata
= container_of(work
,
2143 struct cifs_writedata
, work
);
2144 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
2147 if (wdata
->result
== 0) {
2148 spin_lock(&inode
->i_lock
);
2149 cifs_update_eof(CIFS_I(inode
), wdata
->offset
, wdata
->bytes
);
2150 spin_unlock(&inode
->i_lock
);
2151 cifs_stats_bytes_written(tlink_tcon(wdata
->cfile
->tlink
),
2153 } else if (wdata
->sync_mode
== WB_SYNC_ALL
&& wdata
->result
== -EAGAIN
)
2154 return cifs_writev_requeue(wdata
);
2156 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
2157 struct page
*page
= wdata
->pages
[i
];
2158 if (wdata
->result
== -EAGAIN
)
2159 __set_page_dirty_nobuffers(page
);
2160 else if (wdata
->result
< 0)
2162 end_page_writeback(page
);
2165 if (wdata
->result
!= -EAGAIN
)
2166 mapping_set_error(inode
->i_mapping
, wdata
->result
);
2167 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2170 struct cifs_writedata
*
2171 cifs_writedata_alloc(unsigned int nr_pages
, work_func_t complete
)
2173 struct page
**pages
=
2174 kcalloc(nr_pages
, sizeof(struct page
*), GFP_NOFS
);
2176 return cifs_writedata_direct_alloc(pages
, complete
);
2181 struct cifs_writedata
*
2182 cifs_writedata_direct_alloc(struct page
**pages
, work_func_t complete
)
2184 struct cifs_writedata
*wdata
;
2186 wdata
= kzalloc(sizeof(*wdata
), GFP_NOFS
);
2187 if (wdata
!= NULL
) {
2188 wdata
->pages
= pages
;
2189 kref_init(&wdata
->refcount
);
2190 INIT_LIST_HEAD(&wdata
->list
);
2191 init_completion(&wdata
->done
);
2192 INIT_WORK(&wdata
->work
, complete
);
2198 * Check the mid_state and signature on received buffer (if any), and queue the
2199 * workqueue completion task.
2202 cifs_writev_callback(struct mid_q_entry
*mid
)
2204 struct cifs_writedata
*wdata
= mid
->callback_data
;
2205 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2206 unsigned int written
;
2207 WRITE_RSP
*smb
= (WRITE_RSP
*)mid
->resp_buf
;
2209 switch (mid
->mid_state
) {
2210 case MID_RESPONSE_RECEIVED
:
2211 wdata
->result
= cifs_check_receive(mid
, tcon
->ses
->server
, 0);
2212 if (wdata
->result
!= 0)
2215 written
= le16_to_cpu(smb
->CountHigh
);
2217 written
+= le16_to_cpu(smb
->Count
);
2219 * Mask off high 16 bits when bytes written as returned
2220 * by the server is greater than bytes requested by the
2221 * client. OS/2 servers are known to set incorrect
2224 if (written
> wdata
->bytes
)
2227 if (written
< wdata
->bytes
)
2228 wdata
->result
= -ENOSPC
;
2230 wdata
->bytes
= written
;
2232 case MID_REQUEST_SUBMITTED
:
2233 case MID_RETRY_NEEDED
:
2234 wdata
->result
= -EAGAIN
;
2237 wdata
->result
= -EIO
;
2241 queue_work(cifsiod_wq
, &wdata
->work
);
2242 DeleteMidQEntry(mid
);
2243 add_credits(tcon
->ses
->server
, 1, 0);
2246 /* cifs_async_writev - send an async write, and set up mid to handle result */
2248 cifs_async_writev(struct cifs_writedata
*wdata
,
2249 void (*release
)(struct kref
*kref
))
2252 WRITE_REQ
*smb
= NULL
;
2254 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2256 struct smb_rqst rqst
= { };
2258 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2262 if (wdata
->offset
>> 32 > 0) {
2263 /* can not handle big offset for old srv */
2268 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **)&smb
);
2270 goto async_writev_out
;
2272 smb
->hdr
.Pid
= cpu_to_le16((__u16
)wdata
->pid
);
2273 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(wdata
->pid
>> 16));
2275 smb
->AndXCommand
= 0xFF; /* none */
2276 smb
->Fid
= wdata
->cfile
->fid
.netfid
;
2277 smb
->OffsetLow
= cpu_to_le32(wdata
->offset
& 0xFFFFFFFF);
2279 smb
->OffsetHigh
= cpu_to_le32(wdata
->offset
>> 32);
2280 smb
->Reserved
= 0xFFFFFFFF;
2285 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2287 /* 4 for RFC1001 length + 1 for BCC */
2289 iov
[0].iov_base
= smb
;
2290 iov
[1].iov_len
= get_rfc1002_length(smb
) + 1;
2291 iov
[1].iov_base
= (char *)smb
+ 4;
2295 rqst
.rq_pages
= wdata
->pages
;
2296 rqst
.rq_offset
= wdata
->page_offset
;
2297 rqst
.rq_npages
= wdata
->nr_pages
;
2298 rqst
.rq_pagesz
= wdata
->pagesz
;
2299 rqst
.rq_tailsz
= wdata
->tailsz
;
2301 cifs_dbg(FYI
, "async write at %llu %u bytes\n",
2302 wdata
->offset
, wdata
->bytes
);
2304 smb
->DataLengthLow
= cpu_to_le16(wdata
->bytes
& 0xFFFF);
2305 smb
->DataLengthHigh
= cpu_to_le16(wdata
->bytes
>> 16);
2308 inc_rfc1001_len(&smb
->hdr
, wdata
->bytes
+ 1);
2309 put_bcc(wdata
->bytes
+ 1, &smb
->hdr
);
2312 struct smb_com_writex_req
*smbw
=
2313 (struct smb_com_writex_req
*)smb
;
2314 inc_rfc1001_len(&smbw
->hdr
, wdata
->bytes
+ 5);
2315 put_bcc(wdata
->bytes
+ 5, &smbw
->hdr
);
2316 iov
[1].iov_len
+= 4; /* pad bigger by four bytes */
2319 kref_get(&wdata
->refcount
);
2320 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, NULL
,
2321 cifs_writev_callback
, NULL
, wdata
, 0);
2324 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2326 kref_put(&wdata
->refcount
, release
);
2329 cifs_small_buf_release(smb
);
2334 CIFSSMBWrite2(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
2335 unsigned int *nbytes
, struct kvec
*iov
, int n_vec
)
2338 WRITE_REQ
*pSMB
= NULL
;
2341 int resp_buf_type
= 0;
2342 __u32 pid
= io_parms
->pid
;
2343 __u16 netfid
= io_parms
->netfid
;
2344 __u64 offset
= io_parms
->offset
;
2345 struct cifs_tcon
*tcon
= io_parms
->tcon
;
2346 unsigned int count
= io_parms
->length
;
2347 struct kvec rsp_iov
;
2351 cifs_dbg(FYI
, "write2 at %lld %d bytes\n", (long long)offset
, count
);
2353 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2357 if ((offset
>> 32) > 0) {
2358 /* can not handle big offset for old srv */
2362 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
);
2366 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
2367 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
2369 /* tcon and ses pointer are checked in smb_init */
2370 if (tcon
->ses
->server
== NULL
)
2371 return -ECONNABORTED
;
2373 pSMB
->AndXCommand
= 0xFF; /* none */
2375 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
2377 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
2378 pSMB
->Reserved
= 0xFFFFFFFF;
2379 pSMB
->WriteMode
= 0;
2380 pSMB
->Remaining
= 0;
2383 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2385 pSMB
->DataLengthLow
= cpu_to_le16(count
& 0xFFFF);
2386 pSMB
->DataLengthHigh
= cpu_to_le16(count
>> 16);
2387 /* header + 1 byte pad */
2388 smb_hdr_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 1;
2390 inc_rfc1001_len(pSMB
, count
+ 1);
2391 else /* wct == 12 */
2392 inc_rfc1001_len(pSMB
, count
+ 5); /* smb data starts later */
2394 pSMB
->ByteCount
= cpu_to_le16(count
+ 1);
2395 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2396 struct smb_com_writex_req
*pSMBW
=
2397 (struct smb_com_writex_req
*)pSMB
;
2398 pSMBW
->ByteCount
= cpu_to_le16(count
+ 5);
2400 iov
[0].iov_base
= pSMB
;
2402 iov
[0].iov_len
= smb_hdr_len
+ 4;
2403 else /* wct == 12 pad bigger by four bytes */
2404 iov
[0].iov_len
= smb_hdr_len
+ 8;
2406 rc
= SendReceive2(xid
, tcon
->ses
, iov
, n_vec
+ 1, &resp_buf_type
, 0,
2408 cifs_small_buf_release(pSMB
);
2409 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2411 cifs_dbg(FYI
, "Send error Write2 = %d\n", rc
);
2412 } else if (resp_buf_type
== 0) {
2413 /* presumably this can not happen, but best to be safe */
2416 WRITE_RSP
*pSMBr
= (WRITE_RSP
*)rsp_iov
.iov_base
;
2417 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2418 *nbytes
= (*nbytes
) << 16;
2419 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2422 * Mask off high 16 bits when bytes written as returned by the
2423 * server is greater than bytes requested by the client. OS/2
2424 * servers are known to set incorrect CountHigh values.
2426 if (*nbytes
> count
)
2430 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2432 /* Note: On -EAGAIN error only caller can retry on handle based calls
2433 since file handle passed in no longer valid */
2438 int cifs_lockv(const unsigned int xid
, struct cifs_tcon
*tcon
,
2439 const __u16 netfid
, const __u8 lock_type
, const __u32 num_unlock
,
2440 const __u32 num_lock
, LOCKING_ANDX_RANGE
*buf
)
2443 LOCK_REQ
*pSMB
= NULL
;
2445 struct kvec rsp_iov
;
2449 cifs_dbg(FYI
, "cifs_lockv num lock %d num unlock %d\n",
2450 num_lock
, num_unlock
);
2452 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2457 pSMB
->NumberOfLocks
= cpu_to_le16(num_lock
);
2458 pSMB
->NumberOfUnlocks
= cpu_to_le16(num_unlock
);
2459 pSMB
->LockType
= lock_type
;
2460 pSMB
->AndXCommand
= 0xFF; /* none */
2461 pSMB
->Fid
= netfid
; /* netfid stays le */
2463 count
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2464 inc_rfc1001_len(pSMB
, count
);
2465 pSMB
->ByteCount
= cpu_to_le16(count
);
2467 iov
[0].iov_base
= (char *)pSMB
;
2468 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4 -
2469 (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2470 iov
[1].iov_base
= (char *)buf
;
2471 iov
[1].iov_len
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2473 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2474 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 2, &resp_buf_type
, CIFS_NO_RESP
,
2476 cifs_small_buf_release(pSMB
);
2478 cifs_dbg(FYI
, "Send error in cifs_lockv = %d\n", rc
);
2484 CIFSSMBLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2485 const __u16 smb_file_id
, const __u32 netpid
, const __u64 len
,
2486 const __u64 offset
, const __u32 numUnlock
,
2487 const __u32 numLock
, const __u8 lockType
,
2488 const bool waitFlag
, const __u8 oplock_level
)
2491 LOCK_REQ
*pSMB
= NULL
;
2492 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2497 cifs_dbg(FYI
, "CIFSSMBLock timeout %d numLock %d\n",
2498 (int)waitFlag
, numLock
);
2499 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2504 if (lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
2505 /* no response expected */
2506 flags
= CIFS_ASYNC_OP
| CIFS_OBREAK_OP
;
2508 } else if (waitFlag
) {
2509 flags
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2510 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
2515 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
2516 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
2517 pSMB
->LockType
= lockType
;
2518 pSMB
->OplockLevel
= oplock_level
;
2519 pSMB
->AndXCommand
= 0xFF; /* none */
2520 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
2522 if ((numLock
!= 0) || (numUnlock
!= 0)) {
2523 pSMB
->Locks
[0].Pid
= cpu_to_le16(netpid
);
2524 /* BB where to store pid high? */
2525 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
2526 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
2527 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
2528 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
2529 count
= sizeof(LOCKING_ANDX_RANGE
);
2534 inc_rfc1001_len(pSMB
, count
);
2535 pSMB
->ByteCount
= cpu_to_le16(count
);
2538 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2539 (struct smb_hdr
*) pSMB
, &bytes_returned
);
2541 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)pSMB
, flags
);
2542 cifs_small_buf_release(pSMB
);
2543 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2545 cifs_dbg(FYI
, "Send error in Lock = %d\n", rc
);
2547 /* Note: On -EAGAIN error only caller can retry on handle based calls
2548 since file handle passed in no longer valid */
2553 CIFSSMBPosixLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2554 const __u16 smb_file_id
, const __u32 netpid
,
2555 const loff_t start_offset
, const __u64 len
,
2556 struct file_lock
*pLockData
, const __u16 lock_type
,
2557 const bool waitFlag
)
2559 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2560 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2561 struct cifs_posix_lock
*parm_data
;
2564 int bytes_returned
= 0;
2565 int resp_buf_type
= 0;
2566 __u16 params
, param_offset
, offset
, byte_count
, count
;
2568 struct kvec rsp_iov
;
2570 cifs_dbg(FYI
, "Posix Lock\n");
2572 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
2577 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)pSMB
;
2580 pSMB
->MaxSetupCount
= 0;
2583 pSMB
->Reserved2
= 0;
2584 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2585 offset
= param_offset
+ params
;
2587 count
= sizeof(struct cifs_posix_lock
);
2588 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2589 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2590 pSMB
->SetupCount
= 1;
2591 pSMB
->Reserved3
= 0;
2593 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
2595 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2596 byte_count
= 3 /* pad */ + params
+ count
;
2597 pSMB
->DataCount
= cpu_to_le16(count
);
2598 pSMB
->ParameterCount
= cpu_to_le16(params
);
2599 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2600 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2601 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2602 parm_data
= (struct cifs_posix_lock
*)
2603 (((char *) &pSMB
->hdr
.Protocol
) + offset
);
2605 parm_data
->lock_type
= cpu_to_le16(lock_type
);
2607 timeout
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2608 parm_data
->lock_flags
= cpu_to_le16(1);
2609 pSMB
->Timeout
= cpu_to_le32(-1);
2613 parm_data
->pid
= cpu_to_le32(netpid
);
2614 parm_data
->start
= cpu_to_le64(start_offset
);
2615 parm_data
->length
= cpu_to_le64(len
); /* normalize negative numbers */
2617 pSMB
->DataOffset
= cpu_to_le16(offset
);
2618 pSMB
->Fid
= smb_file_id
;
2619 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_LOCK
);
2620 pSMB
->Reserved4
= 0;
2621 inc_rfc1001_len(pSMB
, byte_count
);
2622 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2624 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2625 (struct smb_hdr
*) pSMBr
, &bytes_returned
);
2627 iov
[0].iov_base
= (char *)pSMB
;
2628 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
2629 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
2630 &resp_buf_type
, timeout
, &rsp_iov
);
2631 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)rsp_iov
.iov_base
;
2633 cifs_small_buf_release(pSMB
);
2636 cifs_dbg(FYI
, "Send error in Posix Lock = %d\n", rc
);
2637 } else if (pLockData
) {
2638 /* lock structure can be returned on get */
2641 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2643 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(*parm_data
)) {
2644 rc
= -EIO
; /* bad smb */
2647 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
2648 data_count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2649 if (data_count
< sizeof(struct cifs_posix_lock
)) {
2653 parm_data
= (struct cifs_posix_lock
*)
2654 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2655 if (parm_data
->lock_type
== cpu_to_le16(CIFS_UNLCK
))
2656 pLockData
->fl_type
= F_UNLCK
;
2658 if (parm_data
->lock_type
==
2659 cpu_to_le16(CIFS_RDLCK
))
2660 pLockData
->fl_type
= F_RDLCK
;
2661 else if (parm_data
->lock_type
==
2662 cpu_to_le16(CIFS_WRLCK
))
2663 pLockData
->fl_type
= F_WRLCK
;
2665 pLockData
->fl_start
= le64_to_cpu(parm_data
->start
);
2666 pLockData
->fl_end
= pLockData
->fl_start
+
2667 le64_to_cpu(parm_data
->length
) - 1;
2668 pLockData
->fl_pid
= -le32_to_cpu(parm_data
->pid
);
2673 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2675 /* Note: On -EAGAIN error only caller can retry on handle based calls
2676 since file handle passed in no longer valid */
2683 CIFSSMBClose(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2686 CLOSE_REQ
*pSMB
= NULL
;
2687 cifs_dbg(FYI
, "In CIFSSMBClose\n");
2689 /* do not retry on dead session on close */
2690 rc
= small_smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
);
2696 pSMB
->FileID
= (__u16
) smb_file_id
;
2697 pSMB
->LastWriteTime
= 0xFFFFFFFF;
2698 pSMB
->ByteCount
= 0;
2699 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2700 cifs_small_buf_release(pSMB
);
2701 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_closes
);
2704 /* EINTR is expected when user ctl-c to kill app */
2705 cifs_dbg(VFS
, "Send error in Close = %d\n", rc
);
2709 /* Since session is dead, file will be closed on server already */
2717 CIFSSMBFlush(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2720 FLUSH_REQ
*pSMB
= NULL
;
2721 cifs_dbg(FYI
, "In CIFSSMBFlush\n");
2723 rc
= small_smb_init(SMB_COM_FLUSH
, 1, tcon
, (void **) &pSMB
);
2727 pSMB
->FileID
= (__u16
) smb_file_id
;
2728 pSMB
->ByteCount
= 0;
2729 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2730 cifs_small_buf_release(pSMB
);
2731 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_flushes
);
2733 cifs_dbg(VFS
, "Send error in Flush = %d\n", rc
);
2739 CIFSSMBRename(const unsigned int xid
, struct cifs_tcon
*tcon
,
2740 const char *from_name
, const char *to_name
,
2741 struct cifs_sb_info
*cifs_sb
)
2744 RENAME_REQ
*pSMB
= NULL
;
2745 RENAME_RSP
*pSMBr
= NULL
;
2747 int name_len
, name_len2
;
2749 int remap
= cifs_remap(cifs_sb
);
2751 cifs_dbg(FYI
, "In CIFSSMBRename\n");
2753 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
2758 pSMB
->BufferFormat
= 0x04;
2759 pSMB
->SearchAttributes
=
2760 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2763 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2764 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2765 from_name
, PATH_MAX
,
2766 cifs_sb
->local_nls
, remap
);
2767 name_len
++; /* trailing null */
2769 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2770 /* protocol requires ASCII signature byte on Unicode string */
2771 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2773 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2774 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2776 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2777 name_len2
*= 2; /* convert to bytes */
2778 } else { /* BB improve the check for buffer overruns BB */
2779 name_len
= strnlen(from_name
, PATH_MAX
);
2780 name_len
++; /* trailing null */
2781 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
2782 name_len2
= strnlen(to_name
, PATH_MAX
);
2783 name_len2
++; /* trailing null */
2784 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2785 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
2786 name_len2
++; /* trailing null */
2787 name_len2
++; /* signature byte */
2790 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2791 inc_rfc1001_len(pSMB
, count
);
2792 pSMB
->ByteCount
= cpu_to_le16(count
);
2794 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2795 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2796 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_renames
);
2798 cifs_dbg(FYI
, "Send error in rename = %d\n", rc
);
2800 cifs_buf_release(pSMB
);
2808 int CIFSSMBRenameOpenFile(const unsigned int xid
, struct cifs_tcon
*pTcon
,
2809 int netfid
, const char *target_name
,
2810 const struct nls_table
*nls_codepage
, int remap
)
2812 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2813 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2814 struct set_file_rename
*rename_info
;
2816 char dummy_string
[30];
2818 int bytes_returned
= 0;
2820 __u16 params
, param_offset
, offset
, count
, byte_count
;
2822 cifs_dbg(FYI
, "Rename to File by handle\n");
2823 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
2829 pSMB
->MaxSetupCount
= 0;
2833 pSMB
->Reserved2
= 0;
2834 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2835 offset
= param_offset
+ params
;
2837 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2838 rename_info
= (struct set_file_rename
*) data_offset
;
2839 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2840 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2841 pSMB
->SetupCount
= 1;
2842 pSMB
->Reserved3
= 0;
2843 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2844 byte_count
= 3 /* pad */ + params
;
2845 pSMB
->ParameterCount
= cpu_to_le16(params
);
2846 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2847 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2848 pSMB
->DataOffset
= cpu_to_le16(offset
);
2849 /* construct random name ".cifs_tmp<inodenum><mid>" */
2850 rename_info
->overwrite
= cpu_to_le32(1);
2851 rename_info
->root_fid
= 0;
2852 /* unicode only call */
2853 if (target_name
== NULL
) {
2854 sprintf(dummy_string
, "cifs%x", pSMB
->hdr
.Mid
);
2856 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2857 dummy_string
, 24, nls_codepage
, remap
);
2860 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2861 target_name
, PATH_MAX
, nls_codepage
,
2864 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
2865 count
= 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str
);
2866 byte_count
+= count
;
2867 pSMB
->DataCount
= cpu_to_le16(count
);
2868 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2870 pSMB
->InformationLevel
=
2871 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
2872 pSMB
->Reserved4
= 0;
2873 inc_rfc1001_len(pSMB
, byte_count
);
2874 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2875 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
2876 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2877 cifs_stats_inc(&pTcon
->stats
.cifs_stats
.num_t2renames
);
2879 cifs_dbg(FYI
, "Send error in Rename (by file handle) = %d\n",
2882 cifs_buf_release(pSMB
);
2884 /* Note: On -EAGAIN error only caller can retry on handle based calls
2885 since file handle passed in no longer valid */
2891 CIFSSMBCopy(const unsigned int xid
, struct cifs_tcon
*tcon
,
2892 const char *fromName
, const __u16 target_tid
, const char *toName
,
2893 const int flags
, const struct nls_table
*nls_codepage
, int remap
)
2896 COPY_REQ
*pSMB
= NULL
;
2897 COPY_RSP
*pSMBr
= NULL
;
2899 int name_len
, name_len2
;
2902 cifs_dbg(FYI
, "In CIFSSMBCopy\n");
2904 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
2909 pSMB
->BufferFormat
= 0x04;
2910 pSMB
->Tid2
= target_tid
;
2912 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
2914 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2915 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2916 fromName
, PATH_MAX
, nls_codepage
,
2918 name_len
++; /* trailing null */
2920 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2921 /* protocol requires ASCII signature byte on Unicode string */
2922 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2924 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2925 toName
, PATH_MAX
, nls_codepage
, remap
);
2926 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2927 name_len2
*= 2; /* convert to bytes */
2928 } else { /* BB improve the check for buffer overruns BB */
2929 name_len
= strnlen(fromName
, PATH_MAX
);
2930 name_len
++; /* trailing null */
2931 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
2932 name_len2
= strnlen(toName
, PATH_MAX
);
2933 name_len2
++; /* trailing null */
2934 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2935 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
2936 name_len2
++; /* trailing null */
2937 name_len2
++; /* signature byte */
2940 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2941 inc_rfc1001_len(pSMB
, count
);
2942 pSMB
->ByteCount
= cpu_to_le16(count
);
2944 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2945 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2947 cifs_dbg(FYI
, "Send error in copy = %d with %d files copied\n",
2948 rc
, le16_to_cpu(pSMBr
->CopyCount
));
2950 cifs_buf_release(pSMB
);
2959 CIFSUnixCreateSymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2960 const char *fromName
, const char *toName
,
2961 const struct nls_table
*nls_codepage
, int remap
)
2963 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2964 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2967 int name_len_target
;
2969 int bytes_returned
= 0;
2970 __u16 params
, param_offset
, offset
, byte_count
;
2972 cifs_dbg(FYI
, "In Symlink Unix style\n");
2974 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2979 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2981 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fromName
,
2982 /* find define for this maxpathcomponent */
2983 PATH_MAX
, nls_codepage
, remap
);
2984 name_len
++; /* trailing null */
2987 } else { /* BB improve the check for buffer overruns BB */
2988 name_len
= strnlen(fromName
, PATH_MAX
);
2989 name_len
++; /* trailing null */
2990 strncpy(pSMB
->FileName
, fromName
, name_len
);
2992 params
= 6 + name_len
;
2993 pSMB
->MaxSetupCount
= 0;
2997 pSMB
->Reserved2
= 0;
2998 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2999 InformationLevel
) - 4;
3000 offset
= param_offset
+ params
;
3002 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
3003 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3005 cifsConvertToUTF16((__le16
*) data_offset
, toName
,
3006 /* find define for this maxpathcomponent */
3007 PATH_MAX
, nls_codepage
, remap
);
3008 name_len_target
++; /* trailing null */
3009 name_len_target
*= 2;
3010 } else { /* BB improve the check for buffer overruns BB */
3011 name_len_target
= strnlen(toName
, PATH_MAX
);
3012 name_len_target
++; /* trailing null */
3013 strncpy(data_offset
, toName
, name_len_target
);
3016 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3017 /* BB find exact max on data count below from sess */
3018 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3019 pSMB
->SetupCount
= 1;
3020 pSMB
->Reserved3
= 0;
3021 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3022 byte_count
= 3 /* pad */ + params
+ name_len_target
;
3023 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
3024 pSMB
->ParameterCount
= cpu_to_le16(params
);
3025 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3026 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3027 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3028 pSMB
->DataOffset
= cpu_to_le16(offset
);
3029 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
3030 pSMB
->Reserved4
= 0;
3031 inc_rfc1001_len(pSMB
, byte_count
);
3032 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3033 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3034 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3035 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_symlinks
);
3037 cifs_dbg(FYI
, "Send error in SetPathInfo create symlink = %d\n",
3040 cifs_buf_release(pSMB
);
3043 goto createSymLinkRetry
;
3049 CIFSUnixCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3050 const char *fromName
, const char *toName
,
3051 const struct nls_table
*nls_codepage
, int remap
)
3053 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
3054 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
3057 int name_len_target
;
3059 int bytes_returned
= 0;
3060 __u16 params
, param_offset
, offset
, byte_count
;
3062 cifs_dbg(FYI
, "In Create Hard link Unix style\n");
3063 createHardLinkRetry
:
3064 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3069 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3070 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->FileName
, toName
,
3071 PATH_MAX
, nls_codepage
, remap
);
3072 name_len
++; /* trailing null */
3075 } else { /* BB improve the check for buffer overruns BB */
3076 name_len
= strnlen(toName
, PATH_MAX
);
3077 name_len
++; /* trailing null */
3078 strncpy(pSMB
->FileName
, toName
, name_len
);
3080 params
= 6 + name_len
;
3081 pSMB
->MaxSetupCount
= 0;
3085 pSMB
->Reserved2
= 0;
3086 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3087 InformationLevel
) - 4;
3088 offset
= param_offset
+ params
;
3090 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
3091 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3093 cifsConvertToUTF16((__le16
*) data_offset
, fromName
,
3094 PATH_MAX
, nls_codepage
, remap
);
3095 name_len_target
++; /* trailing null */
3096 name_len_target
*= 2;
3097 } else { /* BB improve the check for buffer overruns BB */
3098 name_len_target
= strnlen(fromName
, PATH_MAX
);
3099 name_len_target
++; /* trailing null */
3100 strncpy(data_offset
, fromName
, name_len_target
);
3103 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3104 /* BB find exact max on data count below from sess*/
3105 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3106 pSMB
->SetupCount
= 1;
3107 pSMB
->Reserved3
= 0;
3108 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3109 byte_count
= 3 /* pad */ + params
+ name_len_target
;
3110 pSMB
->ParameterCount
= cpu_to_le16(params
);
3111 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3112 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
3113 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3114 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3115 pSMB
->DataOffset
= cpu_to_le16(offset
);
3116 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
3117 pSMB
->Reserved4
= 0;
3118 inc_rfc1001_len(pSMB
, byte_count
);
3119 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3120 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3121 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3122 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3124 cifs_dbg(FYI
, "Send error in SetPathInfo (hard link) = %d\n",
3127 cifs_buf_release(pSMB
);
3129 goto createHardLinkRetry
;
3135 CIFSCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3136 const char *from_name
, const char *to_name
,
3137 struct cifs_sb_info
*cifs_sb
)
3140 NT_RENAME_REQ
*pSMB
= NULL
;
3141 RENAME_RSP
*pSMBr
= NULL
;
3143 int name_len
, name_len2
;
3145 int remap
= cifs_remap(cifs_sb
);
3147 cifs_dbg(FYI
, "In CIFSCreateHardLink\n");
3148 winCreateHardLinkRetry
:
3150 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
3155 pSMB
->SearchAttributes
=
3156 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
3158 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
3159 pSMB
->ClusterCount
= 0;
3161 pSMB
->BufferFormat
= 0x04;
3163 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3165 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, from_name
,
3166 PATH_MAX
, cifs_sb
->local_nls
, remap
);
3167 name_len
++; /* trailing null */
3170 /* protocol specifies ASCII buffer format (0x04) for unicode */
3171 pSMB
->OldFileName
[name_len
] = 0x04;
3172 pSMB
->OldFileName
[name_len
+ 1] = 0x00; /* pad */
3174 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
3175 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
3177 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
3178 name_len2
*= 2; /* convert to bytes */
3179 } else { /* BB improve the check for buffer overruns BB */
3180 name_len
= strnlen(from_name
, PATH_MAX
);
3181 name_len
++; /* trailing null */
3182 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
3183 name_len2
= strnlen(to_name
, PATH_MAX
);
3184 name_len2
++; /* trailing null */
3185 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
3186 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
3187 name_len2
++; /* trailing null */
3188 name_len2
++; /* signature byte */
3191 count
= 1 /* string type byte */ + name_len
+ name_len2
;
3192 inc_rfc1001_len(pSMB
, count
);
3193 pSMB
->ByteCount
= cpu_to_le16(count
);
3195 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3196 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3197 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3199 cifs_dbg(FYI
, "Send error in hard link (NT rename) = %d\n", rc
);
3201 cifs_buf_release(pSMB
);
3203 goto winCreateHardLinkRetry
;
3209 CIFSSMBUnixQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3210 const unsigned char *searchName
, char **symlinkinfo
,
3211 const struct nls_table
*nls_codepage
, int remap
)
3213 /* SMB_QUERY_FILE_UNIX_LINK */
3214 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3215 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3219 __u16 params
, byte_count
;
3222 cifs_dbg(FYI
, "In QPathSymLinkInfo (Unix) for path %s\n", searchName
);
3225 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3230 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3232 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3233 searchName
, PATH_MAX
, nls_codepage
,
3235 name_len
++; /* trailing null */
3237 } else { /* BB improve the check for buffer overruns BB */
3238 name_len
= strnlen(searchName
, PATH_MAX
);
3239 name_len
++; /* trailing null */
3240 strncpy(pSMB
->FileName
, searchName
, name_len
);
3243 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3244 pSMB
->TotalDataCount
= 0;
3245 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3246 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3247 pSMB
->MaxSetupCount
= 0;
3251 pSMB
->Reserved2
= 0;
3252 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3253 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3254 pSMB
->DataCount
= 0;
3255 pSMB
->DataOffset
= 0;
3256 pSMB
->SetupCount
= 1;
3257 pSMB
->Reserved3
= 0;
3258 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3259 byte_count
= params
+ 1 /* pad */ ;
3260 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3261 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3262 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
3263 pSMB
->Reserved4
= 0;
3264 inc_rfc1001_len(pSMB
, byte_count
);
3265 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3267 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3268 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3270 cifs_dbg(FYI
, "Send error in QuerySymLinkInfo = %d\n", rc
);
3272 /* decode response */
3274 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3275 /* BB also check enough total bytes returned */
3276 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3280 u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3282 data_start
= ((char *) &pSMBr
->hdr
.Protocol
) +
3283 le16_to_cpu(pSMBr
->t2
.DataOffset
);
3285 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3290 /* BB FIXME investigate remapping reserved chars here */
3291 *symlinkinfo
= cifs_strndup_from_utf16(data_start
,
3292 count
, is_unicode
, nls_codepage
);
3297 cifs_buf_release(pSMB
);
3299 goto querySymLinkRetry
;
3304 * Recent Windows versions now create symlinks more frequently
3305 * and they use the "reparse point" mechanism below. We can of course
3306 * do symlinks nicely to Samba and other servers which support the
3307 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3308 * "MF" symlinks optionally, but for recent Windows we really need to
3309 * reenable the code below and fix the cifs_symlink callers to handle this.
3310 * In the interim this code has been moved to its own config option so
3311 * it is not compiled in by default until callers fixed up and more tested.
3314 CIFSSMBQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3315 __u16 fid
, char **symlinkinfo
,
3316 const struct nls_table
*nls_codepage
)
3320 struct smb_com_transaction_ioctl_req
*pSMB
;
3321 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3323 unsigned int sub_len
;
3325 struct reparse_symlink_data
*reparse_buf
;
3326 struct reparse_posix_data
*posix_buf
;
3327 __u32 data_offset
, data_count
;
3330 cifs_dbg(FYI
, "In Windows reparse style QueryLink for fid %u\n", fid
);
3331 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3336 pSMB
->TotalParameterCount
= 0 ;
3337 pSMB
->TotalDataCount
= 0;
3338 pSMB
->MaxParameterCount
= cpu_to_le32(2);
3339 /* BB find exact data count max from sess structure BB */
3340 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3341 pSMB
->MaxSetupCount
= 4;
3343 pSMB
->ParameterOffset
= 0;
3344 pSMB
->DataCount
= 0;
3345 pSMB
->DataOffset
= 0;
3346 pSMB
->SetupCount
= 4;
3347 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3348 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3349 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
3350 pSMB
->IsFsctl
= 1; /* FSCTL */
3351 pSMB
->IsRootFlag
= 0;
3352 pSMB
->Fid
= fid
; /* file handle always le */
3353 pSMB
->ByteCount
= 0;
3355 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3356 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3358 cifs_dbg(FYI
, "Send error in QueryReparseLinkInfo = %d\n", rc
);
3362 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3363 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3364 if (get_bcc(&pSMBr
->hdr
) < 2 || data_offset
> 512) {
3365 /* BB also check enough total bytes returned */
3366 rc
= -EIO
; /* bad smb */
3369 if (!data_count
|| (data_count
> 2048)) {
3371 cifs_dbg(FYI
, "Invalid return data count on get reparse info ioctl\n");
3374 end_of_smb
= 2 + get_bcc(&pSMBr
->hdr
) + (char *)&pSMBr
->ByteCount
;
3375 reparse_buf
= (struct reparse_symlink_data
*)
3376 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
3377 if ((char *)reparse_buf
>= end_of_smb
) {
3381 if (reparse_buf
->ReparseTag
== cpu_to_le32(IO_REPARSE_TAG_NFS
)) {
3382 cifs_dbg(FYI
, "NFS style reparse tag\n");
3383 posix_buf
= (struct reparse_posix_data
*)reparse_buf
;
3385 if (posix_buf
->InodeType
!= cpu_to_le64(NFS_SPECFILE_LNK
)) {
3386 cifs_dbg(FYI
, "unsupported file type 0x%llx\n",
3387 le64_to_cpu(posix_buf
->InodeType
));
3392 sub_len
= le16_to_cpu(reparse_buf
->ReparseDataLength
);
3393 if (posix_buf
->PathBuffer
+ sub_len
> end_of_smb
) {
3394 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3398 *symlinkinfo
= cifs_strndup_from_utf16(posix_buf
->PathBuffer
,
3399 sub_len
, is_unicode
, nls_codepage
);
3401 } else if (reparse_buf
->ReparseTag
!=
3402 cpu_to_le32(IO_REPARSE_TAG_SYMLINK
)) {
3407 /* Reparse tag is NTFS symlink */
3408 sub_start
= le16_to_cpu(reparse_buf
->SubstituteNameOffset
) +
3409 reparse_buf
->PathBuffer
;
3410 sub_len
= le16_to_cpu(reparse_buf
->SubstituteNameLength
);
3411 if (sub_start
+ sub_len
> end_of_smb
) {
3412 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3416 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3421 /* BB FIXME investigate remapping reserved chars here */
3422 *symlinkinfo
= cifs_strndup_from_utf16(sub_start
, sub_len
, is_unicode
,
3427 cifs_buf_release(pSMB
);
3430 * Note: On -EAGAIN error only caller can retry on handle based calls
3431 * since file handle passed in no longer valid.
3437 CIFSSMB_set_compression(const unsigned int xid
, struct cifs_tcon
*tcon
,
3442 struct smb_com_transaction_compr_ioctl_req
*pSMB
;
3443 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3445 cifs_dbg(FYI
, "Set compression for %u\n", fid
);
3446 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3451 pSMB
->compression_state
= cpu_to_le16(COMPRESSION_FORMAT_DEFAULT
);
3453 pSMB
->TotalParameterCount
= 0;
3454 pSMB
->TotalDataCount
= cpu_to_le32(2);
3455 pSMB
->MaxParameterCount
= 0;
3456 pSMB
->MaxDataCount
= 0;
3457 pSMB
->MaxSetupCount
= 4;
3459 pSMB
->ParameterOffset
= 0;
3460 pSMB
->DataCount
= cpu_to_le32(2);
3462 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req
,
3463 compression_state
) - 4); /* 84 */
3464 pSMB
->SetupCount
= 4;
3465 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3466 pSMB
->ParameterCount
= 0;
3467 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_SET_COMPRESSION
);
3468 pSMB
->IsFsctl
= 1; /* FSCTL */
3469 pSMB
->IsRootFlag
= 0;
3470 pSMB
->Fid
= fid
; /* file handle always le */
3471 /* 3 byte pad, followed by 2 byte compress state */
3472 pSMB
->ByteCount
= cpu_to_le16(5);
3473 inc_rfc1001_len(pSMB
, 5);
3475 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3476 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3478 cifs_dbg(FYI
, "Send error in SetCompression = %d\n", rc
);
3480 cifs_buf_release(pSMB
);
3483 * Note: On -EAGAIN error only caller can retry on handle based calls
3484 * since file handle passed in no longer valid.
3490 #ifdef CONFIG_CIFS_POSIX
3492 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3493 static void cifs_convert_ace(struct posix_acl_xattr_entry
*ace
,
3494 struct cifs_posix_ace
*cifs_ace
)
3496 /* u8 cifs fields do not need le conversion */
3497 ace
->e_perm
= cpu_to_le16(cifs_ace
->cifs_e_perm
);
3498 ace
->e_tag
= cpu_to_le16(cifs_ace
->cifs_e_tag
);
3499 ace
->e_id
= cpu_to_le32(le64_to_cpu(cifs_ace
->cifs_uid
));
3501 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3502 ace->e_perm, ace->e_tag, ace->e_id);
3508 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3509 static int cifs_copy_posix_acl(char *trgt
, char *src
, const int buflen
,
3510 const int acl_type
, const int size_of_data_area
)
3515 struct cifs_posix_ace
*pACE
;
3516 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)src
;
3517 struct posix_acl_xattr_header
*local_acl
= (void *)trgt
;
3519 if (le16_to_cpu(cifs_acl
->version
) != CIFS_ACL_VERSION
)
3522 if (acl_type
== ACL_TYPE_ACCESS
) {
3523 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3524 pACE
= &cifs_acl
->ace_array
[0];
3525 size
= sizeof(struct cifs_posix_acl
);
3526 size
+= sizeof(struct cifs_posix_ace
) * count
;
3527 /* check if we would go beyond end of SMB */
3528 if (size_of_data_area
< size
) {
3529 cifs_dbg(FYI
, "bad CIFS POSIX ACL size %d vs. %d\n",
3530 size_of_data_area
, size
);
3533 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3534 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3535 size
= sizeof(struct cifs_posix_acl
);
3536 size
+= sizeof(struct cifs_posix_ace
) * count
;
3537 /* skip past access ACEs to get to default ACEs */
3538 pACE
= &cifs_acl
->ace_array
[count
];
3539 count
= le16_to_cpu(cifs_acl
->default_entry_count
);
3540 size
+= sizeof(struct cifs_posix_ace
) * count
;
3541 /* check if we would go beyond end of SMB */
3542 if (size_of_data_area
< size
)
3549 size
= posix_acl_xattr_size(count
);
3550 if ((buflen
== 0) || (local_acl
== NULL
)) {
3551 /* used to query ACL EA size */
3552 } else if (size
> buflen
) {
3554 } else /* buffer big enough */ {
3555 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3557 local_acl
->a_version
= cpu_to_le32(POSIX_ACL_XATTR_VERSION
);
3558 for (i
= 0; i
< count
; i
++) {
3559 cifs_convert_ace(&ace
[i
], pACE
);
3566 static __u16
convert_ace_to_cifs_ace(struct cifs_posix_ace
*cifs_ace
,
3567 const struct posix_acl_xattr_entry
*local_ace
)
3569 __u16 rc
= 0; /* 0 = ACL converted ok */
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);
3586 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3587 static __u16
ACL_to_cifs_posix(char *parm_data
, const char *pACL
,
3588 const int buflen
, const int acl_type
)
3591 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)parm_data
;
3592 struct posix_acl_xattr_header
*local_acl
= (void *)pACL
;
3593 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3597 if ((buflen
== 0) || (pACL
== NULL
) || (cifs_acl
== NULL
))
3600 count
= posix_acl_xattr_count((size_t)buflen
);
3601 cifs_dbg(FYI
, "setting acl with %d entries from buf of length %d and version of %d\n",
3602 count
, buflen
, le32_to_cpu(local_acl
->a_version
));
3603 if (le32_to_cpu(local_acl
->a_version
) != 2) {
3604 cifs_dbg(FYI
, "unknown POSIX ACL version %d\n",
3605 le32_to_cpu(local_acl
->a_version
));
3608 cifs_acl
->version
= cpu_to_le16(1);
3609 if (acl_type
== ACL_TYPE_ACCESS
) {
3610 cifs_acl
->access_entry_count
= cpu_to_le16(count
);
3611 cifs_acl
->default_entry_count
= cpu_to_le16(0xFFFF);
3612 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3613 cifs_acl
->default_entry_count
= cpu_to_le16(count
);
3614 cifs_acl
->access_entry_count
= cpu_to_le16(0xFFFF);
3616 cifs_dbg(FYI
, "unknown ACL type %d\n", acl_type
);
3619 for (i
= 0; i
< count
; i
++) {
3620 rc
= convert_ace_to_cifs_ace(&cifs_acl
->ace_array
[i
], &ace
[i
]);
3622 /* ACE not converted */
3627 rc
= (__u16
)(count
* sizeof(struct cifs_posix_ace
));
3628 rc
+= sizeof(struct cifs_posix_acl
);
3629 /* BB add check to make sure ACL does not overflow SMB */
3635 CIFSSMBGetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3636 const unsigned char *searchName
,
3637 char *acl_inf
, const int buflen
, const int acl_type
,
3638 const struct nls_table
*nls_codepage
, int remap
)
3640 /* SMB_QUERY_POSIX_ACL */
3641 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3642 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3646 __u16 params
, byte_count
;
3648 cifs_dbg(FYI
, "In GetPosixACL (Unix) for path %s\n", searchName
);
3651 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3656 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3658 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3659 searchName
, PATH_MAX
, nls_codepage
,
3661 name_len
++; /* trailing null */
3663 pSMB
->FileName
[name_len
] = 0;
3664 pSMB
->FileName
[name_len
+1] = 0;
3665 } else { /* BB improve the check for buffer overruns BB */
3666 name_len
= strnlen(searchName
, PATH_MAX
);
3667 name_len
++; /* trailing null */
3668 strncpy(pSMB
->FileName
, searchName
, name_len
);
3671 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3672 pSMB
->TotalDataCount
= 0;
3673 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3674 /* BB find exact max data count below from sess structure BB */
3675 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3676 pSMB
->MaxSetupCount
= 0;
3680 pSMB
->Reserved2
= 0;
3681 pSMB
->ParameterOffset
= cpu_to_le16(
3682 offsetof(struct smb_com_transaction2_qpi_req
,
3683 InformationLevel
) - 4);
3684 pSMB
->DataCount
= 0;
3685 pSMB
->DataOffset
= 0;
3686 pSMB
->SetupCount
= 1;
3687 pSMB
->Reserved3
= 0;
3688 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3689 byte_count
= params
+ 1 /* pad */ ;
3690 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3691 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3692 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_ACL
);
3693 pSMB
->Reserved4
= 0;
3694 inc_rfc1001_len(pSMB
, byte_count
);
3695 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3697 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3698 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3699 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3701 cifs_dbg(FYI
, "Send error in Query POSIX ACL = %d\n", rc
);
3703 /* decode response */
3705 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3706 /* BB also check enough total bytes returned */
3707 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3708 rc
= -EIO
; /* bad smb */
3710 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3711 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3712 rc
= cifs_copy_posix_acl(acl_inf
,
3713 (char *)&pSMBr
->hdr
.Protocol
+data_offset
,
3714 buflen
, acl_type
, count
);
3717 cifs_buf_release(pSMB
);
3724 CIFSSMBSetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3725 const unsigned char *fileName
,
3726 const char *local_acl
, const int buflen
,
3728 const struct nls_table
*nls_codepage
, int remap
)
3730 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3731 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3735 int bytes_returned
= 0;
3736 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
3738 cifs_dbg(FYI
, "In SetPosixACL (Unix) for path %s\n", fileName
);
3740 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3744 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3746 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
3747 PATH_MAX
, nls_codepage
, remap
);
3748 name_len
++; /* trailing null */
3750 } else { /* BB improve the check for buffer overruns BB */
3751 name_len
= strnlen(fileName
, PATH_MAX
);
3752 name_len
++; /* trailing null */
3753 strncpy(pSMB
->FileName
, fileName
, name_len
);
3755 params
= 6 + name_len
;
3756 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3757 /* BB find max SMB size from sess */
3758 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3759 pSMB
->MaxSetupCount
= 0;
3763 pSMB
->Reserved2
= 0;
3764 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3765 InformationLevel
) - 4;
3766 offset
= param_offset
+ params
;
3767 parm_data
= ((char *) &pSMB
->hdr
.Protocol
) + offset
;
3768 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3770 /* convert to on the wire format for POSIX ACL */
3771 data_count
= ACL_to_cifs_posix(parm_data
, local_acl
, buflen
, acl_type
);
3773 if (data_count
== 0) {
3775 goto setACLerrorExit
;
3777 pSMB
->DataOffset
= cpu_to_le16(offset
);
3778 pSMB
->SetupCount
= 1;
3779 pSMB
->Reserved3
= 0;
3780 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3781 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_ACL
);
3782 byte_count
= 3 /* pad */ + params
+ data_count
;
3783 pSMB
->DataCount
= cpu_to_le16(data_count
);
3784 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3785 pSMB
->ParameterCount
= cpu_to_le16(params
);
3786 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3787 pSMB
->Reserved4
= 0;
3788 inc_rfc1001_len(pSMB
, byte_count
);
3789 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3790 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3791 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3793 cifs_dbg(FYI
, "Set POSIX ACL returned %d\n", rc
);
3796 cifs_buf_release(pSMB
);
3802 /* BB fix tabs in this function FIXME BB */
3804 CIFSGetExtAttr(const unsigned int xid
, struct cifs_tcon
*tcon
,
3805 const int netfid
, __u64
*pExtAttrBits
, __u64
*pMask
)
3808 struct smb_t2_qfi_req
*pSMB
= NULL
;
3809 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3811 __u16 params
, byte_count
;
3813 cifs_dbg(FYI
, "In GetExtAttr\n");
3818 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3823 params
= 2 /* level */ + 2 /* fid */;
3824 pSMB
->t2
.TotalDataCount
= 0;
3825 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3826 /* BB find exact max data count below from sess structure BB */
3827 pSMB
->t2
.MaxDataCount
= cpu_to_le16(4000);
3828 pSMB
->t2
.MaxSetupCount
= 0;
3829 pSMB
->t2
.Reserved
= 0;
3831 pSMB
->t2
.Timeout
= 0;
3832 pSMB
->t2
.Reserved2
= 0;
3833 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3835 pSMB
->t2
.DataCount
= 0;
3836 pSMB
->t2
.DataOffset
= 0;
3837 pSMB
->t2
.SetupCount
= 1;
3838 pSMB
->t2
.Reserved3
= 0;
3839 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3840 byte_count
= params
+ 1 /* pad */ ;
3841 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3842 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3843 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_ATTR_FLAGS
);
3846 inc_rfc1001_len(pSMB
, byte_count
);
3847 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3849 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3850 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3852 cifs_dbg(FYI
, "error %d in GetExtAttr\n", rc
);
3854 /* decode response */
3855 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3856 /* BB also check enough total bytes returned */
3857 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3858 /* If rc should we check for EOPNOSUPP and
3859 disable the srvino flag? or in caller? */
3860 rc
= -EIO
; /* bad smb */
3862 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3863 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3864 struct file_chattr_info
*pfinfo
;
3865 /* BB Do we need a cast or hash here ? */
3867 cifs_dbg(FYI
, "Illegal size ret in GetExtAttr\n");
3871 pfinfo
= (struct file_chattr_info
*)
3872 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
3873 *pExtAttrBits
= le64_to_cpu(pfinfo
->mode
);
3874 *pMask
= le64_to_cpu(pfinfo
->mask
);
3878 cifs_buf_release(pSMB
);
3880 goto GetExtAttrRetry
;
3884 #endif /* CONFIG_POSIX */
3886 #ifdef CONFIG_CIFS_ACL
3888 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3889 * all NT TRANSACTS that we init here have total parm and data under about 400
3890 * bytes (to fit in small cifs buffer size), which is the case so far, it
3891 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3892 * returned setup area) and MaxParameterCount (returned parms size) must be set
3896 smb_init_nttransact(const __u16 sub_command
, const int setup_count
,
3897 const int parm_len
, struct cifs_tcon
*tcon
,
3902 struct smb_com_ntransact_req
*pSMB
;
3904 rc
= small_smb_init(SMB_COM_NT_TRANSACT
, 19 + setup_count
, tcon
,
3908 *ret_buf
= (void *)pSMB
;
3910 pSMB
->TotalParameterCount
= cpu_to_le32(parm_len
);
3911 pSMB
->TotalDataCount
= 0;
3912 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3913 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3914 pSMB
->DataCount
= pSMB
->TotalDataCount
;
3915 temp_offset
= offsetof(struct smb_com_ntransact_req
, Parms
) +
3916 (setup_count
* 2) - 4 /* for rfc1001 length itself */;
3917 pSMB
->ParameterOffset
= cpu_to_le32(temp_offset
);
3918 pSMB
->DataOffset
= cpu_to_le32(temp_offset
+ parm_len
);
3919 pSMB
->SetupCount
= setup_count
; /* no need to le convert byte fields */
3920 pSMB
->SubCommand
= cpu_to_le16(sub_command
);
3925 validate_ntransact(char *buf
, char **ppparm
, char **ppdata
,
3926 __u32
*pparmlen
, __u32
*pdatalen
)
3929 __u32 data_count
, data_offset
, parm_count
, parm_offset
;
3930 struct smb_com_ntransact_rsp
*pSMBr
;
3939 pSMBr
= (struct smb_com_ntransact_rsp
*)buf
;
3941 bcc
= get_bcc(&pSMBr
->hdr
);
3942 end_of_smb
= 2 /* sizeof byte count */ + bcc
+
3943 (char *)&pSMBr
->ByteCount
;
3945 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3946 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3947 parm_offset
= le32_to_cpu(pSMBr
->ParameterOffset
);
3948 parm_count
= le32_to_cpu(pSMBr
->ParameterCount
);
3950 *ppparm
= (char *)&pSMBr
->hdr
.Protocol
+ parm_offset
;
3951 *ppdata
= (char *)&pSMBr
->hdr
.Protocol
+ data_offset
;
3953 /* should we also check that parm and data areas do not overlap? */
3954 if (*ppparm
> end_of_smb
) {
3955 cifs_dbg(FYI
, "parms start after end of smb\n");
3957 } else if (parm_count
+ *ppparm
> end_of_smb
) {
3958 cifs_dbg(FYI
, "parm end after end of smb\n");
3960 } else if (*ppdata
> end_of_smb
) {
3961 cifs_dbg(FYI
, "data starts after end of smb\n");
3963 } else if (data_count
+ *ppdata
> end_of_smb
) {
3964 cifs_dbg(FYI
, "data %p + count %d (%p) past smb end %p start %p\n",
3965 *ppdata
, data_count
, (data_count
+ *ppdata
),
3968 } else if (parm_count
+ data_count
> bcc
) {
3969 cifs_dbg(FYI
, "parm count and data count larger than SMB\n");
3972 *pdatalen
= data_count
;
3973 *pparmlen
= parm_count
;
3977 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3979 CIFSSMBGetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3980 struct cifs_ntsd
**acl_inf
, __u32
*pbuflen
)
3984 QUERY_SEC_DESC_REQ
*pSMB
;
3986 struct kvec rsp_iov
;
3988 cifs_dbg(FYI
, "GetCifsACL\n");
3993 rc
= smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC
, 0,
3994 8 /* parm len */, tcon
, (void **) &pSMB
);
3998 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3999 /* BB TEST with big acls that might need to be e.g. larger than 16K */
4000 pSMB
->MaxSetupCount
= 0;
4001 pSMB
->Fid
= fid
; /* file handle always le */
4002 pSMB
->AclFlags
= cpu_to_le32(CIFS_ACL_OWNER
| CIFS_ACL_GROUP
|
4004 pSMB
->ByteCount
= cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
4005 inc_rfc1001_len(pSMB
, 11);
4006 iov
[0].iov_base
= (char *)pSMB
;
4007 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
4009 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovec */, &buf_type
,
4011 cifs_small_buf_release(pSMB
);
4012 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
4014 cifs_dbg(FYI
, "Send error in QuerySecDesc = %d\n", rc
);
4015 } else { /* decode response */
4019 struct smb_com_ntransact_rsp
*pSMBr
;
4022 /* validate_nttransact */
4023 rc
= validate_ntransact(rsp_iov
.iov_base
, (char **)&parm
,
4024 &pdata
, &parm_len
, pbuflen
);
4027 pSMBr
= (struct smb_com_ntransact_rsp
*)rsp_iov
.iov_base
;
4029 cifs_dbg(FYI
, "smb %p parm %p data %p\n",
4030 pSMBr
, parm
, *acl_inf
);
4032 if (le32_to_cpu(pSMBr
->ParameterCount
) != 4) {
4033 rc
= -EIO
; /* bad smb */
4038 /* BB check that data area is minimum length and as big as acl_len */
4040 acl_len
= le32_to_cpu(*parm
);
4041 if (acl_len
!= *pbuflen
) {
4042 cifs_dbg(VFS
, "acl length %d does not match %d\n",
4044 if (*pbuflen
> acl_len
)
4048 /* check if buffer is big enough for the acl
4049 header followed by the smallest SID */
4050 if ((*pbuflen
< sizeof(struct cifs_ntsd
) + 8) ||
4051 (*pbuflen
>= 64 * 1024)) {
4052 cifs_dbg(VFS
, "bad acl length %d\n", *pbuflen
);
4056 *acl_inf
= kmemdup(pdata
, *pbuflen
, GFP_KERNEL
);
4057 if (*acl_inf
== NULL
) {
4064 free_rsp_buf(buf_type
, rsp_iov
.iov_base
);
4069 CIFSSMBSetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
4070 struct cifs_ntsd
*pntsd
, __u32 acllen
, int aclflag
)
4072 __u16 byte_count
, param_count
, data_count
, param_offset
, data_offset
;
4074 int bytes_returned
= 0;
4075 SET_SEC_DESC_REQ
*pSMB
= NULL
;
4079 rc
= smb_init(SMB_COM_NT_TRANSACT
, 19, tcon
, (void **) &pSMB
, &pSMBr
);
4083 pSMB
->MaxSetupCount
= 0;
4087 param_offset
= offsetof(struct smb_com_transaction_ssec_req
, Fid
) - 4;
4088 data_count
= acllen
;
4089 data_offset
= param_offset
+ param_count
;
4090 byte_count
= 3 /* pad */ + param_count
;
4092 pSMB
->DataCount
= cpu_to_le32(data_count
);
4093 pSMB
->TotalDataCount
= pSMB
->DataCount
;
4094 pSMB
->MaxParameterCount
= cpu_to_le32(4);
4095 pSMB
->MaxDataCount
= cpu_to_le32(16384);
4096 pSMB
->ParameterCount
= cpu_to_le32(param_count
);
4097 pSMB
->ParameterOffset
= cpu_to_le32(param_offset
);
4098 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4099 pSMB
->DataOffset
= cpu_to_le32(data_offset
);
4100 pSMB
->SetupCount
= 0;
4101 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC
);
4102 pSMB
->ByteCount
= cpu_to_le16(byte_count
+data_count
);
4104 pSMB
->Fid
= fid
; /* file handle always le */
4105 pSMB
->Reserved2
= 0;
4106 pSMB
->AclFlags
= cpu_to_le32(aclflag
);
4108 if (pntsd
&& acllen
) {
4109 memcpy((char *)pSMBr
+ offsetof(struct smb_hdr
, Protocol
) +
4110 data_offset
, pntsd
, acllen
);
4111 inc_rfc1001_len(pSMB
, byte_count
+ data_count
);
4113 inc_rfc1001_len(pSMB
, byte_count
);
4115 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4116 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4118 cifs_dbg(FYI
, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4119 bytes_returned
, rc
);
4121 cifs_dbg(FYI
, "Set CIFS ACL returned %d\n", rc
);
4122 cifs_buf_release(pSMB
);
4125 goto setCifsAclRetry
;
4130 #endif /* CONFIG_CIFS_ACL */
4132 /* Legacy Query Path Information call for lookup to old servers such
4135 SMBQueryInformation(const unsigned int xid
, struct cifs_tcon
*tcon
,
4136 const char *search_name
, FILE_ALL_INFO
*data
,
4137 const struct nls_table
*nls_codepage
, int remap
)
4139 QUERY_INFORMATION_REQ
*pSMB
;
4140 QUERY_INFORMATION_RSP
*pSMBr
;
4145 cifs_dbg(FYI
, "In SMBQPath path %s\n", search_name
);
4147 rc
= smb_init(SMB_COM_QUERY_INFORMATION
, 0, tcon
, (void **) &pSMB
,
4152 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4154 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4155 search_name
, PATH_MAX
, nls_codepage
,
4157 name_len
++; /* trailing null */
4160 name_len
= strnlen(search_name
, PATH_MAX
);
4161 name_len
++; /* trailing null */
4162 strncpy(pSMB
->FileName
, search_name
, name_len
);
4164 pSMB
->BufferFormat
= 0x04;
4165 name_len
++; /* account for buffer type byte */
4166 inc_rfc1001_len(pSMB
, (__u16
)name_len
);
4167 pSMB
->ByteCount
= cpu_to_le16(name_len
);
4169 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4170 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4172 cifs_dbg(FYI
, "Send error in QueryInfo = %d\n", rc
);
4174 struct timespec64 ts
;
4175 __u32 time
= le32_to_cpu(pSMBr
->last_write_time
);
4177 /* decode response */
4178 /* BB FIXME - add time zone adjustment BB */
4179 memset(data
, 0, sizeof(FILE_ALL_INFO
));
4182 /* decode time fields */
4183 data
->ChangeTime
= cpu_to_le64(cifs_UnixTimeToNT(ts
));
4184 data
->LastWriteTime
= data
->ChangeTime
;
4185 data
->LastAccessTime
= 0;
4186 data
->AllocationSize
=
4187 cpu_to_le64(le32_to_cpu(pSMBr
->size
));
4188 data
->EndOfFile
= data
->AllocationSize
;
4190 cpu_to_le32(le16_to_cpu(pSMBr
->attr
));
4192 rc
= -EIO
; /* bad buffer passed in */
4194 cifs_buf_release(pSMB
);
4203 CIFSSMBQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4204 u16 netfid
, FILE_ALL_INFO
*pFindData
)
4206 struct smb_t2_qfi_req
*pSMB
= NULL
;
4207 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4210 __u16 params
, byte_count
;
4213 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4218 params
= 2 /* level */ + 2 /* fid */;
4219 pSMB
->t2
.TotalDataCount
= 0;
4220 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4221 /* BB find exact max data count below from sess structure BB */
4222 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4223 pSMB
->t2
.MaxSetupCount
= 0;
4224 pSMB
->t2
.Reserved
= 0;
4226 pSMB
->t2
.Timeout
= 0;
4227 pSMB
->t2
.Reserved2
= 0;
4228 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4230 pSMB
->t2
.DataCount
= 0;
4231 pSMB
->t2
.DataOffset
= 0;
4232 pSMB
->t2
.SetupCount
= 1;
4233 pSMB
->t2
.Reserved3
= 0;
4234 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4235 byte_count
= params
+ 1 /* pad */ ;
4236 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4237 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4238 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4241 inc_rfc1001_len(pSMB
, byte_count
);
4242 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4244 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4245 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4247 cifs_dbg(FYI
, "Send error in QFileInfo = %d", rc
);
4248 } else { /* decode response */
4249 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4251 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4253 else if (get_bcc(&pSMBr
->hdr
) < 40)
4254 rc
= -EIO
; /* bad smb */
4255 else if (pFindData
) {
4256 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4257 memcpy((char *) pFindData
,
4258 (char *) &pSMBr
->hdr
.Protocol
+
4259 data_offset
, sizeof(FILE_ALL_INFO
));
4263 cifs_buf_release(pSMB
);
4265 goto QFileInfoRetry
;
4271 CIFSSMBQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4272 const char *search_name
, FILE_ALL_INFO
*data
,
4273 int legacy
/* old style infolevel */,
4274 const struct nls_table
*nls_codepage
, int remap
)
4276 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4277 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4278 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4282 __u16 params
, byte_count
;
4284 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4286 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4291 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4293 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, search_name
,
4294 PATH_MAX
, nls_codepage
, remap
);
4295 name_len
++; /* trailing null */
4297 } else { /* BB improve the check for buffer overruns BB */
4298 name_len
= strnlen(search_name
, PATH_MAX
);
4299 name_len
++; /* trailing null */
4300 strncpy(pSMB
->FileName
, search_name
, name_len
);
4303 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4304 pSMB
->TotalDataCount
= 0;
4305 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4306 /* BB find exact max SMB PDU from sess structure BB */
4307 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4308 pSMB
->MaxSetupCount
= 0;
4312 pSMB
->Reserved2
= 0;
4313 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4314 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4315 pSMB
->DataCount
= 0;
4316 pSMB
->DataOffset
= 0;
4317 pSMB
->SetupCount
= 1;
4318 pSMB
->Reserved3
= 0;
4319 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4320 byte_count
= params
+ 1 /* pad */ ;
4321 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4322 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4324 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
4326 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4327 pSMB
->Reserved4
= 0;
4328 inc_rfc1001_len(pSMB
, byte_count
);
4329 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4331 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4332 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4334 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4335 } else { /* decode response */
4336 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4338 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4340 else if (!legacy
&& get_bcc(&pSMBr
->hdr
) < 40)
4341 rc
= -EIO
; /* bad smb */
4342 else if (legacy
&& get_bcc(&pSMBr
->hdr
) < 24)
4343 rc
= -EIO
; /* 24 or 26 expected but we do not read
4347 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4350 * On legacy responses we do not read the last field,
4351 * EAsize, fortunately since it varies by subdialect and
4352 * also note it differs on Set vs Get, ie two bytes or 4
4353 * bytes depending but we don't care here.
4356 size
= sizeof(FILE_INFO_STANDARD
);
4358 size
= sizeof(FILE_ALL_INFO
);
4359 memcpy((char *) data
, (char *) &pSMBr
->hdr
.Protocol
+
4364 cifs_buf_release(pSMB
);
4366 goto QPathInfoRetry
;
4372 CIFSSMBUnixQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4373 u16 netfid
, FILE_UNIX_BASIC_INFO
*pFindData
)
4375 struct smb_t2_qfi_req
*pSMB
= NULL
;
4376 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4379 __u16 params
, byte_count
;
4382 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4387 params
= 2 /* level */ + 2 /* fid */;
4388 pSMB
->t2
.TotalDataCount
= 0;
4389 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4390 /* BB find exact max data count below from sess structure BB */
4391 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4392 pSMB
->t2
.MaxSetupCount
= 0;
4393 pSMB
->t2
.Reserved
= 0;
4395 pSMB
->t2
.Timeout
= 0;
4396 pSMB
->t2
.Reserved2
= 0;
4397 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4399 pSMB
->t2
.DataCount
= 0;
4400 pSMB
->t2
.DataOffset
= 0;
4401 pSMB
->t2
.SetupCount
= 1;
4402 pSMB
->t2
.Reserved3
= 0;
4403 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4404 byte_count
= params
+ 1 /* pad */ ;
4405 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4406 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4407 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4410 inc_rfc1001_len(pSMB
, byte_count
);
4411 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4413 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4414 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4416 cifs_dbg(FYI
, "Send error in UnixQFileInfo = %d", rc
);
4417 } else { /* decode response */
4418 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4420 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4421 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4422 rc
= -EIO
; /* bad smb */
4424 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4425 memcpy((char *) pFindData
,
4426 (char *) &pSMBr
->hdr
.Protocol
+
4428 sizeof(FILE_UNIX_BASIC_INFO
));
4432 cifs_buf_release(pSMB
);
4434 goto UnixQFileInfoRetry
;
4440 CIFSSMBUnixQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4441 const unsigned char *searchName
,
4442 FILE_UNIX_BASIC_INFO
*pFindData
,
4443 const struct nls_table
*nls_codepage
, int remap
)
4445 /* SMB_QUERY_FILE_UNIX_BASIC */
4446 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4447 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4449 int bytes_returned
= 0;
4451 __u16 params
, byte_count
;
4453 cifs_dbg(FYI
, "In QPathInfo (Unix) the path %s\n", searchName
);
4455 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4460 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4462 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4463 PATH_MAX
, nls_codepage
, remap
);
4464 name_len
++; /* trailing null */
4466 } else { /* BB improve the check for buffer overruns BB */
4467 name_len
= strnlen(searchName
, PATH_MAX
);
4468 name_len
++; /* trailing null */
4469 strncpy(pSMB
->FileName
, searchName
, name_len
);
4472 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4473 pSMB
->TotalDataCount
= 0;
4474 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4475 /* BB find exact max SMB PDU from sess structure BB */
4476 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4477 pSMB
->MaxSetupCount
= 0;
4481 pSMB
->Reserved2
= 0;
4482 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4483 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4484 pSMB
->DataCount
= 0;
4485 pSMB
->DataOffset
= 0;
4486 pSMB
->SetupCount
= 1;
4487 pSMB
->Reserved3
= 0;
4488 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4489 byte_count
= params
+ 1 /* pad */ ;
4490 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4491 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4492 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4493 pSMB
->Reserved4
= 0;
4494 inc_rfc1001_len(pSMB
, byte_count
);
4495 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4497 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4498 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4500 cifs_dbg(FYI
, "Send error in UnixQPathInfo = %d", rc
);
4501 } else { /* decode response */
4502 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4504 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4505 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4506 rc
= -EIO
; /* bad smb */
4508 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4509 memcpy((char *) pFindData
,
4510 (char *) &pSMBr
->hdr
.Protocol
+
4512 sizeof(FILE_UNIX_BASIC_INFO
));
4515 cifs_buf_release(pSMB
);
4517 goto UnixQPathInfoRetry
;
4522 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4524 CIFSFindFirst(const unsigned int xid
, struct cifs_tcon
*tcon
,
4525 const char *searchName
, struct cifs_sb_info
*cifs_sb
,
4526 __u16
*pnetfid
, __u16 search_flags
,
4527 struct cifs_search_info
*psrch_inf
, bool msearch
)
4529 /* level 257 SMB_ */
4530 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
4531 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
4532 T2_FFIRST_RSP_PARMS
*parms
;
4534 int bytes_returned
= 0;
4535 int name_len
, remap
;
4536 __u16 params
, byte_count
;
4537 struct nls_table
*nls_codepage
;
4539 cifs_dbg(FYI
, "In FindFirst for %s\n", searchName
);
4542 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4547 nls_codepage
= cifs_sb
->local_nls
;
4548 remap
= cifs_remap(cifs_sb
);
4550 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4552 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4553 PATH_MAX
, nls_codepage
, remap
);
4554 /* We can not add the asterik earlier in case
4555 it got remapped to 0xF03A as if it were part of the
4556 directory name instead of a wildcard */
4559 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4560 pSMB
->FileName
[name_len
+1] = 0;
4561 pSMB
->FileName
[name_len
+2] = '*';
4562 pSMB
->FileName
[name_len
+3] = 0;
4563 name_len
+= 4; /* now the trailing null */
4564 /* null terminate just in case */
4565 pSMB
->FileName
[name_len
] = 0;
4566 pSMB
->FileName
[name_len
+1] = 0;
4569 } else { /* BB add check for overrun of SMB buf BB */
4570 name_len
= strnlen(searchName
, PATH_MAX
);
4571 /* BB fix here and in unicode clause above ie
4572 if (name_len > buffersize-header)
4573 free buffer exit; BB */
4574 strncpy(pSMB
->FileName
, searchName
, name_len
);
4576 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4577 pSMB
->FileName
[name_len
+1] = '*';
4578 pSMB
->FileName
[name_len
+2] = 0;
4583 params
= 12 + name_len
/* includes null */ ;
4584 pSMB
->TotalDataCount
= 0; /* no EAs */
4585 pSMB
->MaxParameterCount
= cpu_to_le16(10);
4586 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4587 pSMB
->MaxSetupCount
= 0;
4591 pSMB
->Reserved2
= 0;
4592 byte_count
= params
+ 1 /* pad */ ;
4593 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4594 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4595 pSMB
->ParameterOffset
= cpu_to_le16(
4596 offsetof(struct smb_com_transaction2_ffirst_req
, SearchAttributes
)
4598 pSMB
->DataCount
= 0;
4599 pSMB
->DataOffset
= 0;
4600 pSMB
->SetupCount
= 1; /* one byte, no need to make endian neutral */
4601 pSMB
->Reserved3
= 0;
4602 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
4603 pSMB
->SearchAttributes
=
4604 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
4606 pSMB
->SearchCount
= cpu_to_le16(CIFSMaxBufSize
/sizeof(FILE_UNIX_INFO
));
4607 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4608 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4610 /* BB what should we set StorageType to? Does it matter? BB */
4611 pSMB
->SearchStorageType
= 0;
4612 inc_rfc1001_len(pSMB
, byte_count
);
4613 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4615 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4616 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4617 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_ffirst
);
4619 if (rc
) {/* BB add logic to retry regular search if Unix search
4620 rejected unexpectedly by server */
4621 /* BB Add code to handle unsupported level rc */
4622 cifs_dbg(FYI
, "Error in FindFirst = %d\n", rc
);
4624 cifs_buf_release(pSMB
);
4626 /* BB eventually could optimize out free and realloc of buf */
4629 goto findFirstRetry
;
4630 } else { /* decode response */
4631 /* BB remember to free buffer if error BB */
4632 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4636 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4637 psrch_inf
->unicode
= true;
4639 psrch_inf
->unicode
= false;
4641 psrch_inf
->ntwrk_buf_start
= (char *)pSMBr
;
4642 psrch_inf
->smallBuf
= 0;
4643 psrch_inf
->srch_entries_start
=
4644 (char *) &pSMBr
->hdr
.Protocol
+
4645 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4646 parms
= (T2_FFIRST_RSP_PARMS
*)((char *) &pSMBr
->hdr
.Protocol
+
4647 le16_to_cpu(pSMBr
->t2
.ParameterOffset
));
4649 if (parms
->EndofSearch
)
4650 psrch_inf
->endOfSearch
= true;
4652 psrch_inf
->endOfSearch
= false;
4654 psrch_inf
->entries_in_buffer
=
4655 le16_to_cpu(parms
->SearchCount
);
4656 psrch_inf
->index_of_last_entry
= 2 /* skip . and .. */ +
4657 psrch_inf
->entries_in_buffer
;
4658 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4659 if (CIFSMaxBufSize
< lnoff
) {
4660 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4661 psrch_inf
->last_entry
= NULL
;
4665 psrch_inf
->last_entry
= psrch_inf
->srch_entries_start
+
4669 *pnetfid
= parms
->SearchHandle
;
4671 cifs_buf_release(pSMB
);
4678 int CIFSFindNext(const unsigned int xid
, struct cifs_tcon
*tcon
,
4679 __u16 searchHandle
, __u16 search_flags
,
4680 struct cifs_search_info
*psrch_inf
)
4682 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
4683 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
4684 T2_FNEXT_RSP_PARMS
*parms
;
4685 char *response_data
;
4688 unsigned int name_len
;
4689 __u16 params
, byte_count
;
4691 cifs_dbg(FYI
, "In FindNext\n");
4693 if (psrch_inf
->endOfSearch
)
4696 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4701 params
= 14; /* includes 2 bytes of null string, converted to LE below*/
4703 pSMB
->TotalDataCount
= 0; /* no EAs */
4704 pSMB
->MaxParameterCount
= cpu_to_le16(8);
4705 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4706 pSMB
->MaxSetupCount
= 0;
4710 pSMB
->Reserved2
= 0;
4711 pSMB
->ParameterOffset
= cpu_to_le16(
4712 offsetof(struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
4713 pSMB
->DataCount
= 0;
4714 pSMB
->DataOffset
= 0;
4715 pSMB
->SetupCount
= 1;
4716 pSMB
->Reserved3
= 0;
4717 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
4718 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
4720 cpu_to_le16(CIFSMaxBufSize
/ sizeof(FILE_UNIX_INFO
));
4721 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4722 pSMB
->ResumeKey
= psrch_inf
->resume_key
;
4723 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4725 name_len
= psrch_inf
->resume_name_len
;
4727 if (name_len
< PATH_MAX
) {
4728 memcpy(pSMB
->ResumeFileName
, psrch_inf
->presume_name
, name_len
);
4729 byte_count
+= name_len
;
4730 /* 14 byte parm len above enough for 2 byte null terminator */
4731 pSMB
->ResumeFileName
[name_len
] = 0;
4732 pSMB
->ResumeFileName
[name_len
+1] = 0;
4735 goto FNext2_err_exit
;
4737 byte_count
= params
+ 1 /* pad */ ;
4738 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4739 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4740 inc_rfc1001_len(pSMB
, byte_count
);
4741 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4743 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4744 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4745 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fnext
);
4748 psrch_inf
->endOfSearch
= true;
4749 cifs_buf_release(pSMB
);
4750 rc
= 0; /* search probably was closed at end of search*/
4752 cifs_dbg(FYI
, "FindNext returned = %d\n", rc
);
4753 } else { /* decode response */
4754 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4759 /* BB fixme add lock for file (srch_info) struct here */
4760 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4761 psrch_inf
->unicode
= true;
4763 psrch_inf
->unicode
= false;
4764 response_data
= (char *) &pSMBr
->hdr
.Protocol
+
4765 le16_to_cpu(pSMBr
->t2
.ParameterOffset
);
4766 parms
= (T2_FNEXT_RSP_PARMS
*)response_data
;
4767 response_data
= (char *)&pSMBr
->hdr
.Protocol
+
4768 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4769 if (psrch_inf
->smallBuf
)
4770 cifs_small_buf_release(
4771 psrch_inf
->ntwrk_buf_start
);
4773 cifs_buf_release(psrch_inf
->ntwrk_buf_start
);
4774 psrch_inf
->srch_entries_start
= response_data
;
4775 psrch_inf
->ntwrk_buf_start
= (char *)pSMB
;
4776 psrch_inf
->smallBuf
= 0;
4777 if (parms
->EndofSearch
)
4778 psrch_inf
->endOfSearch
= true;
4780 psrch_inf
->endOfSearch
= false;
4781 psrch_inf
->entries_in_buffer
=
4782 le16_to_cpu(parms
->SearchCount
);
4783 psrch_inf
->index_of_last_entry
+=
4784 psrch_inf
->entries_in_buffer
;
4785 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4786 if (CIFSMaxBufSize
< lnoff
) {
4787 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4788 psrch_inf
->last_entry
= NULL
;
4791 psrch_inf
->last_entry
=
4792 psrch_inf
->srch_entries_start
+ lnoff
;
4794 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4795 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4797 /* BB fixme add unlock here */
4802 /* BB On error, should we leave previous search buf (and count and
4803 last entry fields) intact or free the previous one? */
4805 /* Note: On -EAGAIN error only caller can retry on handle based calls
4806 since file handle passed in no longer valid */
4809 cifs_buf_release(pSMB
);
4814 CIFSFindClose(const unsigned int xid
, struct cifs_tcon
*tcon
,
4815 const __u16 searchHandle
)
4818 FINDCLOSE_REQ
*pSMB
= NULL
;
4820 cifs_dbg(FYI
, "In CIFSSMBFindClose\n");
4821 rc
= small_smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **)&pSMB
);
4823 /* no sense returning error if session restarted
4824 as file handle has been closed */
4830 pSMB
->FileID
= searchHandle
;
4831 pSMB
->ByteCount
= 0;
4832 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
4833 cifs_small_buf_release(pSMB
);
4835 cifs_dbg(VFS
, "Send error in FindClose = %d\n", rc
);
4837 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fclose
);
4839 /* Since session is dead, search handle closed on server already */
4847 CIFSGetSrvInodeNumber(const unsigned int xid
, struct cifs_tcon
*tcon
,
4848 const char *search_name
, __u64
*inode_number
,
4849 const struct nls_table
*nls_codepage
, int remap
)
4852 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4853 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4854 int name_len
, bytes_returned
;
4855 __u16 params
, byte_count
;
4857 cifs_dbg(FYI
, "In GetSrvInodeNum for %s\n", search_name
);
4861 GetInodeNumberRetry
:
4862 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4867 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4869 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4870 search_name
, PATH_MAX
, nls_codepage
,
4872 name_len
++; /* trailing null */
4874 } else { /* BB improve the check for buffer overruns BB */
4875 name_len
= strnlen(search_name
, PATH_MAX
);
4876 name_len
++; /* trailing null */
4877 strncpy(pSMB
->FileName
, search_name
, name_len
);
4880 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
4881 pSMB
->TotalDataCount
= 0;
4882 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4883 /* BB find exact max data count below from sess structure BB */
4884 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4885 pSMB
->MaxSetupCount
= 0;
4889 pSMB
->Reserved2
= 0;
4890 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4891 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4892 pSMB
->DataCount
= 0;
4893 pSMB
->DataOffset
= 0;
4894 pSMB
->SetupCount
= 1;
4895 pSMB
->Reserved3
= 0;
4896 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4897 byte_count
= params
+ 1 /* pad */ ;
4898 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4899 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4900 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO
);
4901 pSMB
->Reserved4
= 0;
4902 inc_rfc1001_len(pSMB
, byte_count
);
4903 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4905 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4906 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4908 cifs_dbg(FYI
, "error %d in QueryInternalInfo\n", rc
);
4910 /* decode response */
4911 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4912 /* BB also check enough total bytes returned */
4913 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
4914 /* If rc should we check for EOPNOSUPP and
4915 disable the srvino flag? or in caller? */
4916 rc
= -EIO
; /* bad smb */
4918 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4919 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
4920 struct file_internal_info
*pfinfo
;
4921 /* BB Do we need a cast or hash here ? */
4923 cifs_dbg(FYI
, "Illegal size ret in QryIntrnlInf\n");
4925 goto GetInodeNumOut
;
4927 pfinfo
= (struct file_internal_info
*)
4928 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
4929 *inode_number
= le64_to_cpu(pfinfo
->UniqueId
);
4933 cifs_buf_release(pSMB
);
4935 goto GetInodeNumberRetry
;
4940 CIFSGetDFSRefer(const unsigned int xid
, struct cifs_ses
*ses
,
4941 const char *search_name
, struct dfs_info3_param
**target_nodes
,
4942 unsigned int *num_of_nodes
,
4943 const struct nls_table
*nls_codepage
, int remap
)
4945 /* TRANS2_GET_DFS_REFERRAL */
4946 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
4947 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
4951 __u16 params
, byte_count
;
4953 *target_nodes
= NULL
;
4955 cifs_dbg(FYI
, "In GetDFSRefer the path %s\n", search_name
);
4956 if (ses
== NULL
|| ses
->tcon_ipc
== NULL
)
4960 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, ses
->tcon_ipc
, (void **) &pSMB
,
4965 /* server pointer checked in called function,
4966 but should never be null here anyway */
4967 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
4968 pSMB
->hdr
.Tid
= ses
->tcon_ipc
->tid
;
4969 pSMB
->hdr
.Uid
= ses
->Suid
;
4970 if (ses
->capabilities
& CAP_STATUS32
)
4971 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
4972 if (ses
->capabilities
& CAP_DFS
)
4973 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
4975 if (ses
->capabilities
& CAP_UNICODE
) {
4976 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
4978 cifsConvertToUTF16((__le16
*) pSMB
->RequestFileName
,
4979 search_name
, PATH_MAX
, nls_codepage
,
4981 name_len
++; /* trailing null */
4983 } else { /* BB improve the check for buffer overruns BB */
4984 name_len
= strnlen(search_name
, PATH_MAX
);
4985 name_len
++; /* trailing null */
4986 strncpy(pSMB
->RequestFileName
, search_name
, name_len
);
4989 if (ses
->server
->sign
)
4990 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
4992 pSMB
->hdr
.Uid
= ses
->Suid
;
4994 params
= 2 /* level */ + name_len
/*includes null */ ;
4995 pSMB
->TotalDataCount
= 0;
4996 pSMB
->DataCount
= 0;
4997 pSMB
->DataOffset
= 0;
4998 pSMB
->MaxParameterCount
= 0;
4999 /* BB find exact max SMB PDU from sess structure BB */
5000 pSMB
->MaxDataCount
= cpu_to_le16(4000);
5001 pSMB
->MaxSetupCount
= 0;
5005 pSMB
->Reserved2
= 0;
5006 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5007 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
5008 pSMB
->SetupCount
= 1;
5009 pSMB
->Reserved3
= 0;
5010 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
5011 byte_count
= params
+ 3 /* pad */ ;
5012 pSMB
->ParameterCount
= cpu_to_le16(params
);
5013 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5014 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
5015 inc_rfc1001_len(pSMB
, byte_count
);
5016 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5018 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
5019 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5021 cifs_dbg(FYI
, "Send error in GetDFSRefer = %d\n", rc
);
5024 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5026 /* BB Also check if enough total bytes returned? */
5027 if (rc
|| get_bcc(&pSMBr
->hdr
) < 17) {
5028 rc
= -EIO
; /* bad smb */
5032 cifs_dbg(FYI
, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
5033 get_bcc(&pSMBr
->hdr
), le16_to_cpu(pSMBr
->t2
.DataOffset
));
5035 /* parse returned result into more usable form */
5036 rc
= parse_dfs_referrals(&pSMBr
->dfs_data
,
5037 le16_to_cpu(pSMBr
->t2
.DataCount
),
5038 num_of_nodes
, target_nodes
, nls_codepage
,
5040 (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) != 0);
5043 cifs_buf_release(pSMB
);
5051 /* Query File System Info such as free space to old servers such as Win 9x */
5053 SMBOldQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5054 struct kstatfs
*FSData
)
5056 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
5057 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5058 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5059 FILE_SYSTEM_ALLOC_INFO
*response_data
;
5061 int bytes_returned
= 0;
5062 __u16 params
, byte_count
;
5064 cifs_dbg(FYI
, "OldQFSInfo\n");
5066 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5071 params
= 2; /* level */
5072 pSMB
->TotalDataCount
= 0;
5073 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5074 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5075 pSMB
->MaxSetupCount
= 0;
5079 pSMB
->Reserved2
= 0;
5080 byte_count
= params
+ 1 /* pad */ ;
5081 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5082 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5083 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5084 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5085 pSMB
->DataCount
= 0;
5086 pSMB
->DataOffset
= 0;
5087 pSMB
->SetupCount
= 1;
5088 pSMB
->Reserved3
= 0;
5089 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5090 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_ALLOCATION
);
5091 inc_rfc1001_len(pSMB
, byte_count
);
5092 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5094 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5095 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5097 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5098 } else { /* decode response */
5099 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5101 if (rc
|| get_bcc(&pSMBr
->hdr
) < 18)
5102 rc
= -EIO
; /* bad smb */
5104 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5105 cifs_dbg(FYI
, "qfsinf resp BCC: %d Offset %d\n",
5106 get_bcc(&pSMBr
->hdr
), data_offset
);
5108 response_data
= (FILE_SYSTEM_ALLOC_INFO
*)
5109 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
5111 le16_to_cpu(response_data
->BytesPerSector
) *
5112 le32_to_cpu(response_data
->
5113 SectorsPerAllocationUnit
);
5115 * much prefer larger but if server doesn't report
5116 * a valid size than 4K is a reasonable minimum
5118 if (FSData
->f_bsize
< 512)
5119 FSData
->f_bsize
= 4096;
5122 le32_to_cpu(response_data
->TotalAllocationUnits
);
5123 FSData
->f_bfree
= FSData
->f_bavail
=
5124 le32_to_cpu(response_data
->FreeAllocationUnits
);
5125 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5126 (unsigned long long)FSData
->f_blocks
,
5127 (unsigned long long)FSData
->f_bfree
,
5131 cifs_buf_release(pSMB
);
5134 goto oldQFSInfoRetry
;
5140 CIFSSMBQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5141 struct kstatfs
*FSData
)
5143 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5144 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5145 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5146 FILE_SYSTEM_INFO
*response_data
;
5148 int bytes_returned
= 0;
5149 __u16 params
, byte_count
;
5151 cifs_dbg(FYI
, "In QFSInfo\n");
5153 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5158 params
= 2; /* level */
5159 pSMB
->TotalDataCount
= 0;
5160 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5161 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5162 pSMB
->MaxSetupCount
= 0;
5166 pSMB
->Reserved2
= 0;
5167 byte_count
= params
+ 1 /* pad */ ;
5168 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5169 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5170 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5171 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5172 pSMB
->DataCount
= 0;
5173 pSMB
->DataOffset
= 0;
5174 pSMB
->SetupCount
= 1;
5175 pSMB
->Reserved3
= 0;
5176 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5177 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
5178 inc_rfc1001_len(pSMB
, byte_count
);
5179 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5181 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5182 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5184 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5185 } else { /* decode response */
5186 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5188 if (rc
|| get_bcc(&pSMBr
->hdr
) < 24)
5189 rc
= -EIO
; /* bad smb */
5191 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5195 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5198 le32_to_cpu(response_data
->BytesPerSector
) *
5199 le32_to_cpu(response_data
->
5200 SectorsPerAllocationUnit
);
5202 * much prefer larger but if server doesn't report
5203 * a valid size than 4K is a reasonable minimum
5205 if (FSData
->f_bsize
< 512)
5206 FSData
->f_bsize
= 4096;
5209 le64_to_cpu(response_data
->TotalAllocationUnits
);
5210 FSData
->f_bfree
= FSData
->f_bavail
=
5211 le64_to_cpu(response_data
->FreeAllocationUnits
);
5212 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5213 (unsigned long long)FSData
->f_blocks
,
5214 (unsigned long long)FSData
->f_bfree
,
5218 cifs_buf_release(pSMB
);
5227 CIFSSMBQFSAttributeInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5229 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5230 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5231 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5232 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
5234 int bytes_returned
= 0;
5235 __u16 params
, byte_count
;
5237 cifs_dbg(FYI
, "In QFSAttributeInfo\n");
5239 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5244 params
= 2; /* level */
5245 pSMB
->TotalDataCount
= 0;
5246 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5247 /* BB find exact max SMB PDU from sess structure BB */
5248 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5249 pSMB
->MaxSetupCount
= 0;
5253 pSMB
->Reserved2
= 0;
5254 byte_count
= params
+ 1 /* pad */ ;
5255 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5256 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5257 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5258 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5259 pSMB
->DataCount
= 0;
5260 pSMB
->DataOffset
= 0;
5261 pSMB
->SetupCount
= 1;
5262 pSMB
->Reserved3
= 0;
5263 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5264 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
5265 inc_rfc1001_len(pSMB
, byte_count
);
5266 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5268 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5269 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5271 cifs_dbg(VFS
, "Send error in QFSAttributeInfo = %d\n", rc
);
5272 } else { /* decode response */
5273 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5275 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5276 /* BB also check if enough bytes returned */
5277 rc
= -EIO
; /* bad smb */
5279 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5281 (FILE_SYSTEM_ATTRIBUTE_INFO
5282 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5284 memcpy(&tcon
->fsAttrInfo
, response_data
,
5285 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO
));
5288 cifs_buf_release(pSMB
);
5291 goto QFSAttributeRetry
;
5297 CIFSSMBQFSDeviceInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5299 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5300 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5301 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5302 FILE_SYSTEM_DEVICE_INFO
*response_data
;
5304 int bytes_returned
= 0;
5305 __u16 params
, byte_count
;
5307 cifs_dbg(FYI
, "In QFSDeviceInfo\n");
5309 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5314 params
= 2; /* level */
5315 pSMB
->TotalDataCount
= 0;
5316 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5317 /* BB find exact max SMB PDU from sess structure BB */
5318 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5319 pSMB
->MaxSetupCount
= 0;
5323 pSMB
->Reserved2
= 0;
5324 byte_count
= params
+ 1 /* pad */ ;
5325 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5326 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5327 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5328 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5330 pSMB
->DataCount
= 0;
5331 pSMB
->DataOffset
= 0;
5332 pSMB
->SetupCount
= 1;
5333 pSMB
->Reserved3
= 0;
5334 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5335 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
5336 inc_rfc1001_len(pSMB
, byte_count
);
5337 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5339 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5340 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5342 cifs_dbg(FYI
, "Send error in QFSDeviceInfo = %d\n", rc
);
5343 } else { /* decode response */
5344 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5346 if (rc
|| get_bcc(&pSMBr
->hdr
) <
5347 sizeof(FILE_SYSTEM_DEVICE_INFO
))
5348 rc
= -EIO
; /* bad smb */
5350 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5352 (FILE_SYSTEM_DEVICE_INFO
*)
5353 (((char *) &pSMBr
->hdr
.Protocol
) +
5355 memcpy(&tcon
->fsDevInfo
, response_data
,
5356 sizeof(FILE_SYSTEM_DEVICE_INFO
));
5359 cifs_buf_release(pSMB
);
5362 goto QFSDeviceRetry
;
5368 CIFSSMBQFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5370 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5371 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5372 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5373 FILE_SYSTEM_UNIX_INFO
*response_data
;
5375 int bytes_returned
= 0;
5376 __u16 params
, byte_count
;
5378 cifs_dbg(FYI
, "In QFSUnixInfo\n");
5380 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5381 (void **) &pSMB
, (void **) &pSMBr
);
5385 params
= 2; /* level */
5386 pSMB
->TotalDataCount
= 0;
5387 pSMB
->DataCount
= 0;
5388 pSMB
->DataOffset
= 0;
5389 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5390 /* BB find exact max SMB PDU from sess structure BB */
5391 pSMB
->MaxDataCount
= cpu_to_le16(100);
5392 pSMB
->MaxSetupCount
= 0;
5396 pSMB
->Reserved2
= 0;
5397 byte_count
= params
+ 1 /* pad */ ;
5398 pSMB
->ParameterCount
= cpu_to_le16(params
);
5399 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5400 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5401 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5402 pSMB
->SetupCount
= 1;
5403 pSMB
->Reserved3
= 0;
5404 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5405 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
5406 inc_rfc1001_len(pSMB
, byte_count
);
5407 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5409 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5410 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5412 cifs_dbg(VFS
, "Send error in QFSUnixInfo = %d\n", rc
);
5413 } else { /* decode response */
5414 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5416 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5417 rc
= -EIO
; /* bad smb */
5419 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5421 (FILE_SYSTEM_UNIX_INFO
5422 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5424 memcpy(&tcon
->fsUnixInfo
, response_data
,
5425 sizeof(FILE_SYSTEM_UNIX_INFO
));
5428 cifs_buf_release(pSMB
);
5438 CIFSSMBSetFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
, __u64 cap
)
5440 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5441 TRANSACTION2_SETFSI_REQ
*pSMB
= NULL
;
5442 TRANSACTION2_SETFSI_RSP
*pSMBr
= NULL
;
5444 int bytes_returned
= 0;
5445 __u16 params
, param_offset
, offset
, byte_count
;
5447 cifs_dbg(FYI
, "In SETFSUnixInfo\n");
5449 /* BB switch to small buf init to save memory */
5450 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5451 (void **) &pSMB
, (void **) &pSMBr
);
5455 params
= 4; /* 2 bytes zero followed by info level. */
5456 pSMB
->MaxSetupCount
= 0;
5460 pSMB
->Reserved2
= 0;
5461 param_offset
= offsetof(struct smb_com_transaction2_setfsi_req
, FileNum
)
5463 offset
= param_offset
+ params
;
5465 pSMB
->MaxParameterCount
= cpu_to_le16(4);
5466 /* BB find exact max SMB PDU from sess structure BB */
5467 pSMB
->MaxDataCount
= cpu_to_le16(100);
5468 pSMB
->SetupCount
= 1;
5469 pSMB
->Reserved3
= 0;
5470 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FS_INFORMATION
);
5471 byte_count
= 1 /* pad */ + params
+ 12;
5473 pSMB
->DataCount
= cpu_to_le16(12);
5474 pSMB
->ParameterCount
= cpu_to_le16(params
);
5475 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5476 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5477 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5478 pSMB
->DataOffset
= cpu_to_le16(offset
);
5482 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_CIFS_UNIX_INFO
);
5485 pSMB
->ClientUnixMajor
= cpu_to_le16(CIFS_UNIX_MAJOR_VERSION
);
5486 pSMB
->ClientUnixMinor
= cpu_to_le16(CIFS_UNIX_MINOR_VERSION
);
5487 pSMB
->ClientUnixCap
= cpu_to_le64(cap
);
5489 inc_rfc1001_len(pSMB
, byte_count
);
5490 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5492 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5493 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5495 cifs_dbg(VFS
, "Send error in SETFSUnixInfo = %d\n", rc
);
5496 } else { /* decode response */
5497 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5499 rc
= -EIO
; /* bad smb */
5501 cifs_buf_release(pSMB
);
5504 goto SETFSUnixRetry
;
5512 CIFSSMBQFSPosixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5513 struct kstatfs
*FSData
)
5515 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5516 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5517 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5518 FILE_SYSTEM_POSIX_INFO
*response_data
;
5520 int bytes_returned
= 0;
5521 __u16 params
, byte_count
;
5523 cifs_dbg(FYI
, "In QFSPosixInfo\n");
5525 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5530 params
= 2; /* level */
5531 pSMB
->TotalDataCount
= 0;
5532 pSMB
->DataCount
= 0;
5533 pSMB
->DataOffset
= 0;
5534 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5535 /* BB find exact max SMB PDU from sess structure BB */
5536 pSMB
->MaxDataCount
= cpu_to_le16(100);
5537 pSMB
->MaxSetupCount
= 0;
5541 pSMB
->Reserved2
= 0;
5542 byte_count
= params
+ 1 /* pad */ ;
5543 pSMB
->ParameterCount
= cpu_to_le16(params
);
5544 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5545 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5546 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5547 pSMB
->SetupCount
= 1;
5548 pSMB
->Reserved3
= 0;
5549 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5550 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_FS_INFO
);
5551 inc_rfc1001_len(pSMB
, byte_count
);
5552 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5554 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5555 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5557 cifs_dbg(FYI
, "Send error in QFSUnixInfo = %d\n", rc
);
5558 } else { /* decode response */
5559 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5561 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5562 rc
= -EIO
; /* bad smb */
5564 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5566 (FILE_SYSTEM_POSIX_INFO
5567 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5570 le32_to_cpu(response_data
->BlockSize
);
5572 * much prefer larger but if server doesn't report
5573 * a valid size than 4K is a reasonable minimum
5575 if (FSData
->f_bsize
< 512)
5576 FSData
->f_bsize
= 4096;
5579 le64_to_cpu(response_data
->TotalBlocks
);
5581 le64_to_cpu(response_data
->BlocksAvail
);
5582 if (response_data
->UserBlocksAvail
== cpu_to_le64(-1)) {
5583 FSData
->f_bavail
= FSData
->f_bfree
;
5586 le64_to_cpu(response_data
->UserBlocksAvail
);
5588 if (response_data
->TotalFileNodes
!= cpu_to_le64(-1))
5590 le64_to_cpu(response_data
->TotalFileNodes
);
5591 if (response_data
->FreeFileNodes
!= cpu_to_le64(-1))
5593 le64_to_cpu(response_data
->FreeFileNodes
);
5596 cifs_buf_release(pSMB
);
5606 * We can not use write of zero bytes trick to set file size due to need for
5607 * large file support. Also note that this SetPathInfo is preferred to
5608 * SetFileInfo based method in next routine which is only needed to work around
5609 * a sharing violation bugin Samba which this routine can run into.
5612 CIFSSMBSetEOF(const unsigned int xid
, struct cifs_tcon
*tcon
,
5613 const char *file_name
, __u64 size
, struct cifs_sb_info
*cifs_sb
,
5614 bool set_allocation
)
5616 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5617 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5618 struct file_end_of_file_info
*parm_data
;
5621 int bytes_returned
= 0;
5622 int remap
= cifs_remap(cifs_sb
);
5624 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
5626 cifs_dbg(FYI
, "In SetEOF\n");
5628 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5633 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5635 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5636 PATH_MAX
, cifs_sb
->local_nls
, remap
);
5637 name_len
++; /* trailing null */
5639 } else { /* BB improve the check for buffer overruns BB */
5640 name_len
= strnlen(file_name
, PATH_MAX
);
5641 name_len
++; /* trailing null */
5642 strncpy(pSMB
->FileName
, file_name
, name_len
);
5644 params
= 6 + name_len
;
5645 data_count
= sizeof(struct file_end_of_file_info
);
5646 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5647 pSMB
->MaxDataCount
= cpu_to_le16(4100);
5648 pSMB
->MaxSetupCount
= 0;
5652 pSMB
->Reserved2
= 0;
5653 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5654 InformationLevel
) - 4;
5655 offset
= param_offset
+ params
;
5656 if (set_allocation
) {
5657 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5658 pSMB
->InformationLevel
=
5659 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5661 pSMB
->InformationLevel
=
5662 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5663 } else /* Set File Size */ {
5664 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5665 pSMB
->InformationLevel
=
5666 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5668 pSMB
->InformationLevel
=
5669 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5673 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
5675 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5676 pSMB
->DataOffset
= cpu_to_le16(offset
);
5677 pSMB
->SetupCount
= 1;
5678 pSMB
->Reserved3
= 0;
5679 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5680 byte_count
= 3 /* pad */ + params
+ data_count
;
5681 pSMB
->DataCount
= cpu_to_le16(data_count
);
5682 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5683 pSMB
->ParameterCount
= cpu_to_le16(params
);
5684 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5685 pSMB
->Reserved4
= 0;
5686 inc_rfc1001_len(pSMB
, byte_count
);
5687 parm_data
->FileSize
= cpu_to_le64(size
);
5688 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5689 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5690 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5692 cifs_dbg(FYI
, "SetPathInfo (file size) returned %d\n", rc
);
5694 cifs_buf_release(pSMB
);
5703 CIFSSMBSetFileSize(const unsigned int xid
, struct cifs_tcon
*tcon
,
5704 struct cifsFileInfo
*cfile
, __u64 size
, bool set_allocation
)
5706 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5707 struct file_end_of_file_info
*parm_data
;
5709 __u16 params
, param_offset
, offset
, byte_count
, count
;
5711 cifs_dbg(FYI
, "SetFileSize (via SetFileInfo) %lld\n",
5713 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5718 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)cfile
->pid
);
5719 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(cfile
->pid
>> 16));
5722 pSMB
->MaxSetupCount
= 0;
5726 pSMB
->Reserved2
= 0;
5727 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5728 offset
= param_offset
+ params
;
5730 count
= sizeof(struct file_end_of_file_info
);
5731 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5732 /* BB find exact max SMB PDU from sess structure BB */
5733 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5734 pSMB
->SetupCount
= 1;
5735 pSMB
->Reserved3
= 0;
5736 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5737 byte_count
= 3 /* pad */ + params
+ count
;
5738 pSMB
->DataCount
= cpu_to_le16(count
);
5739 pSMB
->ParameterCount
= cpu_to_le16(params
);
5740 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5741 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5742 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5744 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
)
5746 pSMB
->DataOffset
= cpu_to_le16(offset
);
5747 parm_data
->FileSize
= cpu_to_le64(size
);
5748 pSMB
->Fid
= cfile
->fid
.netfid
;
5749 if (set_allocation
) {
5750 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5751 pSMB
->InformationLevel
=
5752 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5754 pSMB
->InformationLevel
=
5755 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5756 } else /* Set File Size */ {
5757 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5758 pSMB
->InformationLevel
=
5759 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5761 pSMB
->InformationLevel
=
5762 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5764 pSMB
->Reserved4
= 0;
5765 inc_rfc1001_len(pSMB
, byte_count
);
5766 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5767 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5768 cifs_small_buf_release(pSMB
);
5770 cifs_dbg(FYI
, "Send error in SetFileInfo (SetFileSize) = %d\n",
5774 /* Note: On -EAGAIN error only caller can retry on handle based calls
5775 since file handle passed in no longer valid */
5780 /* Some legacy servers such as NT4 require that the file times be set on
5781 an open handle, rather than by pathname - this is awkward due to
5782 potential access conflicts on the open, but it is unavoidable for these
5783 old servers since the only other choice is to go from 100 nanosecond DCE
5784 time and resort to the original setpathinfo level which takes the ancient
5785 DOS time format with 2 second granularity */
5787 CIFSSMBSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5788 const FILE_BASIC_INFO
*data
, __u16 fid
, __u32 pid_of_opener
)
5790 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5793 __u16 params
, param_offset
, offset
, byte_count
, count
;
5795 cifs_dbg(FYI
, "Set Times (via SetFileInfo)\n");
5796 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5801 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5802 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5805 pSMB
->MaxSetupCount
= 0;
5809 pSMB
->Reserved2
= 0;
5810 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5811 offset
= param_offset
+ params
;
5813 data_offset
= (char *)pSMB
+
5814 offsetof(struct smb_hdr
, Protocol
) + offset
;
5816 count
= sizeof(FILE_BASIC_INFO
);
5817 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5818 /* BB find max SMB PDU from sess */
5819 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5820 pSMB
->SetupCount
= 1;
5821 pSMB
->Reserved3
= 0;
5822 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5823 byte_count
= 3 /* pad */ + params
+ count
;
5824 pSMB
->DataCount
= cpu_to_le16(count
);
5825 pSMB
->ParameterCount
= cpu_to_le16(params
);
5826 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5827 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5828 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5829 pSMB
->DataOffset
= cpu_to_le16(offset
);
5831 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5832 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5834 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5835 pSMB
->Reserved4
= 0;
5836 inc_rfc1001_len(pSMB
, byte_count
);
5837 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5838 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5839 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5840 cifs_small_buf_release(pSMB
);
5842 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5845 /* Note: On -EAGAIN error only caller can retry on handle based calls
5846 since file handle passed in no longer valid */
5852 CIFSSMBSetFileDisposition(const unsigned int xid
, struct cifs_tcon
*tcon
,
5853 bool delete_file
, __u16 fid
, __u32 pid_of_opener
)
5855 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5858 __u16 params
, param_offset
, offset
, byte_count
, count
;
5860 cifs_dbg(FYI
, "Set File Disposition (via SetFileInfo)\n");
5861 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5866 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5867 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5870 pSMB
->MaxSetupCount
= 0;
5874 pSMB
->Reserved2
= 0;
5875 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5876 offset
= param_offset
+ params
;
5878 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5881 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5882 /* BB find max SMB PDU from sess */
5883 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5884 pSMB
->SetupCount
= 1;
5885 pSMB
->Reserved3
= 0;
5886 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5887 byte_count
= 3 /* pad */ + params
+ count
;
5888 pSMB
->DataCount
= cpu_to_le16(count
);
5889 pSMB
->ParameterCount
= cpu_to_le16(params
);
5890 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5891 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5892 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5893 pSMB
->DataOffset
= cpu_to_le16(offset
);
5895 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO
);
5896 pSMB
->Reserved4
= 0;
5897 inc_rfc1001_len(pSMB
, byte_count
);
5898 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5899 *data_offset
= delete_file
? 1 : 0;
5900 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5901 cifs_small_buf_release(pSMB
);
5903 cifs_dbg(FYI
, "Send error in SetFileDisposition = %d\n", rc
);
5909 CIFSSMBSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5910 const char *fileName
, const FILE_BASIC_INFO
*data
,
5911 const struct nls_table
*nls_codepage
, int remap
)
5913 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5914 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5917 int bytes_returned
= 0;
5919 __u16 params
, param_offset
, offset
, byte_count
, count
;
5921 cifs_dbg(FYI
, "In SetTimes\n");
5924 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5929 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5931 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5932 PATH_MAX
, nls_codepage
, remap
);
5933 name_len
++; /* trailing null */
5935 } else { /* BB improve the check for buffer overruns BB */
5936 name_len
= strnlen(fileName
, PATH_MAX
);
5937 name_len
++; /* trailing null */
5938 strncpy(pSMB
->FileName
, fileName
, name_len
);
5941 params
= 6 + name_len
;
5942 count
= sizeof(FILE_BASIC_INFO
);
5943 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5944 /* BB find max SMB PDU from sess structure BB */
5945 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5946 pSMB
->MaxSetupCount
= 0;
5950 pSMB
->Reserved2
= 0;
5951 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5952 InformationLevel
) - 4;
5953 offset
= param_offset
+ params
;
5954 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5955 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5956 pSMB
->DataOffset
= cpu_to_le16(offset
);
5957 pSMB
->SetupCount
= 1;
5958 pSMB
->Reserved3
= 0;
5959 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5960 byte_count
= 3 /* pad */ + params
+ count
;
5962 pSMB
->DataCount
= cpu_to_le16(count
);
5963 pSMB
->ParameterCount
= cpu_to_le16(params
);
5964 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5965 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5966 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5967 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5969 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5970 pSMB
->Reserved4
= 0;
5971 inc_rfc1001_len(pSMB
, byte_count
);
5972 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5973 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5974 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5975 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5977 cifs_dbg(FYI
, "SetPathInfo (times) returned %d\n", rc
);
5979 cifs_buf_release(pSMB
);
5987 /* Can not be used to set time stamps yet (due to old DOS time format) */
5988 /* Can be used to set attributes */
5989 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5990 handling it anyway and NT4 was what we thought it would be needed for
5991 Do not delete it until we prove whether needed for Win9x though */
5993 CIFSSMBSetAttrLegacy(unsigned int xid
, struct cifs_tcon
*tcon
, char *fileName
,
5994 __u16 dos_attrs
, const struct nls_table
*nls_codepage
)
5996 SETATTR_REQ
*pSMB
= NULL
;
5997 SETATTR_RSP
*pSMBr
= NULL
;
6002 cifs_dbg(FYI
, "In SetAttrLegacy\n");
6005 rc
= smb_init(SMB_COM_SETATTR
, 8, tcon
, (void **) &pSMB
,
6010 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6012 ConvertToUTF16((__le16
*) pSMB
->fileName
, fileName
,
6013 PATH_MAX
, nls_codepage
);
6014 name_len
++; /* trailing null */
6016 } else { /* BB improve the check for buffer overruns BB */
6017 name_len
= strnlen(fileName
, PATH_MAX
);
6018 name_len
++; /* trailing null */
6019 strncpy(pSMB
->fileName
, fileName
, name_len
);
6021 pSMB
->attr
= cpu_to_le16(dos_attrs
);
6022 pSMB
->BufferFormat
= 0x04;
6023 inc_rfc1001_len(pSMB
, name_len
+ 1);
6024 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
6025 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6026 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6028 cifs_dbg(FYI
, "Error in LegacySetAttr = %d\n", rc
);
6030 cifs_buf_release(pSMB
);
6033 goto SetAttrLgcyRetry
;
6037 #endif /* temporarily unneeded SetAttr legacy function */
6040 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO
*data_offset
,
6041 const struct cifs_unix_set_info_args
*args
)
6043 u64 uid
= NO_CHANGE_64
, gid
= NO_CHANGE_64
;
6044 u64 mode
= args
->mode
;
6046 if (uid_valid(args
->uid
))
6047 uid
= from_kuid(&init_user_ns
, args
->uid
);
6048 if (gid_valid(args
->gid
))
6049 gid
= from_kgid(&init_user_ns
, args
->gid
);
6052 * Samba server ignores set of file size to zero due to bugs in some
6053 * older clients, but we should be precise - we use SetFileSize to
6054 * set file size and do not want to truncate file size to zero
6055 * accidentally as happened on one Samba server beta by putting
6056 * zero instead of -1 here
6058 data_offset
->EndOfFile
= cpu_to_le64(NO_CHANGE_64
);
6059 data_offset
->NumOfBytes
= cpu_to_le64(NO_CHANGE_64
);
6060 data_offset
->LastStatusChange
= cpu_to_le64(args
->ctime
);
6061 data_offset
->LastAccessTime
= cpu_to_le64(args
->atime
);
6062 data_offset
->LastModificationTime
= cpu_to_le64(args
->mtime
);
6063 data_offset
->Uid
= cpu_to_le64(uid
);
6064 data_offset
->Gid
= cpu_to_le64(gid
);
6065 /* better to leave device as zero when it is */
6066 data_offset
->DevMajor
= cpu_to_le64(MAJOR(args
->device
));
6067 data_offset
->DevMinor
= cpu_to_le64(MINOR(args
->device
));
6068 data_offset
->Permissions
= cpu_to_le64(mode
);
6071 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
6072 else if (S_ISDIR(mode
))
6073 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
6074 else if (S_ISLNK(mode
))
6075 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
6076 else if (S_ISCHR(mode
))
6077 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
6078 else if (S_ISBLK(mode
))
6079 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
6080 else if (S_ISFIFO(mode
))
6081 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
6082 else if (S_ISSOCK(mode
))
6083 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
6087 CIFSSMBUnixSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6088 const struct cifs_unix_set_info_args
*args
,
6089 u16 fid
, u32 pid_of_opener
)
6091 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
6094 u16 params
, param_offset
, offset
, byte_count
, count
;
6096 cifs_dbg(FYI
, "Set Unix Info (via SetFileInfo)\n");
6097 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
6102 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
6103 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
6106 pSMB
->MaxSetupCount
= 0;
6110 pSMB
->Reserved2
= 0;
6111 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
6112 offset
= param_offset
+ params
;
6114 data_offset
= (char *)pSMB
+
6115 offsetof(struct smb_hdr
, Protocol
) + offset
;
6117 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6119 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6120 /* BB find max SMB PDU from sess */
6121 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6122 pSMB
->SetupCount
= 1;
6123 pSMB
->Reserved3
= 0;
6124 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
6125 byte_count
= 3 /* pad */ + params
+ count
;
6126 pSMB
->DataCount
= cpu_to_le16(count
);
6127 pSMB
->ParameterCount
= cpu_to_le16(params
);
6128 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6129 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6130 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6131 pSMB
->DataOffset
= cpu_to_le16(offset
);
6133 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6134 pSMB
->Reserved4
= 0;
6135 inc_rfc1001_len(pSMB
, byte_count
);
6136 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6138 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO
*)data_offset
, args
);
6140 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
6141 cifs_small_buf_release(pSMB
);
6143 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
6146 /* Note: On -EAGAIN error only caller can retry on handle based calls
6147 since file handle passed in no longer valid */
6153 CIFSSMBUnixSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6154 const char *file_name
,
6155 const struct cifs_unix_set_info_args
*args
,
6156 const struct nls_table
*nls_codepage
, int remap
)
6158 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
6159 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
6162 int bytes_returned
= 0;
6163 FILE_UNIX_BASIC_INFO
*data_offset
;
6164 __u16 params
, param_offset
, offset
, count
, byte_count
;
6166 cifs_dbg(FYI
, "In SetUID/GID/Mode\n");
6168 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6173 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6175 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
6176 PATH_MAX
, nls_codepage
, remap
);
6177 name_len
++; /* trailing null */
6179 } else { /* BB improve the check for buffer overruns BB */
6180 name_len
= strnlen(file_name
, PATH_MAX
);
6181 name_len
++; /* trailing null */
6182 strncpy(pSMB
->FileName
, file_name
, name_len
);
6185 params
= 6 + name_len
;
6186 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6187 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6188 /* BB find max SMB PDU from sess structure BB */
6189 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6190 pSMB
->MaxSetupCount
= 0;
6194 pSMB
->Reserved2
= 0;
6195 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6196 InformationLevel
) - 4;
6197 offset
= param_offset
+ params
;
6199 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
6201 memset(data_offset
, 0, count
);
6202 pSMB
->DataOffset
= cpu_to_le16(offset
);
6203 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6204 pSMB
->SetupCount
= 1;
6205 pSMB
->Reserved3
= 0;
6206 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6207 byte_count
= 3 /* pad */ + params
+ count
;
6208 pSMB
->ParameterCount
= cpu_to_le16(params
);
6209 pSMB
->DataCount
= cpu_to_le16(count
);
6210 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6211 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6212 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6213 pSMB
->Reserved4
= 0;
6214 inc_rfc1001_len(pSMB
, byte_count
);
6216 cifs_fill_unix_set_info(data_offset
, args
);
6218 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6219 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6220 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6222 cifs_dbg(FYI
, "SetPathInfo (perms) returned %d\n", rc
);
6224 cifs_buf_release(pSMB
);
6230 #ifdef CONFIG_CIFS_XATTR
6232 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6233 * function used by listxattr and getxattr type calls. When ea_name is set,
6234 * it looks for that attribute name and stuffs that value into the EAData
6235 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6236 * buffer. In both cases, the return value is either the length of the
6237 * resulting data or a negative error code. If EAData is a NULL pointer then
6238 * the data isn't copied to it, but the length is returned.
6241 CIFSSMBQAllEAs(const unsigned int xid
, struct cifs_tcon
*tcon
,
6242 const unsigned char *searchName
, const unsigned char *ea_name
,
6243 char *EAData
, size_t buf_size
,
6244 struct cifs_sb_info
*cifs_sb
)
6246 /* BB assumes one setup word */
6247 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
6248 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
6249 int remap
= cifs_remap(cifs_sb
);
6250 struct nls_table
*nls_codepage
= cifs_sb
->local_nls
;
6254 struct fealist
*ea_response_data
;
6255 struct fea
*temp_fea
;
6258 __u16 params
, byte_count
, data_offset
;
6259 unsigned int ea_name_len
= ea_name
? strlen(ea_name
) : 0;
6261 cifs_dbg(FYI
, "In Query All EAs path %s\n", searchName
);
6263 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6268 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6270 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
6271 PATH_MAX
, nls_codepage
, remap
);
6272 list_len
++; /* trailing null */
6274 } else { /* BB improve the check for buffer overruns BB */
6275 list_len
= strnlen(searchName
, PATH_MAX
);
6276 list_len
++; /* trailing null */
6277 strncpy(pSMB
->FileName
, searchName
, list_len
);
6280 params
= 2 /* level */ + 4 /* reserved */ + list_len
/* includes NUL */;
6281 pSMB
->TotalDataCount
= 0;
6282 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6283 /* BB find exact max SMB PDU from sess structure BB */
6284 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
6285 pSMB
->MaxSetupCount
= 0;
6289 pSMB
->Reserved2
= 0;
6290 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
6291 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
6292 pSMB
->DataCount
= 0;
6293 pSMB
->DataOffset
= 0;
6294 pSMB
->SetupCount
= 1;
6295 pSMB
->Reserved3
= 0;
6296 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
6297 byte_count
= params
+ 1 /* pad */ ;
6298 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
6299 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6300 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
6301 pSMB
->Reserved4
= 0;
6302 inc_rfc1001_len(pSMB
, byte_count
);
6303 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6305 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6306 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6308 cifs_dbg(FYI
, "Send error in QueryAllEAs = %d\n", rc
);
6313 /* BB also check enough total bytes returned */
6314 /* BB we need to improve the validity checking
6315 of these trans2 responses */
6317 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
6318 if (rc
|| get_bcc(&pSMBr
->hdr
) < 4) {
6319 rc
= -EIO
; /* bad smb */
6323 /* check that length of list is not more than bcc */
6324 /* check that each entry does not go beyond length
6326 /* check that each element of each entry does not
6327 go beyond end of list */
6328 /* validate_trans2_offsets() */
6329 /* BB check if start of smb + data_offset > &bcc+ bcc */
6331 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
6332 ea_response_data
= (struct fealist
*)
6333 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
6335 list_len
= le32_to_cpu(ea_response_data
->list_len
);
6336 cifs_dbg(FYI
, "ea length %d\n", list_len
);
6337 if (list_len
<= 8) {
6338 cifs_dbg(FYI
, "empty EA list returned from server\n");
6339 /* didn't find the named attribute */
6345 /* make sure list_len doesn't go past end of SMB */
6346 end_of_smb
= (char *)pByteArea(&pSMBr
->hdr
) + get_bcc(&pSMBr
->hdr
);
6347 if ((char *)ea_response_data
+ list_len
> end_of_smb
) {
6348 cifs_dbg(FYI
, "EA list appears to go beyond SMB\n");
6353 /* account for ea list len */
6355 temp_fea
= ea_response_data
->list
;
6356 temp_ptr
= (char *)temp_fea
;
6357 while (list_len
> 0) {
6358 unsigned int name_len
;
6363 /* make sure we can read name_len and value_len */
6365 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6370 name_len
= temp_fea
->name_len
;
6371 value_len
= le16_to_cpu(temp_fea
->value_len
);
6372 list_len
-= name_len
+ 1 + value_len
;
6374 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6380 if (ea_name_len
== name_len
&&
6381 memcmp(ea_name
, temp_ptr
, name_len
) == 0) {
6382 temp_ptr
+= name_len
+ 1;
6386 if ((size_t)value_len
> buf_size
) {
6390 memcpy(EAData
, temp_ptr
, value_len
);
6394 /* account for prefix user. and trailing null */
6395 rc
+= (5 + 1 + name_len
);
6396 if (rc
< (int) buf_size
) {
6397 memcpy(EAData
, "user.", 5);
6399 memcpy(EAData
, temp_ptr
, name_len
);
6401 /* null terminate name */
6404 } else if (buf_size
== 0) {
6405 /* skip copy - calc size only */
6407 /* stop before overrun buffer */
6412 temp_ptr
+= name_len
+ 1 + value_len
;
6413 temp_fea
= (struct fea
*)temp_ptr
;
6416 /* didn't find the named attribute */
6421 cifs_buf_release(pSMB
);
6429 CIFSSMBSetEA(const unsigned int xid
, struct cifs_tcon
*tcon
,
6430 const char *fileName
, const char *ea_name
, const void *ea_value
,
6431 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
,
6432 struct cifs_sb_info
*cifs_sb
)
6434 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
6435 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
6436 struct fealist
*parm_data
;
6439 int bytes_returned
= 0;
6440 __u16 params
, param_offset
, byte_count
, offset
, count
;
6441 int remap
= cifs_remap(cifs_sb
);
6443 cifs_dbg(FYI
, "In SetEA\n");
6445 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6450 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6452 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
6453 PATH_MAX
, nls_codepage
, remap
);
6454 name_len
++; /* trailing null */
6456 } else { /* BB improve the check for buffer overruns BB */
6457 name_len
= strnlen(fileName
, PATH_MAX
);
6458 name_len
++; /* trailing null */
6459 strncpy(pSMB
->FileName
, fileName
, name_len
);
6462 params
= 6 + name_len
;
6464 /* done calculating parms using name_len of file name,
6465 now use name_len to calculate length of ea name
6466 we are going to create in the inode xattrs */
6467 if (ea_name
== NULL
)
6470 name_len
= strnlen(ea_name
, 255);
6472 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
;
6473 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6474 /* BB find max SMB PDU from sess */
6475 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6476 pSMB
->MaxSetupCount
= 0;
6480 pSMB
->Reserved2
= 0;
6481 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6482 InformationLevel
) - 4;
6483 offset
= param_offset
+ params
;
6484 pSMB
->InformationLevel
=
6485 cpu_to_le16(SMB_SET_FILE_EA
);
6487 parm_data
= (void *)pSMB
+ offsetof(struct smb_hdr
, Protocol
) + offset
;
6488 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6489 pSMB
->DataOffset
= cpu_to_le16(offset
);
6490 pSMB
->SetupCount
= 1;
6491 pSMB
->Reserved3
= 0;
6492 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6493 byte_count
= 3 /* pad */ + params
+ count
;
6494 pSMB
->DataCount
= cpu_to_le16(count
);
6495 parm_data
->list_len
= cpu_to_le32(count
);
6496 parm_data
->list
[0].EA_flags
= 0;
6497 /* we checked above that name len is less than 255 */
6498 parm_data
->list
[0].name_len
= (__u8
)name_len
;
6499 /* EA names are always ASCII */
6501 strncpy(parm_data
->list
[0].name
, ea_name
, name_len
);
6502 parm_data
->list
[0].name
[name_len
] = 0;
6503 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
6504 /* caller ensures that ea_value_len is less than 64K but
6505 we need to ensure that it fits within the smb */
6507 /*BB add length check to see if it would fit in
6508 negotiated SMB buffer size BB */
6509 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6511 memcpy(parm_data
->list
[0].name
+name_len
+1,
6512 ea_value
, ea_value_len
);
6514 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6515 pSMB
->ParameterCount
= cpu_to_le16(params
);
6516 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6517 pSMB
->Reserved4
= 0;
6518 inc_rfc1001_len(pSMB
, byte_count
);
6519 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6520 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6521 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6523 cifs_dbg(FYI
, "SetPathInfo (EA) returned %d\n", rc
);
6525 cifs_buf_release(pSMB
);
6534 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6536 * Years ago the kernel added a "dnotify" function for Samba server,
6537 * to allow network clients (such as Windows) to display updated
6538 * lists of files in directory listings automatically when
6539 * files are added by one user when another user has the
6540 * same directory open on their desktop. The Linux cifs kernel
6541 * client hooked into the kernel side of this interface for
6542 * the same reason, but ironically when the VFS moved from
6543 * "dnotify" to "inotify" it became harder to plug in Linux
6544 * network file system clients (the most obvious use case
6545 * for notify interfaces is when multiple users can update
6546 * the contents of the same directory - exactly what network
6547 * file systems can do) although the server (Samba) could
6548 * still use it. For the short term we leave the worker
6549 * function ifdeffed out (below) until inotify is fixed
6550 * in the VFS to make it easier to plug in network file
6551 * system clients. If inotify turns out to be permanently
6552 * incompatible for network fs clients, we could instead simply
6553 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6555 int CIFSSMBNotify(const unsigned int xid
, struct cifs_tcon
*tcon
,
6556 const int notify_subdirs
, const __u16 netfid
,
6557 __u32 filter
, struct file
*pfile
, int multishot
,
6558 const struct nls_table
*nls_codepage
)
6561 struct smb_com_transaction_change_notify_req
*pSMB
= NULL
;
6562 struct smb_com_ntransaction_change_notify_rsp
*pSMBr
= NULL
;
6563 struct dir_notify_req
*dnotify_req
;
6566 cifs_dbg(FYI
, "In CIFSSMBNotify for file handle %d\n", (int)netfid
);
6567 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
6572 pSMB
->TotalParameterCount
= 0 ;
6573 pSMB
->TotalDataCount
= 0;
6574 pSMB
->MaxParameterCount
= cpu_to_le32(2);
6575 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
6576 pSMB
->MaxSetupCount
= 4;
6578 pSMB
->ParameterOffset
= 0;
6579 pSMB
->DataCount
= 0;
6580 pSMB
->DataOffset
= 0;
6581 pSMB
->SetupCount
= 4; /* single byte does not need le conversion */
6582 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE
);
6583 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6585 pSMB
->WatchTree
= 1; /* one byte - no le conversion needed */
6586 pSMB
->Reserved2
= 0;
6587 pSMB
->CompletionFilter
= cpu_to_le32(filter
);
6588 pSMB
->Fid
= netfid
; /* file handle always le */
6589 pSMB
->ByteCount
= 0;
6591 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6592 (struct smb_hdr
*)pSMBr
, &bytes_returned
,
6595 cifs_dbg(FYI
, "Error in Notify = %d\n", rc
);
6597 /* Add file to outstanding requests */
6598 /* BB change to kmem cache alloc */
6599 dnotify_req
= kmalloc(
6600 sizeof(struct dir_notify_req
),
6603 dnotify_req
->Pid
= pSMB
->hdr
.Pid
;
6604 dnotify_req
->PidHigh
= pSMB
->hdr
.PidHigh
;
6605 dnotify_req
->Mid
= pSMB
->hdr
.Mid
;
6606 dnotify_req
->Tid
= pSMB
->hdr
.Tid
;
6607 dnotify_req
->Uid
= pSMB
->hdr
.Uid
;
6608 dnotify_req
->netfid
= netfid
;
6609 dnotify_req
->pfile
= pfile
;
6610 dnotify_req
->filter
= filter
;
6611 dnotify_req
->multishot
= multishot
;
6612 spin_lock(&GlobalMid_Lock
);
6613 list_add_tail(&dnotify_req
->lhead
,
6614 &GlobalDnotifyReqList
);
6615 spin_unlock(&GlobalMid_Lock
);
6619 cifs_buf_release(pSMB
);
6622 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */