4 * Copyright (C) International Business Machines Corp., 2002,2010
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Contains the routines for constructing the SMB PDUs themselves
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
25 /* These are mostly routines that operate on a pathname, or on a tree id */
26 /* (mounted volume), but there are eight handle based routines which must be */
27 /* treated slightly differently for reconnection purposes since we never */
28 /* want to reuse a stale file handle and only the caller knows the file info */
31 #include <linux/kernel.h>
32 #include <linux/vfs.h>
33 #include <linux/slab.h>
34 #include <linux/posix_acl_xattr.h>
35 #include <linux/pagemap.h>
36 #include <linux/swap.h>
37 #include <linux/task_io_accounting_ops.h>
38 #include <linux/uaccess.h>
42 #include "cifsproto.h"
43 #include "cifs_unicode.h"
44 #include "cifs_debug.h"
45 #include "smb2proto.h"
47 #include "smbdirect.h"
48 #ifdef CONFIG_CIFS_DFS_UPCALL
49 #include "dfs_cache.h"
52 #ifdef CONFIG_CIFS_POSIX
57 #ifdef CONFIG_CIFS_WEAK_PW_HASH
58 {LANMAN_PROT
, "\2LM1.2X002"},
59 {LANMAN2_PROT
, "\2LANMAN2.1"},
60 #endif /* weak password hashing for legacy clients */
61 {CIFS_PROT
, "\2NT LM 0.12"},
62 {POSIX_PROT
, "\2POSIX 2"},
70 #ifdef CONFIG_CIFS_WEAK_PW_HASH
71 {LANMAN_PROT
, "\2LM1.2X002"},
72 {LANMAN2_PROT
, "\2LANMAN2.1"},
73 #endif /* weak password hashing for legacy clients */
74 {CIFS_PROT
, "\2NT LM 0.12"},
79 /* define the number of elements in the cifs dialect array */
80 #ifdef CONFIG_CIFS_POSIX
81 #ifdef CONFIG_CIFS_WEAK_PW_HASH
82 #define CIFS_NUM_PROT 4
84 #define CIFS_NUM_PROT 2
85 #endif /* CIFS_WEAK_PW_HASH */
87 #ifdef CONFIG_CIFS_WEAK_PW_HASH
88 #define CIFS_NUM_PROT 3
90 #define CIFS_NUM_PROT 1
91 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
92 #endif /* CIFS_POSIX */
95 * Mark as invalid, all open files on tree connections since they
96 * were closed when session to server was lost.
99 cifs_mark_open_files_invalid(struct cifs_tcon
*tcon
)
101 struct cifsFileInfo
*open_file
= NULL
;
102 struct list_head
*tmp
;
103 struct list_head
*tmp1
;
105 /* list all files open on tree connection and mark them invalid */
106 spin_lock(&tcon
->open_file_lock
);
107 list_for_each_safe(tmp
, tmp1
, &tcon
->openFileList
) {
108 open_file
= list_entry(tmp
, struct cifsFileInfo
, tlist
);
109 open_file
->invalidHandle
= true;
110 open_file
->oplock_break_cancelled
= true;
112 spin_unlock(&tcon
->open_file_lock
);
114 mutex_lock(&tcon
->crfid
.fid_mutex
);
115 tcon
->crfid
.is_valid
= false;
116 /* cached handle is not valid, so SMB2_CLOSE won't be sent below */
117 close_shroot_lease_locked(&tcon
->crfid
);
118 memset(tcon
->crfid
.fid
, 0, sizeof(struct cifs_fid
));
119 mutex_unlock(&tcon
->crfid
.fid_mutex
);
122 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
127 /* reconnect the socket, tcon, and smb session if needed */
129 cifs_reconnect_tcon(struct cifs_tcon
*tcon
, int smb_command
)
132 struct cifs_ses
*ses
;
133 struct TCP_Server_Info
*server
;
134 struct nls_table
*nls_codepage
;
138 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
139 * tcp and smb session status done differently for those three - in the
146 server
= ses
->server
;
149 * only tree disconnect, open, and write, (and ulogoff which does not
150 * have tcon) are allowed as we start force umount
152 if (tcon
->tidStatus
== CifsExiting
) {
153 if (smb_command
!= SMB_COM_WRITE_ANDX
&&
154 smb_command
!= SMB_COM_OPEN_ANDX
&&
155 smb_command
!= SMB_COM_TREE_DISCONNECT
) {
156 cifs_dbg(FYI
, "can not send cmd %d while umounting\n",
162 retries
= server
->nr_targets
;
165 * Give demultiplex thread up to 10 seconds to each target available for
166 * reconnect -- should be greater than cifs socket timeout which is 7
169 while (server
->tcpStatus
== CifsNeedReconnect
) {
170 rc
= wait_event_interruptible_timeout(server
->response_q
,
171 (server
->tcpStatus
!= CifsNeedReconnect
),
174 cifs_dbg(FYI
, "%s: aborting reconnect due to a received signal by the process\n",
179 /* are we still trying to reconnect? */
180 if (server
->tcpStatus
!= CifsNeedReconnect
)
183 if (retries
&& --retries
)
187 * on "soft" mounts we wait once. Hard mounts keep
188 * retrying until process is killed or server comes
192 cifs_dbg(FYI
, "gave up waiting on reconnect in smb_init\n");
195 retries
= server
->nr_targets
;
198 if (!ses
->need_reconnect
&& !tcon
->need_reconnect
)
201 nls_codepage
= load_nls_default();
204 * need to prevent multiple threads trying to simultaneously
205 * reconnect the same SMB session
207 mutex_lock(&ses
->session_mutex
);
210 * Recheck after acquire mutex. If another thread is negotiating
211 * and the server never sends an answer the socket will be closed
212 * and tcpStatus set to reconnect.
214 if (server
->tcpStatus
== CifsNeedReconnect
) {
216 mutex_unlock(&ses
->session_mutex
);
220 rc
= cifs_negotiate_protocol(0, ses
);
221 if (rc
== 0 && ses
->need_reconnect
)
222 rc
= cifs_setup_session(0, ses
, nls_codepage
);
224 /* do we need to reconnect tcon? */
225 if (rc
|| !tcon
->need_reconnect
) {
226 mutex_unlock(&ses
->session_mutex
);
230 cifs_mark_open_files_invalid(tcon
);
231 rc
= cifs_tree_connect(0, tcon
, nls_codepage
);
232 mutex_unlock(&ses
->session_mutex
);
233 cifs_dbg(FYI
, "reconnect tcon rc = %d\n", rc
);
236 pr_warn_once("reconnect tcon failed rc = %d\n", rc
);
240 atomic_inc(&tconInfoReconnectCount
);
242 /* tell server Unix caps we support */
244 reset_cifs_unix_caps(0, tcon
, NULL
, NULL
);
247 * Removed call to reopen open files here. It is safer (and faster) to
248 * reopen files one at a time as needed in read and write.
250 * FIXME: what about file locks? don't we need to reclaim them ASAP?
255 * Check if handle based operation so we know whether we can continue
256 * or not without returning to caller to reset file handle
258 switch (smb_command
) {
259 case SMB_COM_READ_ANDX
:
260 case SMB_COM_WRITE_ANDX
:
262 case SMB_COM_FIND_CLOSE2
:
263 case SMB_COM_LOCKING_ANDX
:
267 unload_nls(nls_codepage
);
271 /* Allocate and return pointer to an SMB request buffer, and set basic
272 SMB information in the SMB header. If the return code is zero, this
273 function must have filled in request_buf pointer */
275 small_smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
280 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
284 *request_buf
= cifs_small_buf_get();
285 if (*request_buf
== NULL
) {
286 /* BB should we add a retry in here if not a writepage? */
290 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
,
294 cifs_stats_inc(&tcon
->num_smbs_sent
);
300 small_smb_init_no_tc(const int smb_command
, const int wct
,
301 struct cifs_ses
*ses
, void **request_buf
)
304 struct smb_hdr
*buffer
;
306 rc
= small_smb_init(smb_command
, wct
, NULL
, request_buf
);
310 buffer
= (struct smb_hdr
*)*request_buf
;
311 buffer
->Mid
= get_next_mid(ses
->server
);
312 if (ses
->capabilities
& CAP_UNICODE
)
313 buffer
->Flags2
|= SMBFLG2_UNICODE
;
314 if (ses
->capabilities
& CAP_STATUS32
)
315 buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
317 /* uid, tid can stay at zero as set in header assemble */
319 /* BB add support for turning on the signing when
320 this function is used after 1st of session setup requests */
325 /* If the return code is zero, this function must fill in request_buf pointer */
327 __smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
328 void **request_buf
, void **response_buf
)
330 *request_buf
= cifs_buf_get();
331 if (*request_buf
== NULL
) {
332 /* BB should we add a retry in here if not a writepage? */
335 /* Although the original thought was we needed the response buf for */
336 /* potential retries of smb operations it turns out we can determine */
337 /* from the mid flags when the request buffer can be resent without */
338 /* having to use a second distinct buffer for the response */
340 *response_buf
= *request_buf
;
342 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
, tcon
,
346 cifs_stats_inc(&tcon
->num_smbs_sent
);
351 /* If the return code is zero, this function must fill in request_buf pointer */
353 smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
354 void **request_buf
, void **response_buf
)
358 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
362 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
366 smb_init_no_reconnect(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
367 void **request_buf
, void **response_buf
)
369 if (tcon
->ses
->need_reconnect
|| tcon
->need_reconnect
)
372 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
375 static int validate_t2(struct smb_t2_rsp
*pSMB
)
377 unsigned int total_size
;
379 /* check for plausible wct */
380 if (pSMB
->hdr
.WordCount
< 10)
383 /* check for parm and data offset going beyond end of smb */
384 if (get_unaligned_le16(&pSMB
->t2_rsp
.ParameterOffset
) > 1024 ||
385 get_unaligned_le16(&pSMB
->t2_rsp
.DataOffset
) > 1024)
388 total_size
= get_unaligned_le16(&pSMB
->t2_rsp
.ParameterCount
);
389 if (total_size
>= 512)
392 /* check that bcc is at least as big as parms + data, and that it is
393 * less than negotiated smb buffer
395 total_size
+= get_unaligned_le16(&pSMB
->t2_rsp
.DataCount
);
396 if (total_size
> get_bcc(&pSMB
->hdr
) ||
397 total_size
>= CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
)
402 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB
,
403 sizeof(struct smb_t2_rsp
) + 16);
408 decode_ext_sec_blob(struct cifs_ses
*ses
, NEGOTIATE_RSP
*pSMBr
)
412 char *guid
= pSMBr
->u
.extended_response
.GUID
;
413 struct TCP_Server_Info
*server
= ses
->server
;
415 count
= get_bcc(&pSMBr
->hdr
);
416 if (count
< SMB1_CLIENT_GUID_SIZE
)
419 spin_lock(&cifs_tcp_ses_lock
);
420 if (server
->srv_count
> 1) {
421 spin_unlock(&cifs_tcp_ses_lock
);
422 if (memcmp(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
) != 0) {
423 cifs_dbg(FYI
, "server UID changed\n");
424 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
427 spin_unlock(&cifs_tcp_ses_lock
);
428 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
431 if (count
== SMB1_CLIENT_GUID_SIZE
) {
432 server
->sec_ntlmssp
= true;
434 count
-= SMB1_CLIENT_GUID_SIZE
;
435 rc
= decode_negTokenInit(
436 pSMBr
->u
.extended_response
.SecurityBlob
, count
, server
);
445 cifs_enable_signing(struct TCP_Server_Info
*server
, bool mnt_sign_required
)
447 bool srv_sign_required
= server
->sec_mode
& server
->vals
->signing_required
;
448 bool srv_sign_enabled
= server
->sec_mode
& server
->vals
->signing_enabled
;
449 bool mnt_sign_enabled
= global_secflags
& CIFSSEC_MAY_SIGN
;
452 * Is signing required by mnt options? If not then check
453 * global_secflags to see if it is there.
455 if (!mnt_sign_required
)
456 mnt_sign_required
= ((global_secflags
& CIFSSEC_MUST_SIGN
) ==
460 * If signing is required then it's automatically enabled too,
461 * otherwise, check to see if the secflags allow it.
463 mnt_sign_enabled
= mnt_sign_required
? mnt_sign_required
:
464 (global_secflags
& CIFSSEC_MAY_SIGN
);
466 /* If server requires signing, does client allow it? */
467 if (srv_sign_required
) {
468 if (!mnt_sign_enabled
) {
469 cifs_dbg(VFS
, "Server requires signing, but it's disabled in SecurityFlags!\n");
475 /* If client requires signing, does server allow it? */
476 if (mnt_sign_required
) {
477 if (!srv_sign_enabled
) {
478 cifs_dbg(VFS
, "Server does not support signing!\n");
484 if (cifs_rdma_enabled(server
) && server
->sign
)
485 cifs_dbg(VFS
, "Signing is enabled, and RDMA read/write will be disabled\n");
490 #ifdef CONFIG_CIFS_WEAK_PW_HASH
492 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
495 struct lanman_neg_rsp
*rsp
= (struct lanman_neg_rsp
*)pSMBr
;
497 if (server
->dialect
!= LANMAN_PROT
&& server
->dialect
!= LANMAN2_PROT
)
500 server
->sec_mode
= le16_to_cpu(rsp
->SecurityMode
);
501 server
->maxReq
= min_t(unsigned int,
502 le16_to_cpu(rsp
->MaxMpxCount
),
504 set_credits(server
, server
->maxReq
);
505 server
->maxBuf
= le16_to_cpu(rsp
->MaxBufSize
);
506 /* set up max_read for readpages check */
507 server
->max_read
= server
->maxBuf
;
508 /* even though we do not use raw we might as well set this
509 accurately, in case we ever find a need for it */
510 if ((le16_to_cpu(rsp
->RawMode
) & RAW_ENABLE
) == RAW_ENABLE
) {
511 server
->max_rw
= 0xFF00;
512 server
->capabilities
= CAP_MPX_MODE
| CAP_RAW_MODE
;
514 server
->max_rw
= 0;/* do not need to use raw anyway */
515 server
->capabilities
= CAP_MPX_MODE
;
517 tmp
= (__s16
)le16_to_cpu(rsp
->ServerTimeZone
);
519 /* OS/2 often does not set timezone therefore
520 * we must use server time to calc time zone.
521 * Could deviate slightly from the right zone.
522 * Smallest defined timezone difference is 15 minutes
523 * (i.e. Nepal). Rounding up/down is done to match
526 int val
, seconds
, remain
, result
;
527 struct timespec64 ts
;
528 time64_t utc
= ktime_get_real_seconds();
529 ts
= cnvrtDosUnixTm(rsp
->SrvTime
.Date
,
530 rsp
->SrvTime
.Time
, 0);
531 cifs_dbg(FYI
, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n",
534 val
= (int)(utc
- ts
.tv_sec
);
536 result
= (seconds
/ MIN_TZ_ADJ
) * MIN_TZ_ADJ
;
537 remain
= seconds
% MIN_TZ_ADJ
;
538 if (remain
>= (MIN_TZ_ADJ
/ 2))
539 result
+= MIN_TZ_ADJ
;
542 server
->timeAdj
= result
;
544 server
->timeAdj
= (int)tmp
;
545 server
->timeAdj
*= 60; /* also in seconds */
547 cifs_dbg(FYI
, "server->timeAdj: %d seconds\n", server
->timeAdj
);
550 /* BB get server time for time conversions and add
551 code to use it and timezone since this is not UTC */
553 if (rsp
->EncryptionKeyLength
==
554 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE
)) {
555 memcpy(server
->cryptkey
, rsp
->EncryptionKey
,
556 CIFS_CRYPTO_KEY_SIZE
);
557 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
558 return -EIO
; /* need cryptkey unless plain text */
561 cifs_dbg(FYI
, "LANMAN negotiated\n");
566 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
568 cifs_dbg(VFS
, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
574 should_set_ext_sec_flag(enum securityEnum sectype
)
581 if (global_secflags
&
582 (CIFSSEC_MAY_KRB5
| CIFSSEC_MAY_NTLMSSP
))
591 CIFSSMBNegotiate(const unsigned int xid
, struct cifs_ses
*ses
)
594 NEGOTIATE_RSP
*pSMBr
;
598 struct TCP_Server_Info
*server
= ses
->server
;
602 WARN(1, "%s: server is NULL!\n", __func__
);
606 rc
= smb_init(SMB_COM_NEGOTIATE
, 0, NULL
/* no tcon yet */ ,
607 (void **) &pSMB
, (void **) &pSMBr
);
611 pSMB
->hdr
.Mid
= get_next_mid(server
);
612 pSMB
->hdr
.Flags2
|= (SMBFLG2_UNICODE
| SMBFLG2_ERR_STATUS
);
614 if (should_set_ext_sec_flag(ses
->sectype
)) {
615 cifs_dbg(FYI
, "Requesting extended security\n");
616 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
621 * We know that all the name entries in the protocols array
622 * are short (< 16 bytes anyway) and are NUL terminated.
624 for (i
= 0; i
< CIFS_NUM_PROT
; i
++) {
625 size_t len
= strlen(protocols
[i
].name
) + 1;
627 memcpy(pSMB
->DialectsArray
+count
, protocols
[i
].name
, len
);
630 inc_rfc1001_len(pSMB
, count
);
631 pSMB
->ByteCount
= cpu_to_le16(count
);
633 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
634 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
638 server
->dialect
= le16_to_cpu(pSMBr
->DialectIndex
);
639 cifs_dbg(FYI
, "Dialect: %d\n", server
->dialect
);
640 /* Check wct = 1 error case */
641 if ((pSMBr
->hdr
.WordCount
< 13) || (server
->dialect
== BAD_PROT
)) {
642 /* core returns wct = 1, but we do not ask for core - otherwise
643 small wct just comes when dialect index is -1 indicating we
644 could not negotiate a common dialect */
647 } else if (pSMBr
->hdr
.WordCount
== 13) {
648 server
->negflavor
= CIFS_NEGFLAVOR_LANMAN
;
649 rc
= decode_lanman_negprot_rsp(server
, pSMBr
);
651 } else if (pSMBr
->hdr
.WordCount
!= 17) {
656 /* else wct == 17, NTLM or better */
658 server
->sec_mode
= pSMBr
->SecurityMode
;
659 if ((server
->sec_mode
& SECMODE_USER
) == 0)
660 cifs_dbg(FYI
, "share mode security\n");
662 /* one byte, so no need to convert this or EncryptionKeyLen from
664 server
->maxReq
= min_t(unsigned int, le16_to_cpu(pSMBr
->MaxMpxCount
),
666 set_credits(server
, server
->maxReq
);
667 /* probably no need to store and check maxvcs */
668 server
->maxBuf
= le32_to_cpu(pSMBr
->MaxBufferSize
);
669 /* set up max_read for readpages check */
670 server
->max_read
= server
->maxBuf
;
671 server
->max_rw
= le32_to_cpu(pSMBr
->MaxRawSize
);
672 cifs_dbg(NOISY
, "Max buf = %d\n", ses
->server
->maxBuf
);
673 server
->capabilities
= le32_to_cpu(pSMBr
->Capabilities
);
674 server
->timeAdj
= (int)(__s16
)le16_to_cpu(pSMBr
->ServerTimeZone
);
675 server
->timeAdj
*= 60;
677 if (pSMBr
->EncryptionKeyLength
== CIFS_CRYPTO_KEY_SIZE
) {
678 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
679 memcpy(ses
->server
->cryptkey
, pSMBr
->u
.EncryptionKey
,
680 CIFS_CRYPTO_KEY_SIZE
);
681 } else if (pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
||
682 server
->capabilities
& CAP_EXTENDED_SECURITY
) {
683 server
->negflavor
= CIFS_NEGFLAVOR_EXTENDED
;
684 rc
= decode_ext_sec_blob(ses
, pSMBr
);
685 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
686 rc
= -EIO
; /* no crypt key only if plain text pwd */
688 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
689 server
->capabilities
&= ~CAP_EXTENDED_SECURITY
;
694 rc
= cifs_enable_signing(server
, ses
->sign
);
696 cifs_buf_release(pSMB
);
698 cifs_dbg(FYI
, "negprot rc %d\n", rc
);
703 CIFSSMBTDis(const unsigned int xid
, struct cifs_tcon
*tcon
)
705 struct smb_hdr
*smb_buffer
;
708 cifs_dbg(FYI
, "In tree disconnect\n");
710 /* BB: do we need to check this? These should never be NULL. */
711 if ((tcon
->ses
== NULL
) || (tcon
->ses
->server
== NULL
))
715 * No need to return error on this operation if tid invalidated and
716 * closed on server already e.g. due to tcp session crashing. Also,
717 * the tcon is no longer on the list, so no need to take lock before
720 if ((tcon
->need_reconnect
) || (tcon
->ses
->need_reconnect
))
723 rc
= small_smb_init(SMB_COM_TREE_DISCONNECT
, 0, tcon
,
724 (void **)&smb_buffer
);
728 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)smb_buffer
, 0);
729 cifs_small_buf_release(smb_buffer
);
731 cifs_dbg(FYI
, "Tree disconnect failed %d\n", rc
);
733 /* No need to return error on this operation if tid invalidated and
734 closed on server already e.g. due to tcp session crashing */
742 * This is a no-op for now. We're not really interested in the reply, but
743 * rather in the fact that the server sent one and that server->lstrp
746 * FIXME: maybe we should consider checking that the reply matches request?
749 cifs_echo_callback(struct mid_q_entry
*mid
)
751 struct TCP_Server_Info
*server
= mid
->callback_data
;
752 struct cifs_credits credits
= { .value
= 1, .instance
= 0 };
754 DeleteMidQEntry(mid
);
755 add_credits(server
, &credits
, CIFS_ECHO_OP
);
759 CIFSSMBEcho(struct TCP_Server_Info
*server
)
764 struct smb_rqst rqst
= { .rq_iov
= iov
,
767 cifs_dbg(FYI
, "In echo request\n");
769 rc
= small_smb_init(SMB_COM_ECHO
, 0, NULL
, (void **)&smb
);
773 if (server
->capabilities
& CAP_UNICODE
)
774 smb
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
776 /* set up echo request */
777 smb
->hdr
.Tid
= 0xffff;
778 smb
->hdr
.WordCount
= 1;
779 put_unaligned_le16(1, &smb
->EchoCount
);
780 put_bcc(1, &smb
->hdr
);
782 inc_rfc1001_len(smb
, 3);
785 iov
[0].iov_base
= smb
;
786 iov
[1].iov_len
= get_rfc1002_length(smb
);
787 iov
[1].iov_base
= (char *)smb
+ 4;
789 rc
= cifs_call_async(server
, &rqst
, NULL
, cifs_echo_callback
, NULL
,
790 server
, CIFS_NON_BLOCKING
| CIFS_ECHO_OP
, NULL
);
792 cifs_dbg(FYI
, "Echo request failed: %d\n", rc
);
794 cifs_small_buf_release(smb
);
800 CIFSSMBLogoff(const unsigned int xid
, struct cifs_ses
*ses
)
802 LOGOFF_ANDX_REQ
*pSMB
;
805 cifs_dbg(FYI
, "In SMBLogoff for session disconnect\n");
808 * BB: do we need to check validity of ses and server? They should
809 * always be valid since we have an active reference. If not, that
810 * should probably be a BUG()
812 if (!ses
|| !ses
->server
)
815 mutex_lock(&ses
->session_mutex
);
816 if (ses
->need_reconnect
)
817 goto session_already_dead
; /* no need to send SMBlogoff if uid
818 already closed due to reconnect */
819 rc
= small_smb_init(SMB_COM_LOGOFF_ANDX
, 2, NULL
, (void **)&pSMB
);
821 mutex_unlock(&ses
->session_mutex
);
825 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
827 if (ses
->server
->sign
)
828 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
830 pSMB
->hdr
.Uid
= ses
->Suid
;
832 pSMB
->AndXCommand
= 0xFF;
833 rc
= SendReceiveNoRsp(xid
, ses
, (char *) pSMB
, 0);
834 cifs_small_buf_release(pSMB
);
835 session_already_dead
:
836 mutex_unlock(&ses
->session_mutex
);
838 /* if session dead then we do not need to do ulogoff,
839 since server closed smb session, no sense reporting
847 CIFSPOSIXDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
,
848 const char *fileName
, __u16 type
,
849 const struct nls_table
*nls_codepage
, int remap
)
851 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
852 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
853 struct unlink_psx_rq
*pRqD
;
856 int bytes_returned
= 0;
857 __u16 params
, param_offset
, offset
, byte_count
;
859 cifs_dbg(FYI
, "In POSIX delete\n");
861 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
866 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
868 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
869 PATH_MAX
, nls_codepage
, remap
);
870 name_len
++; /* trailing null */
873 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
876 params
= 6 + name_len
;
877 pSMB
->MaxParameterCount
= cpu_to_le16(2);
878 pSMB
->MaxDataCount
= 0; /* BB double check this with jra */
879 pSMB
->MaxSetupCount
= 0;
884 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
885 InformationLevel
) - 4;
886 offset
= param_offset
+ params
;
888 /* Setup pointer to Request Data (inode type) */
889 pRqD
= (struct unlink_psx_rq
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
890 pRqD
->type
= cpu_to_le16(type
);
891 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
892 pSMB
->DataOffset
= cpu_to_le16(offset
);
893 pSMB
->SetupCount
= 1;
895 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
896 byte_count
= 3 /* pad */ + params
+ sizeof(struct unlink_psx_rq
);
898 pSMB
->DataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
899 pSMB
->TotalDataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
900 pSMB
->ParameterCount
= cpu_to_le16(params
);
901 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
902 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_UNLINK
);
904 inc_rfc1001_len(pSMB
, byte_count
);
905 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
906 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
907 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
909 cifs_dbg(FYI
, "Posix delete returned %d\n", rc
);
910 cifs_buf_release(pSMB
);
912 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
921 CIFSSMBDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
922 struct cifs_sb_info
*cifs_sb
)
924 DELETE_FILE_REQ
*pSMB
= NULL
;
925 DELETE_FILE_RSP
*pSMBr
= NULL
;
929 int remap
= cifs_remap(cifs_sb
);
932 rc
= smb_init(SMB_COM_DELETE
, 1, tcon
, (void **) &pSMB
,
937 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
938 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->fileName
, name
,
939 PATH_MAX
, cifs_sb
->local_nls
,
941 name_len
++; /* trailing null */
944 name_len
= copy_path_name(pSMB
->fileName
, name
);
946 pSMB
->SearchAttributes
=
947 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
);
948 pSMB
->BufferFormat
= 0x04;
949 inc_rfc1001_len(pSMB
, name_len
+ 1);
950 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
951 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
952 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
953 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
955 cifs_dbg(FYI
, "Error in RMFile = %d\n", rc
);
957 cifs_buf_release(pSMB
);
965 CIFSSMBRmDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
966 struct cifs_sb_info
*cifs_sb
)
968 DELETE_DIRECTORY_REQ
*pSMB
= NULL
;
969 DELETE_DIRECTORY_RSP
*pSMBr
= NULL
;
973 int remap
= cifs_remap(cifs_sb
);
975 cifs_dbg(FYI
, "In CIFSSMBRmDir\n");
977 rc
= smb_init(SMB_COM_DELETE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
982 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
983 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
984 PATH_MAX
, cifs_sb
->local_nls
,
986 name_len
++; /* trailing null */
989 name_len
= copy_path_name(pSMB
->DirName
, name
);
992 pSMB
->BufferFormat
= 0x04;
993 inc_rfc1001_len(pSMB
, name_len
+ 1);
994 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
995 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
996 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
997 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_rmdirs
);
999 cifs_dbg(FYI
, "Error in RMDir = %d\n", rc
);
1001 cifs_buf_release(pSMB
);
1008 CIFSSMBMkDir(const unsigned int xid
, struct inode
*inode
, umode_t mode
,
1009 struct cifs_tcon
*tcon
, const char *name
,
1010 struct cifs_sb_info
*cifs_sb
)
1013 CREATE_DIRECTORY_REQ
*pSMB
= NULL
;
1014 CREATE_DIRECTORY_RSP
*pSMBr
= NULL
;
1017 int remap
= cifs_remap(cifs_sb
);
1019 cifs_dbg(FYI
, "In CIFSSMBMkDir\n");
1021 rc
= smb_init(SMB_COM_CREATE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
1026 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1027 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
1028 PATH_MAX
, cifs_sb
->local_nls
,
1030 name_len
++; /* trailing null */
1033 name_len
= copy_path_name(pSMB
->DirName
, name
);
1036 pSMB
->BufferFormat
= 0x04;
1037 inc_rfc1001_len(pSMB
, name_len
+ 1);
1038 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1039 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1040 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1041 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_mkdirs
);
1043 cifs_dbg(FYI
, "Error in Mkdir = %d\n", rc
);
1045 cifs_buf_release(pSMB
);
1052 CIFSPOSIXCreate(const unsigned int xid
, struct cifs_tcon
*tcon
,
1053 __u32 posix_flags
, __u64 mode
, __u16
*netfid
,
1054 FILE_UNIX_BASIC_INFO
*pRetData
, __u32
*pOplock
,
1055 const char *name
, const struct nls_table
*nls_codepage
,
1058 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
1059 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
1062 int bytes_returned
= 0;
1063 __u16 params
, param_offset
, offset
, byte_count
, count
;
1064 OPEN_PSX_REQ
*pdata
;
1065 OPEN_PSX_RSP
*psx_rsp
;
1067 cifs_dbg(FYI
, "In POSIX Create\n");
1069 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1074 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1076 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, name
,
1077 PATH_MAX
, nls_codepage
, remap
);
1078 name_len
++; /* trailing null */
1081 name_len
= copy_path_name(pSMB
->FileName
, name
);
1084 params
= 6 + name_len
;
1085 count
= sizeof(OPEN_PSX_REQ
);
1086 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1087 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* large enough */
1088 pSMB
->MaxSetupCount
= 0;
1092 pSMB
->Reserved2
= 0;
1093 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
1094 InformationLevel
) - 4;
1095 offset
= param_offset
+ params
;
1096 pdata
= (OPEN_PSX_REQ
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
1097 pdata
->Level
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
1098 pdata
->Permissions
= cpu_to_le64(mode
);
1099 pdata
->PosixOpenFlags
= cpu_to_le32(posix_flags
);
1100 pdata
->OpenFlags
= cpu_to_le32(*pOplock
);
1101 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
1102 pSMB
->DataOffset
= cpu_to_le16(offset
);
1103 pSMB
->SetupCount
= 1;
1104 pSMB
->Reserved3
= 0;
1105 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
1106 byte_count
= 3 /* pad */ + params
+ count
;
1108 pSMB
->DataCount
= cpu_to_le16(count
);
1109 pSMB
->ParameterCount
= cpu_to_le16(params
);
1110 pSMB
->TotalDataCount
= pSMB
->DataCount
;
1111 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1112 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_OPEN
);
1113 pSMB
->Reserved4
= 0;
1114 inc_rfc1001_len(pSMB
, byte_count
);
1115 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1116 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1117 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1119 cifs_dbg(FYI
, "Posix create returned %d\n", rc
);
1120 goto psx_create_err
;
1123 cifs_dbg(FYI
, "copying inode info\n");
1124 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
1126 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)) {
1127 rc
= -EIO
; /* bad smb */
1128 goto psx_create_err
;
1131 /* copy return information to pRetData */
1132 psx_rsp
= (OPEN_PSX_RSP
*)((char *) &pSMBr
->hdr
.Protocol
1133 + le16_to_cpu(pSMBr
->t2
.DataOffset
));
1135 *pOplock
= le16_to_cpu(psx_rsp
->OplockFlags
);
1137 *netfid
= psx_rsp
->Fid
; /* cifs fid stays in le */
1138 /* Let caller know file was created so we can set the mode. */
1139 /* Do we care about the CreateAction in any other cases? */
1140 if (cpu_to_le32(FILE_CREATE
) == psx_rsp
->CreateAction
)
1141 *pOplock
|= CIFS_CREATE_ACTION
;
1142 /* check to make sure response data is there */
1143 if (psx_rsp
->ReturnedLevel
!= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
)) {
1144 pRetData
->Type
= cpu_to_le32(-1); /* unknown */
1145 cifs_dbg(NOISY
, "unknown type\n");
1147 if (get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)
1148 + sizeof(FILE_UNIX_BASIC_INFO
)) {
1149 cifs_dbg(VFS
, "Open response data too small\n");
1150 pRetData
->Type
= cpu_to_le32(-1);
1151 goto psx_create_err
;
1153 memcpy((char *) pRetData
,
1154 (char *)psx_rsp
+ sizeof(OPEN_PSX_RSP
),
1155 sizeof(FILE_UNIX_BASIC_INFO
));
1159 cifs_buf_release(pSMB
);
1161 if (posix_flags
& SMB_O_DIRECTORY
)
1162 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixmkdirs
);
1164 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixopens
);
1172 static __u16
convert_disposition(int disposition
)
1176 switch (disposition
) {
1177 case FILE_SUPERSEDE
:
1178 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1181 ofun
= SMBOPEN_OAPPEND
;
1184 ofun
= SMBOPEN_OCREATE
;
1187 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OAPPEND
;
1189 case FILE_OVERWRITE
:
1190 ofun
= SMBOPEN_OTRUNC
;
1192 case FILE_OVERWRITE_IF
:
1193 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1196 cifs_dbg(FYI
, "unknown disposition %d\n", disposition
);
1197 ofun
= SMBOPEN_OAPPEND
; /* regular open */
1203 access_flags_to_smbopen_mode(const int access_flags
)
1205 int masked_flags
= access_flags
& (GENERIC_READ
| GENERIC_WRITE
);
1207 if (masked_flags
== GENERIC_READ
)
1208 return SMBOPEN_READ
;
1209 else if (masked_flags
== GENERIC_WRITE
)
1210 return SMBOPEN_WRITE
;
1212 /* just go for read/write */
1213 return SMBOPEN_READWRITE
;
1217 SMBLegacyOpen(const unsigned int xid
, struct cifs_tcon
*tcon
,
1218 const char *fileName
, const int openDisposition
,
1219 const int access_flags
, const int create_options
, __u16
*netfid
,
1220 int *pOplock
, FILE_ALL_INFO
*pfile_info
,
1221 const struct nls_table
*nls_codepage
, int remap
)
1224 OPENX_REQ
*pSMB
= NULL
;
1225 OPENX_RSP
*pSMBr
= NULL
;
1231 rc
= smb_init(SMB_COM_OPEN_ANDX
, 15, tcon
, (void **) &pSMB
,
1236 pSMB
->AndXCommand
= 0xFF; /* none */
1238 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1239 count
= 1; /* account for one byte pad to word boundary */
1241 cifsConvertToUTF16((__le16
*) (pSMB
->fileName
+ 1),
1242 fileName
, PATH_MAX
, nls_codepage
, remap
);
1243 name_len
++; /* trailing null */
1246 count
= 0; /* no pad */
1247 name_len
= copy_path_name(pSMB
->fileName
, fileName
);
1249 if (*pOplock
& REQ_OPLOCK
)
1250 pSMB
->OpenFlags
= cpu_to_le16(REQ_OPLOCK
);
1251 else if (*pOplock
& REQ_BATCHOPLOCK
)
1252 pSMB
->OpenFlags
= cpu_to_le16(REQ_BATCHOPLOCK
);
1254 pSMB
->OpenFlags
|= cpu_to_le16(REQ_MORE_INFO
);
1255 pSMB
->Mode
= cpu_to_le16(access_flags_to_smbopen_mode(access_flags
));
1256 pSMB
->Mode
|= cpu_to_le16(0x40); /* deny none */
1257 /* set file as system file if special file such
1258 as fifo and server expecting SFU style and
1259 no Unix extensions */
1261 if (create_options
& CREATE_OPTION_SPECIAL
)
1262 pSMB
->FileAttributes
= cpu_to_le16(ATTR_SYSTEM
);
1263 else /* BB FIXME BB */
1264 pSMB
->FileAttributes
= cpu_to_le16(0/*ATTR_NORMAL*/);
1266 if (create_options
& CREATE_OPTION_READONLY
)
1267 pSMB
->FileAttributes
|= cpu_to_le16(ATTR_READONLY
);
1270 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1271 CREATE_OPTIONS_MASK); */
1272 /* BB FIXME END BB */
1274 pSMB
->Sattr
= cpu_to_le16(ATTR_HIDDEN
| ATTR_SYSTEM
| ATTR_DIRECTORY
);
1275 pSMB
->OpenFunction
= cpu_to_le16(convert_disposition(openDisposition
));
1277 inc_rfc1001_len(pSMB
, count
);
1279 pSMB
->ByteCount
= cpu_to_le16(count
);
1280 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1281 (struct smb_hdr
*)pSMBr
, &bytes_returned
, 0);
1282 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1284 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1286 /* BB verify if wct == 15 */
1288 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1290 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
1291 /* Let caller know file was created so we can set the mode. */
1292 /* Do we care about the CreateAction in any other cases? */
1294 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1295 *pOplock |= CIFS_CREATE_ACTION; */
1299 pfile_info
->CreationTime
= 0; /* BB convert CreateTime*/
1300 pfile_info
->LastAccessTime
= 0; /* BB fixme */
1301 pfile_info
->LastWriteTime
= 0; /* BB fixme */
1302 pfile_info
->ChangeTime
= 0; /* BB fixme */
1303 pfile_info
->Attributes
=
1304 cpu_to_le32(le16_to_cpu(pSMBr
->FileAttributes
));
1305 /* the file_info buf is endian converted by caller */
1306 pfile_info
->AllocationSize
=
1307 cpu_to_le64(le32_to_cpu(pSMBr
->EndOfFile
));
1308 pfile_info
->EndOfFile
= pfile_info
->AllocationSize
;
1309 pfile_info
->NumberOfLinks
= cpu_to_le32(1);
1310 pfile_info
->DeletePending
= 0;
1314 cifs_buf_release(pSMB
);
1321 CIFS_open(const unsigned int xid
, struct cifs_open_parms
*oparms
, int *oplock
,
1325 OPEN_REQ
*req
= NULL
;
1326 OPEN_RSP
*rsp
= NULL
;
1330 struct cifs_sb_info
*cifs_sb
= oparms
->cifs_sb
;
1331 struct cifs_tcon
*tcon
= oparms
->tcon
;
1332 int remap
= cifs_remap(cifs_sb
);
1333 const struct nls_table
*nls
= cifs_sb
->local_nls
;
1334 int create_options
= oparms
->create_options
;
1335 int desired_access
= oparms
->desired_access
;
1336 int disposition
= oparms
->disposition
;
1337 const char *path
= oparms
->path
;
1340 rc
= smb_init(SMB_COM_NT_CREATE_ANDX
, 24, tcon
, (void **)&req
,
1345 /* no commands go after this */
1346 req
->AndXCommand
= 0xFF;
1348 if (req
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1349 /* account for one byte pad to word boundary */
1351 name_len
= cifsConvertToUTF16((__le16
*)(req
->fileName
+ 1),
1352 path
, PATH_MAX
, nls
, remap
);
1356 req
->NameLength
= cpu_to_le16(name_len
);
1358 /* BB improve check for buffer overruns BB */
1361 name_len
= copy_path_name(req
->fileName
, path
);
1362 req
->NameLength
= cpu_to_le16(name_len
);
1365 if (*oplock
& REQ_OPLOCK
)
1366 req
->OpenFlags
= cpu_to_le32(REQ_OPLOCK
);
1367 else if (*oplock
& REQ_BATCHOPLOCK
)
1368 req
->OpenFlags
= cpu_to_le32(REQ_BATCHOPLOCK
);
1370 req
->DesiredAccess
= cpu_to_le32(desired_access
);
1371 req
->AllocationSize
= 0;
1374 * Set file as system file if special file such as fifo and server
1375 * expecting SFU style and no Unix extensions.
1377 if (create_options
& CREATE_OPTION_SPECIAL
)
1378 req
->FileAttributes
= cpu_to_le32(ATTR_SYSTEM
);
1380 req
->FileAttributes
= cpu_to_le32(ATTR_NORMAL
);
1383 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1384 * sensitive checks for other servers such as Samba.
1386 if (tcon
->ses
->capabilities
& CAP_UNIX
)
1387 req
->FileAttributes
|= cpu_to_le32(ATTR_POSIX_SEMANTICS
);
1389 if (create_options
& CREATE_OPTION_READONLY
)
1390 req
->FileAttributes
|= cpu_to_le32(ATTR_READONLY
);
1392 req
->ShareAccess
= cpu_to_le32(FILE_SHARE_ALL
);
1393 req
->CreateDisposition
= cpu_to_le32(disposition
);
1394 req
->CreateOptions
= cpu_to_le32(create_options
& CREATE_OPTIONS_MASK
);
1396 /* BB Expirement with various impersonation levels and verify */
1397 req
->ImpersonationLevel
= cpu_to_le32(SECURITY_IMPERSONATION
);
1398 req
->SecurityFlags
= SECURITY_CONTEXT_TRACKING
|SECURITY_EFFECTIVE_ONLY
;
1401 inc_rfc1001_len(req
, count
);
1403 req
->ByteCount
= cpu_to_le16(count
);
1404 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*)req
,
1405 (struct smb_hdr
*)rsp
, &bytes_returned
, 0);
1406 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1408 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1409 cifs_buf_release(req
);
1415 /* 1 byte no need to le_to_cpu */
1416 *oplock
= rsp
->OplockLevel
;
1417 /* cifs fid stays in le */
1418 oparms
->fid
->netfid
= rsp
->Fid
;
1419 oparms
->fid
->access
= desired_access
;
1421 /* Let caller know file was created so we can set the mode. */
1422 /* Do we care about the CreateAction in any other cases? */
1423 if (cpu_to_le32(FILE_CREATE
) == rsp
->CreateAction
)
1424 *oplock
|= CIFS_CREATE_ACTION
;
1427 /* copy from CreationTime to Attributes */
1428 memcpy((char *)buf
, (char *)&rsp
->CreationTime
, 36);
1429 /* the file_info buf is endian converted by caller */
1430 buf
->AllocationSize
= rsp
->AllocationSize
;
1431 buf
->EndOfFile
= rsp
->EndOfFile
;
1432 buf
->NumberOfLinks
= cpu_to_le32(1);
1433 buf
->DeletePending
= 0;
1436 cifs_buf_release(req
);
1441 * Discard any remaining data in the current SMB. To do this, we borrow the
1445 cifs_discard_remaining_data(struct TCP_Server_Info
*server
)
1447 unsigned int rfclen
= server
->pdu_size
;
1448 int remaining
= rfclen
+ server
->vals
->header_preamble_size
-
1451 while (remaining
> 0) {
1454 length
= cifs_read_from_socket(server
, server
->bigbuf
,
1455 min_t(unsigned int, remaining
,
1456 CIFSMaxBufSize
+ MAX_HEADER_SIZE(server
)));
1459 server
->total_read
+= length
;
1460 remaining
-= length
;
1467 __cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
,
1472 length
= cifs_discard_remaining_data(server
);
1473 dequeue_mid(mid
, malformed
);
1474 mid
->resp_buf
= server
->smallbuf
;
1475 server
->smallbuf
= NULL
;
1480 cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1482 struct cifs_readdata
*rdata
= mid
->callback_data
;
1484 return __cifs_readv_discard(server
, mid
, rdata
->result
);
1488 cifs_readv_receive(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1491 unsigned int data_offset
, data_len
;
1492 struct cifs_readdata
*rdata
= mid
->callback_data
;
1493 char *buf
= server
->smallbuf
;
1494 unsigned int buflen
= server
->pdu_size
+
1495 server
->vals
->header_preamble_size
;
1496 bool use_rdma_mr
= false;
1498 cifs_dbg(FYI
, "%s: mid=%llu offset=%llu bytes=%u\n",
1499 __func__
, mid
->mid
, rdata
->offset
, rdata
->bytes
);
1502 * read the rest of READ_RSP header (sans Data array), or whatever we
1503 * can if there's not enough data. At this point, we've read down to
1506 len
= min_t(unsigned int, buflen
, server
->vals
->read_rsp_size
) -
1507 HEADER_SIZE(server
) + 1;
1509 length
= cifs_read_from_socket(server
,
1510 buf
+ HEADER_SIZE(server
) - 1, len
);
1513 server
->total_read
+= length
;
1515 if (server
->ops
->is_session_expired
&&
1516 server
->ops
->is_session_expired(buf
)) {
1517 cifs_reconnect(server
);
1521 if (server
->ops
->is_status_pending
&&
1522 server
->ops
->is_status_pending(buf
, server
)) {
1523 cifs_discard_remaining_data(server
);
1527 /* set up first two iov for signature check and to get credits */
1528 rdata
->iov
[0].iov_base
= buf
;
1529 rdata
->iov
[0].iov_len
= server
->vals
->header_preamble_size
;
1530 rdata
->iov
[1].iov_base
= buf
+ server
->vals
->header_preamble_size
;
1531 rdata
->iov
[1].iov_len
=
1532 server
->total_read
- server
->vals
->header_preamble_size
;
1533 cifs_dbg(FYI
, "0: iov_base=%p iov_len=%zu\n",
1534 rdata
->iov
[0].iov_base
, rdata
->iov
[0].iov_len
);
1535 cifs_dbg(FYI
, "1: iov_base=%p iov_len=%zu\n",
1536 rdata
->iov
[1].iov_base
, rdata
->iov
[1].iov_len
);
1538 /* Was the SMB read successful? */
1539 rdata
->result
= server
->ops
->map_error(buf
, false);
1540 if (rdata
->result
!= 0) {
1541 cifs_dbg(FYI
, "%s: server returned error %d\n",
1542 __func__
, rdata
->result
);
1543 /* normal error on read response */
1544 return __cifs_readv_discard(server
, mid
, false);
1547 /* Is there enough to get to the rest of the READ_RSP header? */
1548 if (server
->total_read
< server
->vals
->read_rsp_size
) {
1549 cifs_dbg(FYI
, "%s: server returned short header. got=%u expected=%zu\n",
1550 __func__
, server
->total_read
,
1551 server
->vals
->read_rsp_size
);
1552 rdata
->result
= -EIO
;
1553 return cifs_readv_discard(server
, mid
);
1556 data_offset
= server
->ops
->read_data_offset(buf
) +
1557 server
->vals
->header_preamble_size
;
1558 if (data_offset
< server
->total_read
) {
1560 * win2k8 sometimes sends an offset of 0 when the read
1561 * is beyond the EOF. Treat it as if the data starts just after
1564 cifs_dbg(FYI
, "%s: data offset (%u) inside read response header\n",
1565 __func__
, data_offset
);
1566 data_offset
= server
->total_read
;
1567 } else if (data_offset
> MAX_CIFS_SMALL_BUFFER_SIZE
) {
1568 /* data_offset is beyond the end of smallbuf */
1569 cifs_dbg(FYI
, "%s: data offset (%u) beyond end of smallbuf\n",
1570 __func__
, data_offset
);
1571 rdata
->result
= -EIO
;
1572 return cifs_readv_discard(server
, mid
);
1575 cifs_dbg(FYI
, "%s: total_read=%u data_offset=%u\n",
1576 __func__
, server
->total_read
, data_offset
);
1578 len
= data_offset
- server
->total_read
;
1580 /* read any junk before data into the rest of smallbuf */
1581 length
= cifs_read_from_socket(server
,
1582 buf
+ server
->total_read
, len
);
1585 server
->total_read
+= length
;
1588 /* how much data is in the response? */
1589 #ifdef CONFIG_CIFS_SMB_DIRECT
1590 use_rdma_mr
= rdata
->mr
;
1592 data_len
= server
->ops
->read_data_length(buf
, use_rdma_mr
);
1593 if (!use_rdma_mr
&& (data_offset
+ data_len
> buflen
)) {
1594 /* data_len is corrupt -- discard frame */
1595 rdata
->result
= -EIO
;
1596 return cifs_readv_discard(server
, mid
);
1599 length
= rdata
->read_into_pages(server
, rdata
, data_len
);
1603 server
->total_read
+= length
;
1605 cifs_dbg(FYI
, "total_read=%u buflen=%u remaining=%u\n",
1606 server
->total_read
, buflen
, data_len
);
1608 /* discard anything left over */
1609 if (server
->total_read
< buflen
)
1610 return cifs_readv_discard(server
, mid
);
1612 dequeue_mid(mid
, false);
1613 mid
->resp_buf
= server
->smallbuf
;
1614 server
->smallbuf
= NULL
;
1619 cifs_readv_callback(struct mid_q_entry
*mid
)
1621 struct cifs_readdata
*rdata
= mid
->callback_data
;
1622 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1623 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
1624 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1626 .rq_pages
= rdata
->pages
,
1627 .rq_offset
= rdata
->page_offset
,
1628 .rq_npages
= rdata
->nr_pages
,
1629 .rq_pagesz
= rdata
->pagesz
,
1630 .rq_tailsz
= rdata
->tailsz
};
1631 struct cifs_credits credits
= { .value
= 1, .instance
= 0 };
1633 cifs_dbg(FYI
, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1634 __func__
, mid
->mid
, mid
->mid_state
, rdata
->result
,
1637 switch (mid
->mid_state
) {
1638 case MID_RESPONSE_RECEIVED
:
1639 /* result already set, check signature */
1643 rc
= cifs_verify_signature(&rqst
, server
,
1644 mid
->sequence_number
);
1646 cifs_dbg(VFS
, "SMB signature verification returned error = %d\n",
1649 /* FIXME: should this be counted toward the initiating task? */
1650 task_io_account_read(rdata
->got_bytes
);
1651 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1653 case MID_REQUEST_SUBMITTED
:
1654 case MID_RETRY_NEEDED
:
1655 rdata
->result
= -EAGAIN
;
1656 if (server
->sign
&& rdata
->got_bytes
)
1657 /* reset bytes number since we can not check a sign */
1658 rdata
->got_bytes
= 0;
1659 /* FIXME: should this be counted toward the initiating task? */
1660 task_io_account_read(rdata
->got_bytes
);
1661 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1664 rdata
->result
= -EIO
;
1667 queue_work(cifsiod_wq
, &rdata
->work
);
1668 DeleteMidQEntry(mid
);
1669 add_credits(server
, &credits
, 0);
1672 /* cifs_async_readv - send an async write, and set up mid to handle result */
1674 cifs_async_readv(struct cifs_readdata
*rdata
)
1677 READ_REQ
*smb
= NULL
;
1679 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1680 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1683 cifs_dbg(FYI
, "%s: offset=%llu bytes=%u\n",
1684 __func__
, rdata
->offset
, rdata
->bytes
);
1686 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1689 wct
= 10; /* old style read */
1690 if ((rdata
->offset
>> 32) > 0) {
1691 /* can not handle this big offset for old */
1696 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **)&smb
);
1700 smb
->hdr
.Pid
= cpu_to_le16((__u16
)rdata
->pid
);
1701 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(rdata
->pid
>> 16));
1703 smb
->AndXCommand
= 0xFF; /* none */
1704 smb
->Fid
= rdata
->cfile
->fid
.netfid
;
1705 smb
->OffsetLow
= cpu_to_le32(rdata
->offset
& 0xFFFFFFFF);
1707 smb
->OffsetHigh
= cpu_to_le32(rdata
->offset
>> 32);
1709 smb
->MaxCount
= cpu_to_le16(rdata
->bytes
& 0xFFFF);
1710 smb
->MaxCountHigh
= cpu_to_le32(rdata
->bytes
>> 16);
1714 /* old style read */
1715 struct smb_com_readx_req
*smbr
=
1716 (struct smb_com_readx_req
*)smb
;
1717 smbr
->ByteCount
= 0;
1720 /* 4 for RFC1001 length + 1 for BCC */
1721 rdata
->iov
[0].iov_base
= smb
;
1722 rdata
->iov
[0].iov_len
= 4;
1723 rdata
->iov
[1].iov_base
= (char *)smb
+ 4;
1724 rdata
->iov
[1].iov_len
= get_rfc1002_length(smb
);
1726 kref_get(&rdata
->refcount
);
1727 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, cifs_readv_receive
,
1728 cifs_readv_callback
, NULL
, rdata
, 0, NULL
);
1731 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1733 kref_put(&rdata
->refcount
, cifs_readdata_release
);
1735 cifs_small_buf_release(smb
);
1740 CIFSSMBRead(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1741 unsigned int *nbytes
, char **buf
, int *pbuf_type
)
1744 READ_REQ
*pSMB
= NULL
;
1745 READ_RSP
*pSMBr
= NULL
;
1746 char *pReadData
= NULL
;
1748 int resp_buf_type
= 0;
1750 struct kvec rsp_iov
;
1751 __u32 pid
= io_parms
->pid
;
1752 __u16 netfid
= io_parms
->netfid
;
1753 __u64 offset
= io_parms
->offset
;
1754 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1755 unsigned int count
= io_parms
->length
;
1757 cifs_dbg(FYI
, "Reading %d bytes on fid %d\n", count
, netfid
);
1758 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1761 wct
= 10; /* old style read */
1762 if ((offset
>> 32) > 0) {
1763 /* can not handle this big offset for old */
1769 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **) &pSMB
);
1773 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1774 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1776 /* tcon and ses pointer are checked in smb_init */
1777 if (tcon
->ses
->server
== NULL
)
1778 return -ECONNABORTED
;
1780 pSMB
->AndXCommand
= 0xFF; /* none */
1782 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1784 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1786 pSMB
->Remaining
= 0;
1787 pSMB
->MaxCount
= cpu_to_le16(count
& 0xFFFF);
1788 pSMB
->MaxCountHigh
= cpu_to_le32(count
>> 16);
1790 pSMB
->ByteCount
= 0; /* no need to do le conversion since 0 */
1792 /* old style read */
1793 struct smb_com_readx_req
*pSMBW
=
1794 (struct smb_com_readx_req
*)pSMB
;
1795 pSMBW
->ByteCount
= 0;
1798 iov
[0].iov_base
= (char *)pSMB
;
1799 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
1800 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1, &resp_buf_type
,
1801 CIFS_LOG_ERROR
, &rsp_iov
);
1802 cifs_small_buf_release(pSMB
);
1803 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1804 pSMBr
= (READ_RSP
*)rsp_iov
.iov_base
;
1806 cifs_dbg(VFS
, "Send error in read = %d\n", rc
);
1808 int data_length
= le16_to_cpu(pSMBr
->DataLengthHigh
);
1809 data_length
= data_length
<< 16;
1810 data_length
+= le16_to_cpu(pSMBr
->DataLength
);
1811 *nbytes
= data_length
;
1813 /*check that DataLength would not go beyond end of SMB */
1814 if ((data_length
> CIFSMaxBufSize
)
1815 || (data_length
> count
)) {
1816 cifs_dbg(FYI
, "bad length %d for count %d\n",
1817 data_length
, count
);
1821 pReadData
= (char *) (&pSMBr
->hdr
.Protocol
) +
1822 le16_to_cpu(pSMBr
->DataOffset
);
1823 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1824 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1826 }*/ /* can not use copy_to_user when using page cache*/
1828 memcpy(*buf
, pReadData
, data_length
);
1833 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
1834 } else if (resp_buf_type
!= CIFS_NO_BUFFER
) {
1835 /* return buffer to caller to free */
1836 *buf
= rsp_iov
.iov_base
;
1837 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1838 *pbuf_type
= CIFS_SMALL_BUFFER
;
1839 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1840 *pbuf_type
= CIFS_LARGE_BUFFER
;
1841 } /* else no valid buffer on return - leave as null */
1843 /* Note: On -EAGAIN error only caller can retry on handle based calls
1844 since file handle passed in no longer valid */
1850 CIFSSMBWrite(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1851 unsigned int *nbytes
, const char *buf
)
1854 WRITE_REQ
*pSMB
= NULL
;
1855 WRITE_RSP
*pSMBr
= NULL
;
1856 int bytes_returned
, wct
;
1859 __u32 pid
= io_parms
->pid
;
1860 __u16 netfid
= io_parms
->netfid
;
1861 __u64 offset
= io_parms
->offset
;
1862 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1863 unsigned int count
= io_parms
->length
;
1867 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1868 if (tcon
->ses
== NULL
)
1869 return -ECONNABORTED
;
1871 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1875 if ((offset
>> 32) > 0) {
1876 /* can not handle big offset for old srv */
1881 rc
= smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
,
1886 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1887 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1889 /* tcon and ses pointer are checked in smb_init */
1890 if (tcon
->ses
->server
== NULL
)
1891 return -ECONNABORTED
;
1893 pSMB
->AndXCommand
= 0xFF; /* none */
1895 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1897 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1899 pSMB
->Reserved
= 0xFFFFFFFF;
1900 pSMB
->WriteMode
= 0;
1901 pSMB
->Remaining
= 0;
1903 /* Can increase buffer size if buffer is big enough in some cases ie we
1904 can send more if LARGE_WRITE_X capability returned by the server and if
1905 our buffer is big enough or if we convert to iovecs on socket writes
1906 and eliminate the copy to the CIFS buffer */
1907 if (tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
) {
1908 bytes_sent
= min_t(const unsigned int, CIFSMaxBufSize
, count
);
1910 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
)
1914 if (bytes_sent
> count
)
1917 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1919 memcpy(pSMB
->Data
, buf
, bytes_sent
);
1920 else if (count
!= 0) {
1922 cifs_buf_release(pSMB
);
1924 } /* else setting file size with write of zero bytes */
1926 byte_count
= bytes_sent
+ 1; /* pad */
1927 else /* wct == 12 */
1928 byte_count
= bytes_sent
+ 5; /* bigger pad, smaller smb hdr */
1930 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
& 0xFFFF);
1931 pSMB
->DataLengthHigh
= cpu_to_le16(bytes_sent
>> 16);
1932 inc_rfc1001_len(pSMB
, byte_count
);
1935 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1936 else { /* old style write has byte count 4 bytes earlier
1938 struct smb_com_writex_req
*pSMBW
=
1939 (struct smb_com_writex_req
*)pSMB
;
1940 pSMBW
->ByteCount
= cpu_to_le16(byte_count
);
1943 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1944 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1945 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
1947 cifs_dbg(FYI
, "Send error in write = %d\n", rc
);
1949 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
1950 *nbytes
= (*nbytes
) << 16;
1951 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
1954 * Mask off high 16 bits when bytes written as returned by the
1955 * server is greater than bytes requested by the client. Some
1956 * OS/2 servers are known to set incorrect CountHigh values.
1958 if (*nbytes
> count
)
1962 cifs_buf_release(pSMB
);
1964 /* Note: On -EAGAIN error only caller can retry on handle based calls
1965 since file handle passed in no longer valid */
1971 cifs_writedata_release(struct kref
*refcount
)
1973 struct cifs_writedata
*wdata
= container_of(refcount
,
1974 struct cifs_writedata
, refcount
);
1975 #ifdef CONFIG_CIFS_SMB_DIRECT
1977 smbd_deregister_mr(wdata
->mr
);
1983 cifsFileInfo_put(wdata
->cfile
);
1985 kvfree(wdata
->pages
);
1990 * Write failed with a retryable error. Resend the write request. It's also
1991 * possible that the page was redirtied so re-clean the page.
1994 cifs_writev_requeue(struct cifs_writedata
*wdata
)
1997 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
1998 struct TCP_Server_Info
*server
;
1999 unsigned int rest_len
;
2001 server
= tlink_tcon(wdata
->cfile
->tlink
)->ses
->server
;
2003 rest_len
= wdata
->bytes
;
2005 struct cifs_writedata
*wdata2
;
2006 unsigned int j
, nr_pages
, wsize
, tailsz
, cur_len
;
2008 wsize
= server
->ops
->wp_retry_size(inode
);
2009 if (wsize
< rest_len
) {
2010 nr_pages
= wsize
/ PAGE_SIZE
;
2015 cur_len
= nr_pages
* PAGE_SIZE
;
2018 nr_pages
= DIV_ROUND_UP(rest_len
, PAGE_SIZE
);
2020 tailsz
= rest_len
- (nr_pages
- 1) * PAGE_SIZE
;
2023 wdata2
= cifs_writedata_alloc(nr_pages
, cifs_writev_complete
);
2029 for (j
= 0; j
< nr_pages
; j
++) {
2030 wdata2
->pages
[j
] = wdata
->pages
[i
+ j
];
2031 lock_page(wdata2
->pages
[j
]);
2032 clear_page_dirty_for_io(wdata2
->pages
[j
]);
2035 wdata2
->sync_mode
= wdata
->sync_mode
;
2036 wdata2
->nr_pages
= nr_pages
;
2037 wdata2
->offset
= page_offset(wdata2
->pages
[0]);
2038 wdata2
->pagesz
= PAGE_SIZE
;
2039 wdata2
->tailsz
= tailsz
;
2040 wdata2
->bytes
= cur_len
;
2042 rc
= cifs_get_writable_file(CIFS_I(inode
), FIND_WR_ANY
,
2044 if (!wdata2
->cfile
) {
2045 cifs_dbg(VFS
, "No writable handle to retry writepages rc=%d\n",
2047 if (!is_retryable_error(rc
))
2050 wdata2
->pid
= wdata2
->cfile
->pid
;
2051 rc
= server
->ops
->async_writev(wdata2
,
2052 cifs_writedata_release
);
2055 for (j
= 0; j
< nr_pages
; j
++) {
2056 unlock_page(wdata2
->pages
[j
]);
2057 if (rc
!= 0 && !is_retryable_error(rc
)) {
2058 SetPageError(wdata2
->pages
[j
]);
2059 end_page_writeback(wdata2
->pages
[j
]);
2060 put_page(wdata2
->pages
[j
]);
2064 kref_put(&wdata2
->refcount
, cifs_writedata_release
);
2066 if (is_retryable_error(rc
))
2072 rest_len
-= cur_len
;
2074 } while (i
< wdata
->nr_pages
);
2076 /* cleanup remaining pages from the original wdata */
2077 for (; i
< wdata
->nr_pages
; i
++) {
2078 SetPageError(wdata
->pages
[i
]);
2079 end_page_writeback(wdata
->pages
[i
]);
2080 put_page(wdata
->pages
[i
]);
2083 if (rc
!= 0 && !is_retryable_error(rc
))
2084 mapping_set_error(inode
->i_mapping
, rc
);
2085 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2089 cifs_writev_complete(struct work_struct
*work
)
2091 struct cifs_writedata
*wdata
= container_of(work
,
2092 struct cifs_writedata
, work
);
2093 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
2096 if (wdata
->result
== 0) {
2097 spin_lock(&inode
->i_lock
);
2098 cifs_update_eof(CIFS_I(inode
), wdata
->offset
, wdata
->bytes
);
2099 spin_unlock(&inode
->i_lock
);
2100 cifs_stats_bytes_written(tlink_tcon(wdata
->cfile
->tlink
),
2102 } else if (wdata
->sync_mode
== WB_SYNC_ALL
&& wdata
->result
== -EAGAIN
)
2103 return cifs_writev_requeue(wdata
);
2105 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
2106 struct page
*page
= wdata
->pages
[i
];
2107 if (wdata
->result
== -EAGAIN
)
2108 __set_page_dirty_nobuffers(page
);
2109 else if (wdata
->result
< 0)
2111 end_page_writeback(page
);
2114 if (wdata
->result
!= -EAGAIN
)
2115 mapping_set_error(inode
->i_mapping
, wdata
->result
);
2116 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2119 struct cifs_writedata
*
2120 cifs_writedata_alloc(unsigned int nr_pages
, work_func_t complete
)
2122 struct page
**pages
=
2123 kcalloc(nr_pages
, sizeof(struct page
*), GFP_NOFS
);
2125 return cifs_writedata_direct_alloc(pages
, complete
);
2130 struct cifs_writedata
*
2131 cifs_writedata_direct_alloc(struct page
**pages
, work_func_t complete
)
2133 struct cifs_writedata
*wdata
;
2135 wdata
= kzalloc(sizeof(*wdata
), GFP_NOFS
);
2136 if (wdata
!= NULL
) {
2137 wdata
->pages
= pages
;
2138 kref_init(&wdata
->refcount
);
2139 INIT_LIST_HEAD(&wdata
->list
);
2140 init_completion(&wdata
->done
);
2141 INIT_WORK(&wdata
->work
, complete
);
2147 * Check the mid_state and signature on received buffer (if any), and queue the
2148 * workqueue completion task.
2151 cifs_writev_callback(struct mid_q_entry
*mid
)
2153 struct cifs_writedata
*wdata
= mid
->callback_data
;
2154 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2155 unsigned int written
;
2156 WRITE_RSP
*smb
= (WRITE_RSP
*)mid
->resp_buf
;
2157 struct cifs_credits credits
= { .value
= 1, .instance
= 0 };
2159 switch (mid
->mid_state
) {
2160 case MID_RESPONSE_RECEIVED
:
2161 wdata
->result
= cifs_check_receive(mid
, tcon
->ses
->server
, 0);
2162 if (wdata
->result
!= 0)
2165 written
= le16_to_cpu(smb
->CountHigh
);
2167 written
+= le16_to_cpu(smb
->Count
);
2169 * Mask off high 16 bits when bytes written as returned
2170 * by the server is greater than bytes requested by the
2171 * client. OS/2 servers are known to set incorrect
2174 if (written
> wdata
->bytes
)
2177 if (written
< wdata
->bytes
)
2178 wdata
->result
= -ENOSPC
;
2180 wdata
->bytes
= written
;
2182 case MID_REQUEST_SUBMITTED
:
2183 case MID_RETRY_NEEDED
:
2184 wdata
->result
= -EAGAIN
;
2187 wdata
->result
= -EIO
;
2191 queue_work(cifsiod_wq
, &wdata
->work
);
2192 DeleteMidQEntry(mid
);
2193 add_credits(tcon
->ses
->server
, &credits
, 0);
2196 /* cifs_async_writev - send an async write, and set up mid to handle result */
2198 cifs_async_writev(struct cifs_writedata
*wdata
,
2199 void (*release
)(struct kref
*kref
))
2202 WRITE_REQ
*smb
= NULL
;
2204 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2206 struct smb_rqst rqst
= { };
2208 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2212 if (wdata
->offset
>> 32 > 0) {
2213 /* can not handle big offset for old srv */
2218 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **)&smb
);
2220 goto async_writev_out
;
2222 smb
->hdr
.Pid
= cpu_to_le16((__u16
)wdata
->pid
);
2223 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(wdata
->pid
>> 16));
2225 smb
->AndXCommand
= 0xFF; /* none */
2226 smb
->Fid
= wdata
->cfile
->fid
.netfid
;
2227 smb
->OffsetLow
= cpu_to_le32(wdata
->offset
& 0xFFFFFFFF);
2229 smb
->OffsetHigh
= cpu_to_le32(wdata
->offset
>> 32);
2230 smb
->Reserved
= 0xFFFFFFFF;
2235 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2237 /* 4 for RFC1001 length + 1 for BCC */
2239 iov
[0].iov_base
= smb
;
2240 iov
[1].iov_len
= get_rfc1002_length(smb
) + 1;
2241 iov
[1].iov_base
= (char *)smb
+ 4;
2245 rqst
.rq_pages
= wdata
->pages
;
2246 rqst
.rq_offset
= wdata
->page_offset
;
2247 rqst
.rq_npages
= wdata
->nr_pages
;
2248 rqst
.rq_pagesz
= wdata
->pagesz
;
2249 rqst
.rq_tailsz
= wdata
->tailsz
;
2251 cifs_dbg(FYI
, "async write at %llu %u bytes\n",
2252 wdata
->offset
, wdata
->bytes
);
2254 smb
->DataLengthLow
= cpu_to_le16(wdata
->bytes
& 0xFFFF);
2255 smb
->DataLengthHigh
= cpu_to_le16(wdata
->bytes
>> 16);
2258 inc_rfc1001_len(&smb
->hdr
, wdata
->bytes
+ 1);
2259 put_bcc(wdata
->bytes
+ 1, &smb
->hdr
);
2262 struct smb_com_writex_req
*smbw
=
2263 (struct smb_com_writex_req
*)smb
;
2264 inc_rfc1001_len(&smbw
->hdr
, wdata
->bytes
+ 5);
2265 put_bcc(wdata
->bytes
+ 5, &smbw
->hdr
);
2266 iov
[1].iov_len
+= 4; /* pad bigger by four bytes */
2269 kref_get(&wdata
->refcount
);
2270 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, NULL
,
2271 cifs_writev_callback
, NULL
, wdata
, 0, NULL
);
2274 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2276 kref_put(&wdata
->refcount
, release
);
2279 cifs_small_buf_release(smb
);
2284 CIFSSMBWrite2(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
2285 unsigned int *nbytes
, struct kvec
*iov
, int n_vec
)
2288 WRITE_REQ
*pSMB
= NULL
;
2291 int resp_buf_type
= 0;
2292 __u32 pid
= io_parms
->pid
;
2293 __u16 netfid
= io_parms
->netfid
;
2294 __u64 offset
= io_parms
->offset
;
2295 struct cifs_tcon
*tcon
= io_parms
->tcon
;
2296 unsigned int count
= io_parms
->length
;
2297 struct kvec rsp_iov
;
2301 cifs_dbg(FYI
, "write2 at %lld %d bytes\n", (long long)offset
, count
);
2303 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2307 if ((offset
>> 32) > 0) {
2308 /* can not handle big offset for old srv */
2312 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
);
2316 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
2317 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
2319 /* tcon and ses pointer are checked in smb_init */
2320 if (tcon
->ses
->server
== NULL
)
2321 return -ECONNABORTED
;
2323 pSMB
->AndXCommand
= 0xFF; /* none */
2325 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
2327 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
2328 pSMB
->Reserved
= 0xFFFFFFFF;
2329 pSMB
->WriteMode
= 0;
2330 pSMB
->Remaining
= 0;
2333 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2335 pSMB
->DataLengthLow
= cpu_to_le16(count
& 0xFFFF);
2336 pSMB
->DataLengthHigh
= cpu_to_le16(count
>> 16);
2337 /* header + 1 byte pad */
2338 smb_hdr_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 1;
2340 inc_rfc1001_len(pSMB
, count
+ 1);
2341 else /* wct == 12 */
2342 inc_rfc1001_len(pSMB
, count
+ 5); /* smb data starts later */
2344 pSMB
->ByteCount
= cpu_to_le16(count
+ 1);
2345 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2346 struct smb_com_writex_req
*pSMBW
=
2347 (struct smb_com_writex_req
*)pSMB
;
2348 pSMBW
->ByteCount
= cpu_to_le16(count
+ 5);
2350 iov
[0].iov_base
= pSMB
;
2352 iov
[0].iov_len
= smb_hdr_len
+ 4;
2353 else /* wct == 12 pad bigger by four bytes */
2354 iov
[0].iov_len
= smb_hdr_len
+ 8;
2356 rc
= SendReceive2(xid
, tcon
->ses
, iov
, n_vec
+ 1, &resp_buf_type
, 0,
2358 cifs_small_buf_release(pSMB
);
2359 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2361 cifs_dbg(FYI
, "Send error Write2 = %d\n", rc
);
2362 } else if (resp_buf_type
== 0) {
2363 /* presumably this can not happen, but best to be safe */
2366 WRITE_RSP
*pSMBr
= (WRITE_RSP
*)rsp_iov
.iov_base
;
2367 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2368 *nbytes
= (*nbytes
) << 16;
2369 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2372 * Mask off high 16 bits when bytes written as returned by the
2373 * server is greater than bytes requested by the client. OS/2
2374 * servers are known to set incorrect CountHigh values.
2376 if (*nbytes
> count
)
2380 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2382 /* Note: On -EAGAIN error only caller can retry on handle based calls
2383 since file handle passed in no longer valid */
2388 int cifs_lockv(const unsigned int xid
, struct cifs_tcon
*tcon
,
2389 const __u16 netfid
, const __u8 lock_type
, const __u32 num_unlock
,
2390 const __u32 num_lock
, LOCKING_ANDX_RANGE
*buf
)
2393 LOCK_REQ
*pSMB
= NULL
;
2395 struct kvec rsp_iov
;
2399 cifs_dbg(FYI
, "cifs_lockv num lock %d num unlock %d\n",
2400 num_lock
, num_unlock
);
2402 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2407 pSMB
->NumberOfLocks
= cpu_to_le16(num_lock
);
2408 pSMB
->NumberOfUnlocks
= cpu_to_le16(num_unlock
);
2409 pSMB
->LockType
= lock_type
;
2410 pSMB
->AndXCommand
= 0xFF; /* none */
2411 pSMB
->Fid
= netfid
; /* netfid stays le */
2413 count
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2414 inc_rfc1001_len(pSMB
, count
);
2415 pSMB
->ByteCount
= cpu_to_le16(count
);
2417 iov
[0].iov_base
= (char *)pSMB
;
2418 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4 -
2419 (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2420 iov
[1].iov_base
= (char *)buf
;
2421 iov
[1].iov_len
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2423 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2424 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 2, &resp_buf_type
,
2425 CIFS_NO_RSP_BUF
, &rsp_iov
);
2426 cifs_small_buf_release(pSMB
);
2428 cifs_dbg(FYI
, "Send error in cifs_lockv = %d\n", rc
);
2434 CIFSSMBLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2435 const __u16 smb_file_id
, const __u32 netpid
, const __u64 len
,
2436 const __u64 offset
, const __u32 numUnlock
,
2437 const __u32 numLock
, const __u8 lockType
,
2438 const bool waitFlag
, const __u8 oplock_level
)
2441 LOCK_REQ
*pSMB
= NULL
;
2442 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2447 cifs_dbg(FYI
, "CIFSSMBLock timeout %d numLock %d\n",
2448 (int)waitFlag
, numLock
);
2449 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2454 if (lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
2455 /* no response expected */
2456 flags
= CIFS_NO_SRV_RSP
| CIFS_NON_BLOCKING
| CIFS_OBREAK_OP
;
2458 } else if (waitFlag
) {
2459 flags
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2460 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
2465 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
2466 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
2467 pSMB
->LockType
= lockType
;
2468 pSMB
->OplockLevel
= oplock_level
;
2469 pSMB
->AndXCommand
= 0xFF; /* none */
2470 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
2472 if ((numLock
!= 0) || (numUnlock
!= 0)) {
2473 pSMB
->Locks
[0].Pid
= cpu_to_le16(netpid
);
2474 /* BB where to store pid high? */
2475 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
2476 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
2477 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
2478 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
2479 count
= sizeof(LOCKING_ANDX_RANGE
);
2484 inc_rfc1001_len(pSMB
, count
);
2485 pSMB
->ByteCount
= cpu_to_le16(count
);
2488 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2489 (struct smb_hdr
*) pSMB
, &bytes_returned
);
2491 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)pSMB
, flags
);
2492 cifs_small_buf_release(pSMB
);
2493 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2495 cifs_dbg(FYI
, "Send error in Lock = %d\n", rc
);
2497 /* Note: On -EAGAIN error only caller can retry on handle based calls
2498 since file handle passed in no longer valid */
2503 CIFSSMBPosixLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2504 const __u16 smb_file_id
, const __u32 netpid
,
2505 const loff_t start_offset
, const __u64 len
,
2506 struct file_lock
*pLockData
, const __u16 lock_type
,
2507 const bool waitFlag
)
2509 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2510 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2511 struct cifs_posix_lock
*parm_data
;
2514 int bytes_returned
= 0;
2515 int resp_buf_type
= 0;
2516 __u16 params
, param_offset
, offset
, byte_count
, count
;
2518 struct kvec rsp_iov
;
2520 cifs_dbg(FYI
, "Posix Lock\n");
2522 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
2527 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)pSMB
;
2530 pSMB
->MaxSetupCount
= 0;
2533 pSMB
->Reserved2
= 0;
2534 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2535 offset
= param_offset
+ params
;
2537 count
= sizeof(struct cifs_posix_lock
);
2538 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2539 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2540 pSMB
->SetupCount
= 1;
2541 pSMB
->Reserved3
= 0;
2543 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
2545 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2546 byte_count
= 3 /* pad */ + params
+ count
;
2547 pSMB
->DataCount
= cpu_to_le16(count
);
2548 pSMB
->ParameterCount
= cpu_to_le16(params
);
2549 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2550 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2551 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2552 parm_data
= (struct cifs_posix_lock
*)
2553 (((char *) &pSMB
->hdr
.Protocol
) + offset
);
2555 parm_data
->lock_type
= cpu_to_le16(lock_type
);
2557 timeout
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2558 parm_data
->lock_flags
= cpu_to_le16(1);
2559 pSMB
->Timeout
= cpu_to_le32(-1);
2563 parm_data
->pid
= cpu_to_le32(netpid
);
2564 parm_data
->start
= cpu_to_le64(start_offset
);
2565 parm_data
->length
= cpu_to_le64(len
); /* normalize negative numbers */
2567 pSMB
->DataOffset
= cpu_to_le16(offset
);
2568 pSMB
->Fid
= smb_file_id
;
2569 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_LOCK
);
2570 pSMB
->Reserved4
= 0;
2571 inc_rfc1001_len(pSMB
, byte_count
);
2572 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2574 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2575 (struct smb_hdr
*) pSMBr
, &bytes_returned
);
2577 iov
[0].iov_base
= (char *)pSMB
;
2578 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
2579 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
2580 &resp_buf_type
, timeout
, &rsp_iov
);
2581 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)rsp_iov
.iov_base
;
2583 cifs_small_buf_release(pSMB
);
2586 cifs_dbg(FYI
, "Send error in Posix Lock = %d\n", rc
);
2587 } else if (pLockData
) {
2588 /* lock structure can be returned on get */
2591 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2593 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(*parm_data
)) {
2594 rc
= -EIO
; /* bad smb */
2597 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
2598 data_count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2599 if (data_count
< sizeof(struct cifs_posix_lock
)) {
2603 parm_data
= (struct cifs_posix_lock
*)
2604 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2605 if (parm_data
->lock_type
== cpu_to_le16(CIFS_UNLCK
))
2606 pLockData
->fl_type
= F_UNLCK
;
2608 if (parm_data
->lock_type
==
2609 cpu_to_le16(CIFS_RDLCK
))
2610 pLockData
->fl_type
= F_RDLCK
;
2611 else if (parm_data
->lock_type
==
2612 cpu_to_le16(CIFS_WRLCK
))
2613 pLockData
->fl_type
= F_WRLCK
;
2615 pLockData
->fl_start
= le64_to_cpu(parm_data
->start
);
2616 pLockData
->fl_end
= pLockData
->fl_start
+
2617 le64_to_cpu(parm_data
->length
) - 1;
2618 pLockData
->fl_pid
= -le32_to_cpu(parm_data
->pid
);
2623 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2625 /* Note: On -EAGAIN error only caller can retry on handle based calls
2626 since file handle passed in no longer valid */
2633 CIFSSMBClose(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2636 CLOSE_REQ
*pSMB
= NULL
;
2637 cifs_dbg(FYI
, "In CIFSSMBClose\n");
2639 /* do not retry on dead session on close */
2640 rc
= small_smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
);
2646 pSMB
->FileID
= (__u16
) smb_file_id
;
2647 pSMB
->LastWriteTime
= 0xFFFFFFFF;
2648 pSMB
->ByteCount
= 0;
2649 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2650 cifs_small_buf_release(pSMB
);
2651 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_closes
);
2654 /* EINTR is expected when user ctl-c to kill app */
2655 cifs_dbg(VFS
, "Send error in Close = %d\n", rc
);
2659 /* Since session is dead, file will be closed on server already */
2667 CIFSSMBFlush(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2670 FLUSH_REQ
*pSMB
= NULL
;
2671 cifs_dbg(FYI
, "In CIFSSMBFlush\n");
2673 rc
= small_smb_init(SMB_COM_FLUSH
, 1, tcon
, (void **) &pSMB
);
2677 pSMB
->FileID
= (__u16
) smb_file_id
;
2678 pSMB
->ByteCount
= 0;
2679 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2680 cifs_small_buf_release(pSMB
);
2681 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_flushes
);
2683 cifs_dbg(VFS
, "Send error in Flush = %d\n", rc
);
2689 CIFSSMBRename(const unsigned int xid
, struct cifs_tcon
*tcon
,
2690 const char *from_name
, const char *to_name
,
2691 struct cifs_sb_info
*cifs_sb
)
2694 RENAME_REQ
*pSMB
= NULL
;
2695 RENAME_RSP
*pSMBr
= NULL
;
2697 int name_len
, name_len2
;
2699 int remap
= cifs_remap(cifs_sb
);
2701 cifs_dbg(FYI
, "In CIFSSMBRename\n");
2703 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
2708 pSMB
->BufferFormat
= 0x04;
2709 pSMB
->SearchAttributes
=
2710 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2713 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2714 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2715 from_name
, PATH_MAX
,
2716 cifs_sb
->local_nls
, remap
);
2717 name_len
++; /* trailing null */
2719 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2720 /* protocol requires ASCII signature byte on Unicode string */
2721 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2723 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2724 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2726 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2727 name_len2
*= 2; /* convert to bytes */
2729 name_len
= copy_path_name(pSMB
->OldFileName
, from_name
);
2730 name_len2
= copy_path_name(pSMB
->OldFileName
+name_len
+1, to_name
);
2731 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2732 name_len2
++; /* signature byte */
2735 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2736 inc_rfc1001_len(pSMB
, count
);
2737 pSMB
->ByteCount
= cpu_to_le16(count
);
2739 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2740 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2741 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_renames
);
2743 cifs_dbg(FYI
, "Send error in rename = %d\n", rc
);
2745 cifs_buf_release(pSMB
);
2753 int CIFSSMBRenameOpenFile(const unsigned int xid
, struct cifs_tcon
*pTcon
,
2754 int netfid
, const char *target_name
,
2755 const struct nls_table
*nls_codepage
, int remap
)
2757 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2758 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2759 struct set_file_rename
*rename_info
;
2761 char dummy_string
[30];
2763 int bytes_returned
= 0;
2765 __u16 params
, param_offset
, offset
, count
, byte_count
;
2767 cifs_dbg(FYI
, "Rename to File by handle\n");
2768 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
2774 pSMB
->MaxSetupCount
= 0;
2778 pSMB
->Reserved2
= 0;
2779 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2780 offset
= param_offset
+ params
;
2782 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2783 rename_info
= (struct set_file_rename
*) data_offset
;
2784 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2785 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2786 pSMB
->SetupCount
= 1;
2787 pSMB
->Reserved3
= 0;
2788 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2789 byte_count
= 3 /* pad */ + params
;
2790 pSMB
->ParameterCount
= cpu_to_le16(params
);
2791 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2792 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2793 pSMB
->DataOffset
= cpu_to_le16(offset
);
2794 /* construct random name ".cifs_tmp<inodenum><mid>" */
2795 rename_info
->overwrite
= cpu_to_le32(1);
2796 rename_info
->root_fid
= 0;
2797 /* unicode only call */
2798 if (target_name
== NULL
) {
2799 sprintf(dummy_string
, "cifs%x", pSMB
->hdr
.Mid
);
2801 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2802 dummy_string
, 24, nls_codepage
, remap
);
2805 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2806 target_name
, PATH_MAX
, nls_codepage
,
2809 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
2810 count
= 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str
);
2811 byte_count
+= count
;
2812 pSMB
->DataCount
= cpu_to_le16(count
);
2813 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2815 pSMB
->InformationLevel
=
2816 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
2817 pSMB
->Reserved4
= 0;
2818 inc_rfc1001_len(pSMB
, byte_count
);
2819 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2820 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
2821 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2822 cifs_stats_inc(&pTcon
->stats
.cifs_stats
.num_t2renames
);
2824 cifs_dbg(FYI
, "Send error in Rename (by file handle) = %d\n",
2827 cifs_buf_release(pSMB
);
2829 /* Note: On -EAGAIN error only caller can retry on handle based calls
2830 since file handle passed in no longer valid */
2836 CIFSSMBCopy(const unsigned int xid
, struct cifs_tcon
*tcon
,
2837 const char *fromName
, const __u16 target_tid
, const char *toName
,
2838 const int flags
, const struct nls_table
*nls_codepage
, int remap
)
2841 COPY_REQ
*pSMB
= NULL
;
2842 COPY_RSP
*pSMBr
= NULL
;
2844 int name_len
, name_len2
;
2847 cifs_dbg(FYI
, "In CIFSSMBCopy\n");
2849 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
2854 pSMB
->BufferFormat
= 0x04;
2855 pSMB
->Tid2
= target_tid
;
2857 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
2859 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2860 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2861 fromName
, PATH_MAX
, nls_codepage
,
2863 name_len
++; /* trailing null */
2865 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2866 /* protocol requires ASCII signature byte on Unicode string */
2867 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2869 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2870 toName
, PATH_MAX
, nls_codepage
, remap
);
2871 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2872 name_len2
*= 2; /* convert to bytes */
2874 name_len
= copy_path_name(pSMB
->OldFileName
, fromName
);
2875 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2876 name_len2
= copy_path_name(pSMB
->OldFileName
+name_len
+1, toName
);
2877 name_len2
++; /* signature byte */
2880 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2881 inc_rfc1001_len(pSMB
, count
);
2882 pSMB
->ByteCount
= cpu_to_le16(count
);
2884 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2885 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2887 cifs_dbg(FYI
, "Send error in copy = %d with %d files copied\n",
2888 rc
, le16_to_cpu(pSMBr
->CopyCount
));
2890 cifs_buf_release(pSMB
);
2899 CIFSUnixCreateSymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2900 const char *fromName
, const char *toName
,
2901 const struct nls_table
*nls_codepage
, int remap
)
2903 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2904 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2907 int name_len_target
;
2909 int bytes_returned
= 0;
2910 __u16 params
, param_offset
, offset
, byte_count
;
2912 cifs_dbg(FYI
, "In Symlink Unix style\n");
2914 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2919 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2921 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fromName
,
2922 /* find define for this maxpathcomponent */
2923 PATH_MAX
, nls_codepage
, remap
);
2924 name_len
++; /* trailing null */
2928 name_len
= copy_path_name(pSMB
->FileName
, fromName
);
2930 params
= 6 + name_len
;
2931 pSMB
->MaxSetupCount
= 0;
2935 pSMB
->Reserved2
= 0;
2936 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2937 InformationLevel
) - 4;
2938 offset
= param_offset
+ params
;
2940 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2941 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2943 cifsConvertToUTF16((__le16
*) data_offset
, toName
,
2944 /* find define for this maxpathcomponent */
2945 PATH_MAX
, nls_codepage
, remap
);
2946 name_len_target
++; /* trailing null */
2947 name_len_target
*= 2;
2949 name_len_target
= copy_path_name(data_offset
, toName
);
2952 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2953 /* BB find exact max on data count below from sess */
2954 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2955 pSMB
->SetupCount
= 1;
2956 pSMB
->Reserved3
= 0;
2957 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2958 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2959 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2960 pSMB
->ParameterCount
= cpu_to_le16(params
);
2961 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2962 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2963 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2964 pSMB
->DataOffset
= cpu_to_le16(offset
);
2965 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
2966 pSMB
->Reserved4
= 0;
2967 inc_rfc1001_len(pSMB
, byte_count
);
2968 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2969 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2970 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2971 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_symlinks
);
2973 cifs_dbg(FYI
, "Send error in SetPathInfo create symlink = %d\n",
2976 cifs_buf_release(pSMB
);
2979 goto createSymLinkRetry
;
2985 CIFSUnixCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2986 const char *fromName
, const char *toName
,
2987 const struct nls_table
*nls_codepage
, int remap
)
2989 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2990 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2993 int name_len_target
;
2995 int bytes_returned
= 0;
2996 __u16 params
, param_offset
, offset
, byte_count
;
2998 cifs_dbg(FYI
, "In Create Hard link Unix style\n");
2999 createHardLinkRetry
:
3000 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3005 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3006 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->FileName
, toName
,
3007 PATH_MAX
, nls_codepage
, remap
);
3008 name_len
++; /* trailing null */
3012 name_len
= copy_path_name(pSMB
->FileName
, toName
);
3014 params
= 6 + name_len
;
3015 pSMB
->MaxSetupCount
= 0;
3019 pSMB
->Reserved2
= 0;
3020 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3021 InformationLevel
) - 4;
3022 offset
= param_offset
+ params
;
3024 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
3025 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3027 cifsConvertToUTF16((__le16
*) data_offset
, fromName
,
3028 PATH_MAX
, nls_codepage
, remap
);
3029 name_len_target
++; /* trailing null */
3030 name_len_target
*= 2;
3032 name_len_target
= copy_path_name(data_offset
, fromName
);
3035 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3036 /* BB find exact max on data count below from sess*/
3037 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3038 pSMB
->SetupCount
= 1;
3039 pSMB
->Reserved3
= 0;
3040 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3041 byte_count
= 3 /* pad */ + params
+ name_len_target
;
3042 pSMB
->ParameterCount
= cpu_to_le16(params
);
3043 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3044 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
3045 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3046 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3047 pSMB
->DataOffset
= cpu_to_le16(offset
);
3048 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
3049 pSMB
->Reserved4
= 0;
3050 inc_rfc1001_len(pSMB
, byte_count
);
3051 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3052 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3053 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3054 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3056 cifs_dbg(FYI
, "Send error in SetPathInfo (hard link) = %d\n",
3059 cifs_buf_release(pSMB
);
3061 goto createHardLinkRetry
;
3067 CIFSCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3068 const char *from_name
, const char *to_name
,
3069 struct cifs_sb_info
*cifs_sb
)
3072 NT_RENAME_REQ
*pSMB
= NULL
;
3073 RENAME_RSP
*pSMBr
= NULL
;
3075 int name_len
, name_len2
;
3077 int remap
= cifs_remap(cifs_sb
);
3079 cifs_dbg(FYI
, "In CIFSCreateHardLink\n");
3080 winCreateHardLinkRetry
:
3082 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
3087 pSMB
->SearchAttributes
=
3088 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
3090 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
3091 pSMB
->ClusterCount
= 0;
3093 pSMB
->BufferFormat
= 0x04;
3095 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3097 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, from_name
,
3098 PATH_MAX
, cifs_sb
->local_nls
, remap
);
3099 name_len
++; /* trailing null */
3102 /* protocol specifies ASCII buffer format (0x04) for unicode */
3103 pSMB
->OldFileName
[name_len
] = 0x04;
3104 pSMB
->OldFileName
[name_len
+ 1] = 0x00; /* pad */
3106 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
3107 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
3109 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
3110 name_len2
*= 2; /* convert to bytes */
3112 name_len
= copy_path_name(pSMB
->OldFileName
, from_name
);
3113 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
3114 name_len2
= copy_path_name(pSMB
->OldFileName
+name_len
+1, to_name
);
3115 name_len2
++; /* signature byte */
3118 count
= 1 /* string type byte */ + name_len
+ name_len2
;
3119 inc_rfc1001_len(pSMB
, count
);
3120 pSMB
->ByteCount
= cpu_to_le16(count
);
3122 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3123 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3124 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3126 cifs_dbg(FYI
, "Send error in hard link (NT rename) = %d\n", rc
);
3128 cifs_buf_release(pSMB
);
3130 goto winCreateHardLinkRetry
;
3136 CIFSSMBUnixQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3137 const unsigned char *searchName
, char **symlinkinfo
,
3138 const struct nls_table
*nls_codepage
, int remap
)
3140 /* SMB_QUERY_FILE_UNIX_LINK */
3141 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3142 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3146 __u16 params
, byte_count
;
3149 cifs_dbg(FYI
, "In QPathSymLinkInfo (Unix) for path %s\n", searchName
);
3152 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3157 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3159 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3160 searchName
, PATH_MAX
, nls_codepage
,
3162 name_len
++; /* trailing null */
3165 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
3168 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3169 pSMB
->TotalDataCount
= 0;
3170 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3171 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3172 pSMB
->MaxSetupCount
= 0;
3176 pSMB
->Reserved2
= 0;
3177 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3178 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3179 pSMB
->DataCount
= 0;
3180 pSMB
->DataOffset
= 0;
3181 pSMB
->SetupCount
= 1;
3182 pSMB
->Reserved3
= 0;
3183 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3184 byte_count
= params
+ 1 /* pad */ ;
3185 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3186 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3187 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
3188 pSMB
->Reserved4
= 0;
3189 inc_rfc1001_len(pSMB
, byte_count
);
3190 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3192 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3193 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3195 cifs_dbg(FYI
, "Send error in QuerySymLinkInfo = %d\n", rc
);
3197 /* decode response */
3199 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3200 /* BB also check enough total bytes returned */
3201 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3205 u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3207 data_start
= ((char *) &pSMBr
->hdr
.Protocol
) +
3208 le16_to_cpu(pSMBr
->t2
.DataOffset
);
3210 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3215 /* BB FIXME investigate remapping reserved chars here */
3216 *symlinkinfo
= cifs_strndup_from_utf16(data_start
,
3217 count
, is_unicode
, nls_codepage
);
3222 cifs_buf_release(pSMB
);
3224 goto querySymLinkRetry
;
3229 * Recent Windows versions now create symlinks more frequently
3230 * and they use the "reparse point" mechanism below. We can of course
3231 * do symlinks nicely to Samba and other servers which support the
3232 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3233 * "MF" symlinks optionally, but for recent Windows we really need to
3234 * reenable the code below and fix the cifs_symlink callers to handle this.
3235 * In the interim this code has been moved to its own config option so
3236 * it is not compiled in by default until callers fixed up and more tested.
3239 CIFSSMBQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3240 __u16 fid
, char **symlinkinfo
,
3241 const struct nls_table
*nls_codepage
)
3245 struct smb_com_transaction_ioctl_req
*pSMB
;
3246 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3248 unsigned int sub_len
;
3250 struct reparse_symlink_data
*reparse_buf
;
3251 struct reparse_posix_data
*posix_buf
;
3252 __u32 data_offset
, data_count
;
3255 cifs_dbg(FYI
, "In Windows reparse style QueryLink for fid %u\n", fid
);
3256 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3261 pSMB
->TotalParameterCount
= 0 ;
3262 pSMB
->TotalDataCount
= 0;
3263 pSMB
->MaxParameterCount
= cpu_to_le32(2);
3264 /* BB find exact data count max from sess structure BB */
3265 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3266 pSMB
->MaxSetupCount
= 4;
3268 pSMB
->ParameterOffset
= 0;
3269 pSMB
->DataCount
= 0;
3270 pSMB
->DataOffset
= 0;
3271 pSMB
->SetupCount
= 4;
3272 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3273 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3274 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
3275 pSMB
->IsFsctl
= 1; /* FSCTL */
3276 pSMB
->IsRootFlag
= 0;
3277 pSMB
->Fid
= fid
; /* file handle always le */
3278 pSMB
->ByteCount
= 0;
3280 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3281 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3283 cifs_dbg(FYI
, "Send error in QueryReparseLinkInfo = %d\n", rc
);
3287 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3288 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3289 if (get_bcc(&pSMBr
->hdr
) < 2 || data_offset
> 512) {
3290 /* BB also check enough total bytes returned */
3291 rc
= -EIO
; /* bad smb */
3294 if (!data_count
|| (data_count
> 2048)) {
3296 cifs_dbg(FYI
, "Invalid return data count on get reparse info ioctl\n");
3299 end_of_smb
= 2 + get_bcc(&pSMBr
->hdr
) + (char *)&pSMBr
->ByteCount
;
3300 reparse_buf
= (struct reparse_symlink_data
*)
3301 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
3302 if ((char *)reparse_buf
>= end_of_smb
) {
3306 if (reparse_buf
->ReparseTag
== cpu_to_le32(IO_REPARSE_TAG_NFS
)) {
3307 cifs_dbg(FYI
, "NFS style reparse tag\n");
3308 posix_buf
= (struct reparse_posix_data
*)reparse_buf
;
3310 if (posix_buf
->InodeType
!= cpu_to_le64(NFS_SPECFILE_LNK
)) {
3311 cifs_dbg(FYI
, "unsupported file type 0x%llx\n",
3312 le64_to_cpu(posix_buf
->InodeType
));
3317 sub_len
= le16_to_cpu(reparse_buf
->ReparseDataLength
);
3318 if (posix_buf
->PathBuffer
+ sub_len
> end_of_smb
) {
3319 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3323 *symlinkinfo
= cifs_strndup_from_utf16(posix_buf
->PathBuffer
,
3324 sub_len
, is_unicode
, nls_codepage
);
3326 } else if (reparse_buf
->ReparseTag
!=
3327 cpu_to_le32(IO_REPARSE_TAG_SYMLINK
)) {
3332 /* Reparse tag is NTFS symlink */
3333 sub_start
= le16_to_cpu(reparse_buf
->SubstituteNameOffset
) +
3334 reparse_buf
->PathBuffer
;
3335 sub_len
= le16_to_cpu(reparse_buf
->SubstituteNameLength
);
3336 if (sub_start
+ sub_len
> end_of_smb
) {
3337 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3341 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3346 /* BB FIXME investigate remapping reserved chars here */
3347 *symlinkinfo
= cifs_strndup_from_utf16(sub_start
, sub_len
, is_unicode
,
3352 cifs_buf_release(pSMB
);
3355 * Note: On -EAGAIN error only caller can retry on handle based calls
3356 * since file handle passed in no longer valid.
3362 CIFSSMB_set_compression(const unsigned int xid
, struct cifs_tcon
*tcon
,
3367 struct smb_com_transaction_compr_ioctl_req
*pSMB
;
3368 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3370 cifs_dbg(FYI
, "Set compression for %u\n", fid
);
3371 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3376 pSMB
->compression_state
= cpu_to_le16(COMPRESSION_FORMAT_DEFAULT
);
3378 pSMB
->TotalParameterCount
= 0;
3379 pSMB
->TotalDataCount
= cpu_to_le32(2);
3380 pSMB
->MaxParameterCount
= 0;
3381 pSMB
->MaxDataCount
= 0;
3382 pSMB
->MaxSetupCount
= 4;
3384 pSMB
->ParameterOffset
= 0;
3385 pSMB
->DataCount
= cpu_to_le32(2);
3387 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req
,
3388 compression_state
) - 4); /* 84 */
3389 pSMB
->SetupCount
= 4;
3390 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3391 pSMB
->ParameterCount
= 0;
3392 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_SET_COMPRESSION
);
3393 pSMB
->IsFsctl
= 1; /* FSCTL */
3394 pSMB
->IsRootFlag
= 0;
3395 pSMB
->Fid
= fid
; /* file handle always le */
3396 /* 3 byte pad, followed by 2 byte compress state */
3397 pSMB
->ByteCount
= cpu_to_le16(5);
3398 inc_rfc1001_len(pSMB
, 5);
3400 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3401 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3403 cifs_dbg(FYI
, "Send error in SetCompression = %d\n", rc
);
3405 cifs_buf_release(pSMB
);
3408 * Note: On -EAGAIN error only caller can retry on handle based calls
3409 * since file handle passed in no longer valid.
3415 #ifdef CONFIG_CIFS_POSIX
3417 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3418 static void cifs_convert_ace(struct posix_acl_xattr_entry
*ace
,
3419 struct cifs_posix_ace
*cifs_ace
)
3421 /* u8 cifs fields do not need le conversion */
3422 ace
->e_perm
= cpu_to_le16(cifs_ace
->cifs_e_perm
);
3423 ace
->e_tag
= cpu_to_le16(cifs_ace
->cifs_e_tag
);
3424 ace
->e_id
= cpu_to_le32(le64_to_cpu(cifs_ace
->cifs_uid
));
3426 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3427 ace->e_perm, ace->e_tag, ace->e_id);
3433 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3434 static int cifs_copy_posix_acl(char *trgt
, char *src
, const int buflen
,
3435 const int acl_type
, const int size_of_data_area
)
3440 struct cifs_posix_ace
*pACE
;
3441 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)src
;
3442 struct posix_acl_xattr_header
*local_acl
= (void *)trgt
;
3444 if (le16_to_cpu(cifs_acl
->version
) != CIFS_ACL_VERSION
)
3447 if (acl_type
== ACL_TYPE_ACCESS
) {
3448 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3449 pACE
= &cifs_acl
->ace_array
[0];
3450 size
= sizeof(struct cifs_posix_acl
);
3451 size
+= sizeof(struct cifs_posix_ace
) * count
;
3452 /* check if we would go beyond end of SMB */
3453 if (size_of_data_area
< size
) {
3454 cifs_dbg(FYI
, "bad CIFS POSIX ACL size %d vs. %d\n",
3455 size_of_data_area
, size
);
3458 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3459 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3460 size
= sizeof(struct cifs_posix_acl
);
3461 size
+= sizeof(struct cifs_posix_ace
) * count
;
3462 /* skip past access ACEs to get to default ACEs */
3463 pACE
= &cifs_acl
->ace_array
[count
];
3464 count
= le16_to_cpu(cifs_acl
->default_entry_count
);
3465 size
+= sizeof(struct cifs_posix_ace
) * count
;
3466 /* check if we would go beyond end of SMB */
3467 if (size_of_data_area
< size
)
3474 size
= posix_acl_xattr_size(count
);
3475 if ((buflen
== 0) || (local_acl
== NULL
)) {
3476 /* used to query ACL EA size */
3477 } else if (size
> buflen
) {
3479 } else /* buffer big enough */ {
3480 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3482 local_acl
->a_version
= cpu_to_le32(POSIX_ACL_XATTR_VERSION
);
3483 for (i
= 0; i
< count
; i
++) {
3484 cifs_convert_ace(&ace
[i
], pACE
);
3491 static void convert_ace_to_cifs_ace(struct cifs_posix_ace
*cifs_ace
,
3492 const struct posix_acl_xattr_entry
*local_ace
)
3494 cifs_ace
->cifs_e_perm
= le16_to_cpu(local_ace
->e_perm
);
3495 cifs_ace
->cifs_e_tag
= le16_to_cpu(local_ace
->e_tag
);
3496 /* BB is there a better way to handle the large uid? */
3497 if (local_ace
->e_id
== cpu_to_le32(-1)) {
3498 /* Probably no need to le convert -1 on any arch but can not hurt */
3499 cifs_ace
->cifs_uid
= cpu_to_le64(-1);
3501 cifs_ace
->cifs_uid
= cpu_to_le64(le32_to_cpu(local_ace
->e_id
));
3503 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3504 ace->e_perm, ace->e_tag, ace->e_id);
3508 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3509 static __u16
ACL_to_cifs_posix(char *parm_data
, const char *pACL
,
3510 const int buflen
, const int acl_type
)
3513 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)parm_data
;
3514 struct posix_acl_xattr_header
*local_acl
= (void *)pACL
;
3515 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3519 if ((buflen
== 0) || (pACL
== NULL
) || (cifs_acl
== NULL
))
3522 count
= posix_acl_xattr_count((size_t)buflen
);
3523 cifs_dbg(FYI
, "setting acl with %d entries from buf of length %d and version of %d\n",
3524 count
, buflen
, le32_to_cpu(local_acl
->a_version
));
3525 if (le32_to_cpu(local_acl
->a_version
) != 2) {
3526 cifs_dbg(FYI
, "unknown POSIX ACL version %d\n",
3527 le32_to_cpu(local_acl
->a_version
));
3530 cifs_acl
->version
= cpu_to_le16(1);
3531 if (acl_type
== ACL_TYPE_ACCESS
) {
3532 cifs_acl
->access_entry_count
= cpu_to_le16(count
);
3533 cifs_acl
->default_entry_count
= cpu_to_le16(0xFFFF);
3534 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3535 cifs_acl
->default_entry_count
= cpu_to_le16(count
);
3536 cifs_acl
->access_entry_count
= cpu_to_le16(0xFFFF);
3538 cifs_dbg(FYI
, "unknown ACL type %d\n", acl_type
);
3541 for (i
= 0; i
< count
; i
++)
3542 convert_ace_to_cifs_ace(&cifs_acl
->ace_array
[i
], &ace
[i
]);
3544 rc
= (__u16
)(count
* sizeof(struct cifs_posix_ace
));
3545 rc
+= sizeof(struct cifs_posix_acl
);
3546 /* BB add check to make sure ACL does not overflow SMB */
3552 CIFSSMBGetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3553 const unsigned char *searchName
,
3554 char *acl_inf
, const int buflen
, const int acl_type
,
3555 const struct nls_table
*nls_codepage
, int remap
)
3557 /* SMB_QUERY_POSIX_ACL */
3558 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3559 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3563 __u16 params
, byte_count
;
3565 cifs_dbg(FYI
, "In GetPosixACL (Unix) for path %s\n", searchName
);
3568 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3573 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3575 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3576 searchName
, PATH_MAX
, nls_codepage
,
3578 name_len
++; /* trailing null */
3580 pSMB
->FileName
[name_len
] = 0;
3581 pSMB
->FileName
[name_len
+1] = 0;
3583 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
3586 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3587 pSMB
->TotalDataCount
= 0;
3588 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3589 /* BB find exact max data count below from sess structure BB */
3590 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3591 pSMB
->MaxSetupCount
= 0;
3595 pSMB
->Reserved2
= 0;
3596 pSMB
->ParameterOffset
= cpu_to_le16(
3597 offsetof(struct smb_com_transaction2_qpi_req
,
3598 InformationLevel
) - 4);
3599 pSMB
->DataCount
= 0;
3600 pSMB
->DataOffset
= 0;
3601 pSMB
->SetupCount
= 1;
3602 pSMB
->Reserved3
= 0;
3603 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3604 byte_count
= params
+ 1 /* pad */ ;
3605 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3606 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3607 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_ACL
);
3608 pSMB
->Reserved4
= 0;
3609 inc_rfc1001_len(pSMB
, byte_count
);
3610 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3612 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3613 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3614 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3616 cifs_dbg(FYI
, "Send error in Query POSIX ACL = %d\n", rc
);
3618 /* decode response */
3620 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3621 /* BB also check enough total bytes returned */
3622 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3623 rc
= -EIO
; /* bad smb */
3625 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3626 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3627 rc
= cifs_copy_posix_acl(acl_inf
,
3628 (char *)&pSMBr
->hdr
.Protocol
+data_offset
,
3629 buflen
, acl_type
, count
);
3632 cifs_buf_release(pSMB
);
3639 CIFSSMBSetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3640 const unsigned char *fileName
,
3641 const char *local_acl
, const int buflen
,
3643 const struct nls_table
*nls_codepage
, int remap
)
3645 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3646 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3650 int bytes_returned
= 0;
3651 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
3653 cifs_dbg(FYI
, "In SetPosixACL (Unix) for path %s\n", fileName
);
3655 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3659 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3661 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
3662 PATH_MAX
, nls_codepage
, remap
);
3663 name_len
++; /* trailing null */
3666 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
3668 params
= 6 + name_len
;
3669 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3670 /* BB find max SMB size from sess */
3671 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3672 pSMB
->MaxSetupCount
= 0;
3676 pSMB
->Reserved2
= 0;
3677 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3678 InformationLevel
) - 4;
3679 offset
= param_offset
+ params
;
3680 parm_data
= ((char *) &pSMB
->hdr
.Protocol
) + offset
;
3681 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3683 /* convert to on the wire format for POSIX ACL */
3684 data_count
= ACL_to_cifs_posix(parm_data
, local_acl
, buflen
, acl_type
);
3686 if (data_count
== 0) {
3688 goto setACLerrorExit
;
3690 pSMB
->DataOffset
= cpu_to_le16(offset
);
3691 pSMB
->SetupCount
= 1;
3692 pSMB
->Reserved3
= 0;
3693 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3694 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_ACL
);
3695 byte_count
= 3 /* pad */ + params
+ data_count
;
3696 pSMB
->DataCount
= cpu_to_le16(data_count
);
3697 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3698 pSMB
->ParameterCount
= cpu_to_le16(params
);
3699 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3700 pSMB
->Reserved4
= 0;
3701 inc_rfc1001_len(pSMB
, byte_count
);
3702 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3703 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3704 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3706 cifs_dbg(FYI
, "Set POSIX ACL returned %d\n", rc
);
3709 cifs_buf_release(pSMB
);
3715 /* BB fix tabs in this function FIXME BB */
3717 CIFSGetExtAttr(const unsigned int xid
, struct cifs_tcon
*tcon
,
3718 const int netfid
, __u64
*pExtAttrBits
, __u64
*pMask
)
3721 struct smb_t2_qfi_req
*pSMB
= NULL
;
3722 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3724 __u16 params
, byte_count
;
3726 cifs_dbg(FYI
, "In GetExtAttr\n");
3731 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3736 params
= 2 /* level */ + 2 /* fid */;
3737 pSMB
->t2
.TotalDataCount
= 0;
3738 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3739 /* BB find exact max data count below from sess structure BB */
3740 pSMB
->t2
.MaxDataCount
= cpu_to_le16(4000);
3741 pSMB
->t2
.MaxSetupCount
= 0;
3742 pSMB
->t2
.Reserved
= 0;
3744 pSMB
->t2
.Timeout
= 0;
3745 pSMB
->t2
.Reserved2
= 0;
3746 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3748 pSMB
->t2
.DataCount
= 0;
3749 pSMB
->t2
.DataOffset
= 0;
3750 pSMB
->t2
.SetupCount
= 1;
3751 pSMB
->t2
.Reserved3
= 0;
3752 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3753 byte_count
= params
+ 1 /* pad */ ;
3754 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3755 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3756 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_ATTR_FLAGS
);
3759 inc_rfc1001_len(pSMB
, byte_count
);
3760 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3762 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3763 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3765 cifs_dbg(FYI
, "error %d in GetExtAttr\n", rc
);
3767 /* decode response */
3768 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3769 /* BB also check enough total bytes returned */
3770 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3771 /* If rc should we check for EOPNOSUPP and
3772 disable the srvino flag? or in caller? */
3773 rc
= -EIO
; /* bad smb */
3775 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3776 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3777 struct file_chattr_info
*pfinfo
;
3778 /* BB Do we need a cast or hash here ? */
3780 cifs_dbg(FYI
, "Invalid size ret in GetExtAttr\n");
3784 pfinfo
= (struct file_chattr_info
*)
3785 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
3786 *pExtAttrBits
= le64_to_cpu(pfinfo
->mode
);
3787 *pMask
= le64_to_cpu(pfinfo
->mask
);
3791 cifs_buf_release(pSMB
);
3793 goto GetExtAttrRetry
;
3797 #endif /* CONFIG_POSIX */
3800 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3801 * all NT TRANSACTS that we init here have total parm and data under about 400
3802 * bytes (to fit in small cifs buffer size), which is the case so far, it
3803 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3804 * returned setup area) and MaxParameterCount (returned parms size) must be set
3808 smb_init_nttransact(const __u16 sub_command
, const int setup_count
,
3809 const int parm_len
, struct cifs_tcon
*tcon
,
3814 struct smb_com_ntransact_req
*pSMB
;
3816 rc
= small_smb_init(SMB_COM_NT_TRANSACT
, 19 + setup_count
, tcon
,
3820 *ret_buf
= (void *)pSMB
;
3822 pSMB
->TotalParameterCount
= cpu_to_le32(parm_len
);
3823 pSMB
->TotalDataCount
= 0;
3824 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3825 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3826 pSMB
->DataCount
= pSMB
->TotalDataCount
;
3827 temp_offset
= offsetof(struct smb_com_ntransact_req
, Parms
) +
3828 (setup_count
* 2) - 4 /* for rfc1001 length itself */;
3829 pSMB
->ParameterOffset
= cpu_to_le32(temp_offset
);
3830 pSMB
->DataOffset
= cpu_to_le32(temp_offset
+ parm_len
);
3831 pSMB
->SetupCount
= setup_count
; /* no need to le convert byte fields */
3832 pSMB
->SubCommand
= cpu_to_le16(sub_command
);
3837 validate_ntransact(char *buf
, char **ppparm
, char **ppdata
,
3838 __u32
*pparmlen
, __u32
*pdatalen
)
3841 __u32 data_count
, data_offset
, parm_count
, parm_offset
;
3842 struct smb_com_ntransact_rsp
*pSMBr
;
3851 pSMBr
= (struct smb_com_ntransact_rsp
*)buf
;
3853 bcc
= get_bcc(&pSMBr
->hdr
);
3854 end_of_smb
= 2 /* sizeof byte count */ + bcc
+
3855 (char *)&pSMBr
->ByteCount
;
3857 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3858 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3859 parm_offset
= le32_to_cpu(pSMBr
->ParameterOffset
);
3860 parm_count
= le32_to_cpu(pSMBr
->ParameterCount
);
3862 *ppparm
= (char *)&pSMBr
->hdr
.Protocol
+ parm_offset
;
3863 *ppdata
= (char *)&pSMBr
->hdr
.Protocol
+ data_offset
;
3865 /* should we also check that parm and data areas do not overlap? */
3866 if (*ppparm
> end_of_smb
) {
3867 cifs_dbg(FYI
, "parms start after end of smb\n");
3869 } else if (parm_count
+ *ppparm
> end_of_smb
) {
3870 cifs_dbg(FYI
, "parm end after end of smb\n");
3872 } else if (*ppdata
> end_of_smb
) {
3873 cifs_dbg(FYI
, "data starts after end of smb\n");
3875 } else if (data_count
+ *ppdata
> end_of_smb
) {
3876 cifs_dbg(FYI
, "data %p + count %d (%p) past smb end %p start %p\n",
3877 *ppdata
, data_count
, (data_count
+ *ppdata
),
3880 } else if (parm_count
+ data_count
> bcc
) {
3881 cifs_dbg(FYI
, "parm count and data count larger than SMB\n");
3884 *pdatalen
= data_count
;
3885 *pparmlen
= parm_count
;
3889 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3891 CIFSSMBGetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3892 struct cifs_ntsd
**acl_inf
, __u32
*pbuflen
)
3896 QUERY_SEC_DESC_REQ
*pSMB
;
3898 struct kvec rsp_iov
;
3900 cifs_dbg(FYI
, "GetCifsACL\n");
3905 rc
= smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC
, 0,
3906 8 /* parm len */, tcon
, (void **) &pSMB
);
3910 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3911 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3912 pSMB
->MaxSetupCount
= 0;
3913 pSMB
->Fid
= fid
; /* file handle always le */
3914 pSMB
->AclFlags
= cpu_to_le32(CIFS_ACL_OWNER
| CIFS_ACL_GROUP
|
3916 pSMB
->ByteCount
= cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3917 inc_rfc1001_len(pSMB
, 11);
3918 iov
[0].iov_base
= (char *)pSMB
;
3919 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
3921 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovec */, &buf_type
,
3923 cifs_small_buf_release(pSMB
);
3924 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3926 cifs_dbg(FYI
, "Send error in QuerySecDesc = %d\n", rc
);
3927 } else { /* decode response */
3931 struct smb_com_ntransact_rsp
*pSMBr
;
3934 /* validate_nttransact */
3935 rc
= validate_ntransact(rsp_iov
.iov_base
, (char **)&parm
,
3936 &pdata
, &parm_len
, pbuflen
);
3939 pSMBr
= (struct smb_com_ntransact_rsp
*)rsp_iov
.iov_base
;
3941 cifs_dbg(FYI
, "smb %p parm %p data %p\n",
3942 pSMBr
, parm
, *acl_inf
);
3944 if (le32_to_cpu(pSMBr
->ParameterCount
) != 4) {
3945 rc
= -EIO
; /* bad smb */
3950 /* BB check that data area is minimum length and as big as acl_len */
3952 acl_len
= le32_to_cpu(*parm
);
3953 if (acl_len
!= *pbuflen
) {
3954 cifs_dbg(VFS
, "acl length %d does not match %d\n",
3956 if (*pbuflen
> acl_len
)
3960 /* check if buffer is big enough for the acl
3961 header followed by the smallest SID */
3962 if ((*pbuflen
< sizeof(struct cifs_ntsd
) + 8) ||
3963 (*pbuflen
>= 64 * 1024)) {
3964 cifs_dbg(VFS
, "bad acl length %d\n", *pbuflen
);
3968 *acl_inf
= kmemdup(pdata
, *pbuflen
, GFP_KERNEL
);
3969 if (*acl_inf
== NULL
) {
3976 free_rsp_buf(buf_type
, rsp_iov
.iov_base
);
3981 CIFSSMBSetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3982 struct cifs_ntsd
*pntsd
, __u32 acllen
, int aclflag
)
3984 __u16 byte_count
, param_count
, data_count
, param_offset
, data_offset
;
3986 int bytes_returned
= 0;
3987 SET_SEC_DESC_REQ
*pSMB
= NULL
;
3991 rc
= smb_init(SMB_COM_NT_TRANSACT
, 19, tcon
, (void **) &pSMB
, &pSMBr
);
3995 pSMB
->MaxSetupCount
= 0;
3999 param_offset
= offsetof(struct smb_com_transaction_ssec_req
, Fid
) - 4;
4000 data_count
= acllen
;
4001 data_offset
= param_offset
+ param_count
;
4002 byte_count
= 3 /* pad */ + param_count
;
4004 pSMB
->DataCount
= cpu_to_le32(data_count
);
4005 pSMB
->TotalDataCount
= pSMB
->DataCount
;
4006 pSMB
->MaxParameterCount
= cpu_to_le32(4);
4007 pSMB
->MaxDataCount
= cpu_to_le32(16384);
4008 pSMB
->ParameterCount
= cpu_to_le32(param_count
);
4009 pSMB
->ParameterOffset
= cpu_to_le32(param_offset
);
4010 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4011 pSMB
->DataOffset
= cpu_to_le32(data_offset
);
4012 pSMB
->SetupCount
= 0;
4013 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC
);
4014 pSMB
->ByteCount
= cpu_to_le16(byte_count
+data_count
);
4016 pSMB
->Fid
= fid
; /* file handle always le */
4017 pSMB
->Reserved2
= 0;
4018 pSMB
->AclFlags
= cpu_to_le32(aclflag
);
4020 if (pntsd
&& acllen
) {
4021 memcpy((char *)pSMBr
+ offsetof(struct smb_hdr
, Protocol
) +
4022 data_offset
, pntsd
, acllen
);
4023 inc_rfc1001_len(pSMB
, byte_count
+ data_count
);
4025 inc_rfc1001_len(pSMB
, byte_count
);
4027 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4028 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4030 cifs_dbg(FYI
, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4031 bytes_returned
, rc
);
4033 cifs_dbg(FYI
, "Set CIFS ACL returned %d\n", rc
);
4034 cifs_buf_release(pSMB
);
4037 goto setCifsAclRetry
;
4043 /* Legacy Query Path Information call for lookup to old servers such
4046 SMBQueryInformation(const unsigned int xid
, struct cifs_tcon
*tcon
,
4047 const char *search_name
, FILE_ALL_INFO
*data
,
4048 const struct nls_table
*nls_codepage
, int remap
)
4050 QUERY_INFORMATION_REQ
*pSMB
;
4051 QUERY_INFORMATION_RSP
*pSMBr
;
4056 cifs_dbg(FYI
, "In SMBQPath path %s\n", search_name
);
4058 rc
= smb_init(SMB_COM_QUERY_INFORMATION
, 0, tcon
, (void **) &pSMB
,
4063 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4065 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4066 search_name
, PATH_MAX
, nls_codepage
,
4068 name_len
++; /* trailing null */
4071 name_len
= copy_path_name(pSMB
->FileName
, search_name
);
4073 pSMB
->BufferFormat
= 0x04;
4074 name_len
++; /* account for buffer type byte */
4075 inc_rfc1001_len(pSMB
, (__u16
)name_len
);
4076 pSMB
->ByteCount
= cpu_to_le16(name_len
);
4078 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4079 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4081 cifs_dbg(FYI
, "Send error in QueryInfo = %d\n", rc
);
4083 struct timespec64 ts
;
4084 __u32 time
= le32_to_cpu(pSMBr
->last_write_time
);
4086 /* decode response */
4087 /* BB FIXME - add time zone adjustment BB */
4088 memset(data
, 0, sizeof(FILE_ALL_INFO
));
4091 /* decode time fields */
4092 data
->ChangeTime
= cpu_to_le64(cifs_UnixTimeToNT(ts
));
4093 data
->LastWriteTime
= data
->ChangeTime
;
4094 data
->LastAccessTime
= 0;
4095 data
->AllocationSize
=
4096 cpu_to_le64(le32_to_cpu(pSMBr
->size
));
4097 data
->EndOfFile
= data
->AllocationSize
;
4099 cpu_to_le32(le16_to_cpu(pSMBr
->attr
));
4101 rc
= -EIO
; /* bad buffer passed in */
4103 cifs_buf_release(pSMB
);
4112 CIFSSMBQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4113 u16 netfid
, FILE_ALL_INFO
*pFindData
)
4115 struct smb_t2_qfi_req
*pSMB
= NULL
;
4116 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4119 __u16 params
, byte_count
;
4122 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4127 params
= 2 /* level */ + 2 /* fid */;
4128 pSMB
->t2
.TotalDataCount
= 0;
4129 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4130 /* BB find exact max data count below from sess structure BB */
4131 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4132 pSMB
->t2
.MaxSetupCount
= 0;
4133 pSMB
->t2
.Reserved
= 0;
4135 pSMB
->t2
.Timeout
= 0;
4136 pSMB
->t2
.Reserved2
= 0;
4137 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4139 pSMB
->t2
.DataCount
= 0;
4140 pSMB
->t2
.DataOffset
= 0;
4141 pSMB
->t2
.SetupCount
= 1;
4142 pSMB
->t2
.Reserved3
= 0;
4143 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4144 byte_count
= params
+ 1 /* pad */ ;
4145 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4146 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4147 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4150 inc_rfc1001_len(pSMB
, byte_count
);
4151 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4153 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4154 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4156 cifs_dbg(FYI
, "Send error in QFileInfo = %d\n", rc
);
4157 } else { /* decode response */
4158 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4160 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4162 else if (get_bcc(&pSMBr
->hdr
) < 40)
4163 rc
= -EIO
; /* bad smb */
4164 else if (pFindData
) {
4165 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4166 memcpy((char *) pFindData
,
4167 (char *) &pSMBr
->hdr
.Protocol
+
4168 data_offset
, sizeof(FILE_ALL_INFO
));
4172 cifs_buf_release(pSMB
);
4174 goto QFileInfoRetry
;
4180 CIFSSMBQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4181 const char *search_name
, FILE_ALL_INFO
*data
,
4182 int legacy
/* old style infolevel */,
4183 const struct nls_table
*nls_codepage
, int remap
)
4185 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4186 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4187 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4191 __u16 params
, byte_count
;
4193 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4195 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4200 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4202 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, search_name
,
4203 PATH_MAX
, nls_codepage
, remap
);
4204 name_len
++; /* trailing null */
4207 name_len
= copy_path_name(pSMB
->FileName
, search_name
);
4210 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4211 pSMB
->TotalDataCount
= 0;
4212 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4213 /* BB find exact max SMB PDU from sess structure BB */
4214 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4215 pSMB
->MaxSetupCount
= 0;
4219 pSMB
->Reserved2
= 0;
4220 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4221 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4222 pSMB
->DataCount
= 0;
4223 pSMB
->DataOffset
= 0;
4224 pSMB
->SetupCount
= 1;
4225 pSMB
->Reserved3
= 0;
4226 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4227 byte_count
= params
+ 1 /* pad */ ;
4228 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4229 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4231 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
4233 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4234 pSMB
->Reserved4
= 0;
4235 inc_rfc1001_len(pSMB
, byte_count
);
4236 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4238 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4239 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4241 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4242 } else { /* decode response */
4243 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4245 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4247 else if (!legacy
&& get_bcc(&pSMBr
->hdr
) < 40)
4248 rc
= -EIO
; /* bad smb */
4249 else if (legacy
&& get_bcc(&pSMBr
->hdr
) < 24)
4250 rc
= -EIO
; /* 24 or 26 expected but we do not read
4254 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4257 * On legacy responses we do not read the last field,
4258 * EAsize, fortunately since it varies by subdialect and
4259 * also note it differs on Set vs Get, ie two bytes or 4
4260 * bytes depending but we don't care here.
4263 size
= sizeof(FILE_INFO_STANDARD
);
4265 size
= sizeof(FILE_ALL_INFO
);
4266 memcpy((char *) data
, (char *) &pSMBr
->hdr
.Protocol
+
4271 cifs_buf_release(pSMB
);
4273 goto QPathInfoRetry
;
4279 CIFSSMBUnixQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4280 u16 netfid
, FILE_UNIX_BASIC_INFO
*pFindData
)
4282 struct smb_t2_qfi_req
*pSMB
= NULL
;
4283 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4286 __u16 params
, byte_count
;
4289 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4294 params
= 2 /* level */ + 2 /* fid */;
4295 pSMB
->t2
.TotalDataCount
= 0;
4296 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4297 /* BB find exact max data count below from sess structure BB */
4298 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4299 pSMB
->t2
.MaxSetupCount
= 0;
4300 pSMB
->t2
.Reserved
= 0;
4302 pSMB
->t2
.Timeout
= 0;
4303 pSMB
->t2
.Reserved2
= 0;
4304 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4306 pSMB
->t2
.DataCount
= 0;
4307 pSMB
->t2
.DataOffset
= 0;
4308 pSMB
->t2
.SetupCount
= 1;
4309 pSMB
->t2
.Reserved3
= 0;
4310 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4311 byte_count
= params
+ 1 /* pad */ ;
4312 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4313 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4314 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4317 inc_rfc1001_len(pSMB
, byte_count
);
4318 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4320 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4321 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4323 cifs_dbg(FYI
, "Send error in UnixQFileInfo = %d\n", rc
);
4324 } else { /* decode response */
4325 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4327 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4328 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4329 rc
= -EIO
; /* bad smb */
4331 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4332 memcpy((char *) pFindData
,
4333 (char *) &pSMBr
->hdr
.Protocol
+
4335 sizeof(FILE_UNIX_BASIC_INFO
));
4339 cifs_buf_release(pSMB
);
4341 goto UnixQFileInfoRetry
;
4347 CIFSSMBUnixQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4348 const unsigned char *searchName
,
4349 FILE_UNIX_BASIC_INFO
*pFindData
,
4350 const struct nls_table
*nls_codepage
, int remap
)
4352 /* SMB_QUERY_FILE_UNIX_BASIC */
4353 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4354 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4356 int bytes_returned
= 0;
4358 __u16 params
, byte_count
;
4360 cifs_dbg(FYI
, "In QPathInfo (Unix) the path %s\n", searchName
);
4362 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4367 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4369 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4370 PATH_MAX
, nls_codepage
, remap
);
4371 name_len
++; /* trailing null */
4374 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
4377 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4378 pSMB
->TotalDataCount
= 0;
4379 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4380 /* BB find exact max SMB PDU from sess structure BB */
4381 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4382 pSMB
->MaxSetupCount
= 0;
4386 pSMB
->Reserved2
= 0;
4387 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4388 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4389 pSMB
->DataCount
= 0;
4390 pSMB
->DataOffset
= 0;
4391 pSMB
->SetupCount
= 1;
4392 pSMB
->Reserved3
= 0;
4393 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4394 byte_count
= params
+ 1 /* pad */ ;
4395 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4396 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4397 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4398 pSMB
->Reserved4
= 0;
4399 inc_rfc1001_len(pSMB
, byte_count
);
4400 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4402 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4403 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4405 cifs_dbg(FYI
, "Send error in UnixQPathInfo = %d\n", rc
);
4406 } else { /* decode response */
4407 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4409 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4410 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4411 rc
= -EIO
; /* bad smb */
4413 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4414 memcpy((char *) pFindData
,
4415 (char *) &pSMBr
->hdr
.Protocol
+
4417 sizeof(FILE_UNIX_BASIC_INFO
));
4420 cifs_buf_release(pSMB
);
4422 goto UnixQPathInfoRetry
;
4427 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4429 CIFSFindFirst(const unsigned int xid
, struct cifs_tcon
*tcon
,
4430 const char *searchName
, struct cifs_sb_info
*cifs_sb
,
4431 __u16
*pnetfid
, __u16 search_flags
,
4432 struct cifs_search_info
*psrch_inf
, bool msearch
)
4434 /* level 257 SMB_ */
4435 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
4436 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
4437 T2_FFIRST_RSP_PARMS
*parms
;
4439 int bytes_returned
= 0;
4440 int name_len
, remap
;
4441 __u16 params
, byte_count
;
4442 struct nls_table
*nls_codepage
;
4444 cifs_dbg(FYI
, "In FindFirst for %s\n", searchName
);
4447 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4452 nls_codepage
= cifs_sb
->local_nls
;
4453 remap
= cifs_remap(cifs_sb
);
4455 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4457 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4458 PATH_MAX
, nls_codepage
, remap
);
4459 /* We can not add the asterik earlier in case
4460 it got remapped to 0xF03A as if it were part of the
4461 directory name instead of a wildcard */
4464 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4465 pSMB
->FileName
[name_len
+1] = 0;
4466 pSMB
->FileName
[name_len
+2] = '*';
4467 pSMB
->FileName
[name_len
+3] = 0;
4468 name_len
+= 4; /* now the trailing null */
4469 /* null terminate just in case */
4470 pSMB
->FileName
[name_len
] = 0;
4471 pSMB
->FileName
[name_len
+1] = 0;
4475 name_len
= copy_path_name(pSMB
->FileName
, searchName
);
4477 if (WARN_ON_ONCE(name_len
> PATH_MAX
-2))
4478 name_len
= PATH_MAX
-2;
4479 /* overwrite nul byte */
4480 pSMB
->FileName
[name_len
-1] = CIFS_DIR_SEP(cifs_sb
);
4481 pSMB
->FileName
[name_len
] = '*';
4482 pSMB
->FileName
[name_len
+1] = 0;
4487 params
= 12 + name_len
/* includes null */ ;
4488 pSMB
->TotalDataCount
= 0; /* no EAs */
4489 pSMB
->MaxParameterCount
= cpu_to_le16(10);
4490 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4491 pSMB
->MaxSetupCount
= 0;
4495 pSMB
->Reserved2
= 0;
4496 byte_count
= params
+ 1 /* pad */ ;
4497 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4498 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4499 pSMB
->ParameterOffset
= cpu_to_le16(
4500 offsetof(struct smb_com_transaction2_ffirst_req
, SearchAttributes
)
4502 pSMB
->DataCount
= 0;
4503 pSMB
->DataOffset
= 0;
4504 pSMB
->SetupCount
= 1; /* one byte, no need to make endian neutral */
4505 pSMB
->Reserved3
= 0;
4506 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
4507 pSMB
->SearchAttributes
=
4508 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
4510 pSMB
->SearchCount
= cpu_to_le16(CIFSMaxBufSize
/sizeof(FILE_UNIX_INFO
));
4511 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4512 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4514 /* BB what should we set StorageType to? Does it matter? BB */
4515 pSMB
->SearchStorageType
= 0;
4516 inc_rfc1001_len(pSMB
, byte_count
);
4517 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4519 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4520 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4521 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_ffirst
);
4523 if (rc
) {/* BB add logic to retry regular search if Unix search
4524 rejected unexpectedly by server */
4525 /* BB Add code to handle unsupported level rc */
4526 cifs_dbg(FYI
, "Error in FindFirst = %d\n", rc
);
4528 cifs_buf_release(pSMB
);
4530 /* BB eventually could optimize out free and realloc of buf */
4533 goto findFirstRetry
;
4534 } else { /* decode response */
4535 /* BB remember to free buffer if error BB */
4536 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4540 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4541 psrch_inf
->unicode
= true;
4543 psrch_inf
->unicode
= false;
4545 psrch_inf
->ntwrk_buf_start
= (char *)pSMBr
;
4546 psrch_inf
->smallBuf
= false;
4547 psrch_inf
->srch_entries_start
=
4548 (char *) &pSMBr
->hdr
.Protocol
+
4549 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4550 parms
= (T2_FFIRST_RSP_PARMS
*)((char *) &pSMBr
->hdr
.Protocol
+
4551 le16_to_cpu(pSMBr
->t2
.ParameterOffset
));
4553 if (parms
->EndofSearch
)
4554 psrch_inf
->endOfSearch
= true;
4556 psrch_inf
->endOfSearch
= false;
4558 psrch_inf
->entries_in_buffer
=
4559 le16_to_cpu(parms
->SearchCount
);
4560 psrch_inf
->index_of_last_entry
= 2 /* skip . and .. */ +
4561 psrch_inf
->entries_in_buffer
;
4562 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4563 if (CIFSMaxBufSize
< lnoff
) {
4564 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4565 psrch_inf
->last_entry
= NULL
;
4569 psrch_inf
->last_entry
= psrch_inf
->srch_entries_start
+
4573 *pnetfid
= parms
->SearchHandle
;
4575 cifs_buf_release(pSMB
);
4582 int CIFSFindNext(const unsigned int xid
, struct cifs_tcon
*tcon
,
4583 __u16 searchHandle
, __u16 search_flags
,
4584 struct cifs_search_info
*psrch_inf
)
4586 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
4587 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
4588 T2_FNEXT_RSP_PARMS
*parms
;
4589 char *response_data
;
4592 unsigned int name_len
;
4593 __u16 params
, byte_count
;
4595 cifs_dbg(FYI
, "In FindNext\n");
4597 if (psrch_inf
->endOfSearch
)
4600 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4605 params
= 14; /* includes 2 bytes of null string, converted to LE below*/
4607 pSMB
->TotalDataCount
= 0; /* no EAs */
4608 pSMB
->MaxParameterCount
= cpu_to_le16(8);
4609 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4610 pSMB
->MaxSetupCount
= 0;
4614 pSMB
->Reserved2
= 0;
4615 pSMB
->ParameterOffset
= cpu_to_le16(
4616 offsetof(struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
4617 pSMB
->DataCount
= 0;
4618 pSMB
->DataOffset
= 0;
4619 pSMB
->SetupCount
= 1;
4620 pSMB
->Reserved3
= 0;
4621 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
4622 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
4624 cpu_to_le16(CIFSMaxBufSize
/ sizeof(FILE_UNIX_INFO
));
4625 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4626 pSMB
->ResumeKey
= psrch_inf
->resume_key
;
4627 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4629 name_len
= psrch_inf
->resume_name_len
;
4631 if (name_len
< PATH_MAX
) {
4632 memcpy(pSMB
->ResumeFileName
, psrch_inf
->presume_name
, name_len
);
4633 byte_count
+= name_len
;
4634 /* 14 byte parm len above enough for 2 byte null terminator */
4635 pSMB
->ResumeFileName
[name_len
] = 0;
4636 pSMB
->ResumeFileName
[name_len
+1] = 0;
4639 goto FNext2_err_exit
;
4641 byte_count
= params
+ 1 /* pad */ ;
4642 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4643 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4644 inc_rfc1001_len(pSMB
, byte_count
);
4645 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4647 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4648 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4649 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fnext
);
4652 psrch_inf
->endOfSearch
= true;
4653 cifs_buf_release(pSMB
);
4654 rc
= 0; /* search probably was closed at end of search*/
4656 cifs_dbg(FYI
, "FindNext returned = %d\n", rc
);
4657 } else { /* decode response */
4658 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4663 /* BB fixme add lock for file (srch_info) struct here */
4664 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4665 psrch_inf
->unicode
= true;
4667 psrch_inf
->unicode
= false;
4668 response_data
= (char *) &pSMBr
->hdr
.Protocol
+
4669 le16_to_cpu(pSMBr
->t2
.ParameterOffset
);
4670 parms
= (T2_FNEXT_RSP_PARMS
*)response_data
;
4671 response_data
= (char *)&pSMBr
->hdr
.Protocol
+
4672 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4673 if (psrch_inf
->smallBuf
)
4674 cifs_small_buf_release(
4675 psrch_inf
->ntwrk_buf_start
);
4677 cifs_buf_release(psrch_inf
->ntwrk_buf_start
);
4678 psrch_inf
->srch_entries_start
= response_data
;
4679 psrch_inf
->ntwrk_buf_start
= (char *)pSMB
;
4680 psrch_inf
->smallBuf
= false;
4681 if (parms
->EndofSearch
)
4682 psrch_inf
->endOfSearch
= true;
4684 psrch_inf
->endOfSearch
= false;
4685 psrch_inf
->entries_in_buffer
=
4686 le16_to_cpu(parms
->SearchCount
);
4687 psrch_inf
->index_of_last_entry
+=
4688 psrch_inf
->entries_in_buffer
;
4689 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4690 if (CIFSMaxBufSize
< lnoff
) {
4691 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4692 psrch_inf
->last_entry
= NULL
;
4695 psrch_inf
->last_entry
=
4696 psrch_inf
->srch_entries_start
+ lnoff
;
4698 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4699 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4701 /* BB fixme add unlock here */
4706 /* BB On error, should we leave previous search buf (and count and
4707 last entry fields) intact or free the previous one? */
4709 /* Note: On -EAGAIN error only caller can retry on handle based calls
4710 since file handle passed in no longer valid */
4713 cifs_buf_release(pSMB
);
4718 CIFSFindClose(const unsigned int xid
, struct cifs_tcon
*tcon
,
4719 const __u16 searchHandle
)
4722 FINDCLOSE_REQ
*pSMB
= NULL
;
4724 cifs_dbg(FYI
, "In CIFSSMBFindClose\n");
4725 rc
= small_smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **)&pSMB
);
4727 /* no sense returning error if session restarted
4728 as file handle has been closed */
4734 pSMB
->FileID
= searchHandle
;
4735 pSMB
->ByteCount
= 0;
4736 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
4737 cifs_small_buf_release(pSMB
);
4739 cifs_dbg(VFS
, "Send error in FindClose = %d\n", rc
);
4741 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fclose
);
4743 /* Since session is dead, search handle closed on server already */
4751 CIFSGetSrvInodeNumber(const unsigned int xid
, struct cifs_tcon
*tcon
,
4752 const char *search_name
, __u64
*inode_number
,
4753 const struct nls_table
*nls_codepage
, int remap
)
4756 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4757 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4758 int name_len
, bytes_returned
;
4759 __u16 params
, byte_count
;
4761 cifs_dbg(FYI
, "In GetSrvInodeNum for %s\n", search_name
);
4765 GetInodeNumberRetry
:
4766 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4771 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4773 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4774 search_name
, PATH_MAX
, nls_codepage
,
4776 name_len
++; /* trailing null */
4779 name_len
= copy_path_name(pSMB
->FileName
, search_name
);
4782 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
4783 pSMB
->TotalDataCount
= 0;
4784 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4785 /* BB find exact max data count below from sess structure BB */
4786 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4787 pSMB
->MaxSetupCount
= 0;
4791 pSMB
->Reserved2
= 0;
4792 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4793 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4794 pSMB
->DataCount
= 0;
4795 pSMB
->DataOffset
= 0;
4796 pSMB
->SetupCount
= 1;
4797 pSMB
->Reserved3
= 0;
4798 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4799 byte_count
= params
+ 1 /* pad */ ;
4800 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4801 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4802 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO
);
4803 pSMB
->Reserved4
= 0;
4804 inc_rfc1001_len(pSMB
, byte_count
);
4805 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4807 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4808 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4810 cifs_dbg(FYI
, "error %d in QueryInternalInfo\n", rc
);
4812 /* decode response */
4813 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4814 /* BB also check enough total bytes returned */
4815 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
4816 /* If rc should we check for EOPNOSUPP and
4817 disable the srvino flag? or in caller? */
4818 rc
= -EIO
; /* bad smb */
4820 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4821 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
4822 struct file_internal_info
*pfinfo
;
4823 /* BB Do we need a cast or hash here ? */
4825 cifs_dbg(FYI
, "Invalid size ret in QryIntrnlInf\n");
4827 goto GetInodeNumOut
;
4829 pfinfo
= (struct file_internal_info
*)
4830 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
4831 *inode_number
= le64_to_cpu(pfinfo
->UniqueId
);
4835 cifs_buf_release(pSMB
);
4837 goto GetInodeNumberRetry
;
4842 CIFSGetDFSRefer(const unsigned int xid
, struct cifs_ses
*ses
,
4843 const char *search_name
, struct dfs_info3_param
**target_nodes
,
4844 unsigned int *num_of_nodes
,
4845 const struct nls_table
*nls_codepage
, int remap
)
4847 /* TRANS2_GET_DFS_REFERRAL */
4848 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
4849 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
4853 __u16 params
, byte_count
;
4855 *target_nodes
= NULL
;
4857 cifs_dbg(FYI
, "In GetDFSRefer the path %s\n", search_name
);
4858 if (ses
== NULL
|| ses
->tcon_ipc
== NULL
)
4862 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, ses
->tcon_ipc
, (void **) &pSMB
,
4867 /* server pointer checked in called function,
4868 but should never be null here anyway */
4869 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
4870 pSMB
->hdr
.Tid
= ses
->tcon_ipc
->tid
;
4871 pSMB
->hdr
.Uid
= ses
->Suid
;
4872 if (ses
->capabilities
& CAP_STATUS32
)
4873 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
4874 if (ses
->capabilities
& CAP_DFS
)
4875 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
4877 if (ses
->capabilities
& CAP_UNICODE
) {
4878 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
4880 cifsConvertToUTF16((__le16
*) pSMB
->RequestFileName
,
4881 search_name
, PATH_MAX
, nls_codepage
,
4883 name_len
++; /* trailing null */
4885 } else { /* BB improve the check for buffer overruns BB */
4886 name_len
= copy_path_name(pSMB
->RequestFileName
, search_name
);
4889 if (ses
->server
->sign
)
4890 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
4892 pSMB
->hdr
.Uid
= ses
->Suid
;
4894 params
= 2 /* level */ + name_len
/*includes null */ ;
4895 pSMB
->TotalDataCount
= 0;
4896 pSMB
->DataCount
= 0;
4897 pSMB
->DataOffset
= 0;
4898 pSMB
->MaxParameterCount
= 0;
4899 /* BB find exact max SMB PDU from sess structure BB */
4900 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4901 pSMB
->MaxSetupCount
= 0;
4905 pSMB
->Reserved2
= 0;
4906 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4907 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
4908 pSMB
->SetupCount
= 1;
4909 pSMB
->Reserved3
= 0;
4910 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
4911 byte_count
= params
+ 3 /* pad */ ;
4912 pSMB
->ParameterCount
= cpu_to_le16(params
);
4913 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4914 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
4915 inc_rfc1001_len(pSMB
, byte_count
);
4916 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4918 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
4919 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4921 cifs_dbg(FYI
, "Send error in GetDFSRefer = %d\n", rc
);
4924 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4926 /* BB Also check if enough total bytes returned? */
4927 if (rc
|| get_bcc(&pSMBr
->hdr
) < 17) {
4928 rc
= -EIO
; /* bad smb */
4932 cifs_dbg(FYI
, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4933 get_bcc(&pSMBr
->hdr
), le16_to_cpu(pSMBr
->t2
.DataOffset
));
4935 /* parse returned result into more usable form */
4936 rc
= parse_dfs_referrals(&pSMBr
->dfs_data
,
4937 le16_to_cpu(pSMBr
->t2
.DataCount
),
4938 num_of_nodes
, target_nodes
, nls_codepage
,
4940 (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) != 0);
4943 cifs_buf_release(pSMB
);
4951 /* Query File System Info such as free space to old servers such as Win 9x */
4953 SMBOldQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4954 struct kstatfs
*FSData
)
4956 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4957 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4958 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4959 FILE_SYSTEM_ALLOC_INFO
*response_data
;
4961 int bytes_returned
= 0;
4962 __u16 params
, byte_count
;
4964 cifs_dbg(FYI
, "OldQFSInfo\n");
4966 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4971 params
= 2; /* level */
4972 pSMB
->TotalDataCount
= 0;
4973 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4974 pSMB
->MaxDataCount
= cpu_to_le16(1000);
4975 pSMB
->MaxSetupCount
= 0;
4979 pSMB
->Reserved2
= 0;
4980 byte_count
= params
+ 1 /* pad */ ;
4981 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4982 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4983 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4984 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
4985 pSMB
->DataCount
= 0;
4986 pSMB
->DataOffset
= 0;
4987 pSMB
->SetupCount
= 1;
4988 pSMB
->Reserved3
= 0;
4989 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
4990 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_ALLOCATION
);
4991 inc_rfc1001_len(pSMB
, byte_count
);
4992 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4994 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4995 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4997 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
4998 } else { /* decode response */
4999 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5001 if (rc
|| get_bcc(&pSMBr
->hdr
) < 18)
5002 rc
= -EIO
; /* bad smb */
5004 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5005 cifs_dbg(FYI
, "qfsinf resp BCC: %d Offset %d\n",
5006 get_bcc(&pSMBr
->hdr
), data_offset
);
5008 response_data
= (FILE_SYSTEM_ALLOC_INFO
*)
5009 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
5011 le16_to_cpu(response_data
->BytesPerSector
) *
5012 le32_to_cpu(response_data
->
5013 SectorsPerAllocationUnit
);
5015 * much prefer larger but if server doesn't report
5016 * a valid size than 4K is a reasonable minimum
5018 if (FSData
->f_bsize
< 512)
5019 FSData
->f_bsize
= 4096;
5022 le32_to_cpu(response_data
->TotalAllocationUnits
);
5023 FSData
->f_bfree
= FSData
->f_bavail
=
5024 le32_to_cpu(response_data
->FreeAllocationUnits
);
5025 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5026 (unsigned long long)FSData
->f_blocks
,
5027 (unsigned long long)FSData
->f_bfree
,
5031 cifs_buf_release(pSMB
);
5034 goto oldQFSInfoRetry
;
5040 CIFSSMBQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5041 struct kstatfs
*FSData
)
5043 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5044 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5045 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5046 FILE_SYSTEM_INFO
*response_data
;
5048 int bytes_returned
= 0;
5049 __u16 params
, byte_count
;
5051 cifs_dbg(FYI
, "In QFSInfo\n");
5053 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5058 params
= 2; /* level */
5059 pSMB
->TotalDataCount
= 0;
5060 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5061 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5062 pSMB
->MaxSetupCount
= 0;
5066 pSMB
->Reserved2
= 0;
5067 byte_count
= params
+ 1 /* pad */ ;
5068 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5069 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5070 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5071 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5072 pSMB
->DataCount
= 0;
5073 pSMB
->DataOffset
= 0;
5074 pSMB
->SetupCount
= 1;
5075 pSMB
->Reserved3
= 0;
5076 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5077 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
5078 inc_rfc1001_len(pSMB
, byte_count
);
5079 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5081 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5082 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5084 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5085 } else { /* decode response */
5086 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5088 if (rc
|| get_bcc(&pSMBr
->hdr
) < 24)
5089 rc
= -EIO
; /* bad smb */
5091 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5095 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5098 le32_to_cpu(response_data
->BytesPerSector
) *
5099 le32_to_cpu(response_data
->
5100 SectorsPerAllocationUnit
);
5102 * much prefer larger but if server doesn't report
5103 * a valid size than 4K is a reasonable minimum
5105 if (FSData
->f_bsize
< 512)
5106 FSData
->f_bsize
= 4096;
5109 le64_to_cpu(response_data
->TotalAllocationUnits
);
5110 FSData
->f_bfree
= FSData
->f_bavail
=
5111 le64_to_cpu(response_data
->FreeAllocationUnits
);
5112 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5113 (unsigned long long)FSData
->f_blocks
,
5114 (unsigned long long)FSData
->f_bfree
,
5118 cifs_buf_release(pSMB
);
5127 CIFSSMBQFSAttributeInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5129 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5130 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5131 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5132 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
5134 int bytes_returned
= 0;
5135 __u16 params
, byte_count
;
5137 cifs_dbg(FYI
, "In QFSAttributeInfo\n");
5139 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5144 params
= 2; /* level */
5145 pSMB
->TotalDataCount
= 0;
5146 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5147 /* BB find exact max SMB PDU from sess structure BB */
5148 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5149 pSMB
->MaxSetupCount
= 0;
5153 pSMB
->Reserved2
= 0;
5154 byte_count
= params
+ 1 /* pad */ ;
5155 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5156 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5157 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5158 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5159 pSMB
->DataCount
= 0;
5160 pSMB
->DataOffset
= 0;
5161 pSMB
->SetupCount
= 1;
5162 pSMB
->Reserved3
= 0;
5163 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5164 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
5165 inc_rfc1001_len(pSMB
, byte_count
);
5166 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5168 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5169 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5171 cifs_dbg(VFS
, "Send error in QFSAttributeInfo = %d\n", rc
);
5172 } else { /* decode response */
5173 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5175 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5176 /* BB also check if enough bytes returned */
5177 rc
= -EIO
; /* bad smb */
5179 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5181 (FILE_SYSTEM_ATTRIBUTE_INFO
5182 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5184 memcpy(&tcon
->fsAttrInfo
, response_data
,
5185 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO
));
5188 cifs_buf_release(pSMB
);
5191 goto QFSAttributeRetry
;
5197 CIFSSMBQFSDeviceInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5199 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5200 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5201 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5202 FILE_SYSTEM_DEVICE_INFO
*response_data
;
5204 int bytes_returned
= 0;
5205 __u16 params
, byte_count
;
5207 cifs_dbg(FYI
, "In QFSDeviceInfo\n");
5209 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5214 params
= 2; /* level */
5215 pSMB
->TotalDataCount
= 0;
5216 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5217 /* BB find exact max SMB PDU from sess structure BB */
5218 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5219 pSMB
->MaxSetupCount
= 0;
5223 pSMB
->Reserved2
= 0;
5224 byte_count
= params
+ 1 /* pad */ ;
5225 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5226 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5227 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5228 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5230 pSMB
->DataCount
= 0;
5231 pSMB
->DataOffset
= 0;
5232 pSMB
->SetupCount
= 1;
5233 pSMB
->Reserved3
= 0;
5234 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5235 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
5236 inc_rfc1001_len(pSMB
, byte_count
);
5237 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5239 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5240 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5242 cifs_dbg(FYI
, "Send error in QFSDeviceInfo = %d\n", rc
);
5243 } else { /* decode response */
5244 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5246 if (rc
|| get_bcc(&pSMBr
->hdr
) <
5247 sizeof(FILE_SYSTEM_DEVICE_INFO
))
5248 rc
= -EIO
; /* bad smb */
5250 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5252 (FILE_SYSTEM_DEVICE_INFO
*)
5253 (((char *) &pSMBr
->hdr
.Protocol
) +
5255 memcpy(&tcon
->fsDevInfo
, response_data
,
5256 sizeof(FILE_SYSTEM_DEVICE_INFO
));
5259 cifs_buf_release(pSMB
);
5262 goto QFSDeviceRetry
;
5268 CIFSSMBQFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5270 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5271 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5272 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5273 FILE_SYSTEM_UNIX_INFO
*response_data
;
5275 int bytes_returned
= 0;
5276 __u16 params
, byte_count
;
5278 cifs_dbg(FYI
, "In QFSUnixInfo\n");
5280 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5281 (void **) &pSMB
, (void **) &pSMBr
);
5285 params
= 2; /* level */
5286 pSMB
->TotalDataCount
= 0;
5287 pSMB
->DataCount
= 0;
5288 pSMB
->DataOffset
= 0;
5289 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5290 /* BB find exact max SMB PDU from sess structure BB */
5291 pSMB
->MaxDataCount
= cpu_to_le16(100);
5292 pSMB
->MaxSetupCount
= 0;
5296 pSMB
->Reserved2
= 0;
5297 byte_count
= params
+ 1 /* pad */ ;
5298 pSMB
->ParameterCount
= cpu_to_le16(params
);
5299 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5300 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5301 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5302 pSMB
->SetupCount
= 1;
5303 pSMB
->Reserved3
= 0;
5304 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5305 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
5306 inc_rfc1001_len(pSMB
, byte_count
);
5307 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5309 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5310 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5312 cifs_dbg(VFS
, "Send error in QFSUnixInfo = %d\n", rc
);
5313 } else { /* decode response */
5314 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5316 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5317 rc
= -EIO
; /* bad smb */
5319 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5321 (FILE_SYSTEM_UNIX_INFO
5322 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5324 memcpy(&tcon
->fsUnixInfo
, response_data
,
5325 sizeof(FILE_SYSTEM_UNIX_INFO
));
5328 cifs_buf_release(pSMB
);
5338 CIFSSMBSetFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
, __u64 cap
)
5340 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5341 TRANSACTION2_SETFSI_REQ
*pSMB
= NULL
;
5342 TRANSACTION2_SETFSI_RSP
*pSMBr
= NULL
;
5344 int bytes_returned
= 0;
5345 __u16 params
, param_offset
, offset
, byte_count
;
5347 cifs_dbg(FYI
, "In SETFSUnixInfo\n");
5349 /* BB switch to small buf init to save memory */
5350 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5351 (void **) &pSMB
, (void **) &pSMBr
);
5355 params
= 4; /* 2 bytes zero followed by info level. */
5356 pSMB
->MaxSetupCount
= 0;
5360 pSMB
->Reserved2
= 0;
5361 param_offset
= offsetof(struct smb_com_transaction2_setfsi_req
, FileNum
)
5363 offset
= param_offset
+ params
;
5365 pSMB
->MaxParameterCount
= cpu_to_le16(4);
5366 /* BB find exact max SMB PDU from sess structure BB */
5367 pSMB
->MaxDataCount
= cpu_to_le16(100);
5368 pSMB
->SetupCount
= 1;
5369 pSMB
->Reserved3
= 0;
5370 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FS_INFORMATION
);
5371 byte_count
= 1 /* pad */ + params
+ 12;
5373 pSMB
->DataCount
= cpu_to_le16(12);
5374 pSMB
->ParameterCount
= cpu_to_le16(params
);
5375 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5376 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5377 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5378 pSMB
->DataOffset
= cpu_to_le16(offset
);
5382 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_CIFS_UNIX_INFO
);
5385 pSMB
->ClientUnixMajor
= cpu_to_le16(CIFS_UNIX_MAJOR_VERSION
);
5386 pSMB
->ClientUnixMinor
= cpu_to_le16(CIFS_UNIX_MINOR_VERSION
);
5387 pSMB
->ClientUnixCap
= cpu_to_le64(cap
);
5389 inc_rfc1001_len(pSMB
, byte_count
);
5390 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5392 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5393 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5395 cifs_dbg(VFS
, "Send error in SETFSUnixInfo = %d\n", rc
);
5396 } else { /* decode response */
5397 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5399 rc
= -EIO
; /* bad smb */
5401 cifs_buf_release(pSMB
);
5404 goto SETFSUnixRetry
;
5412 CIFSSMBQFSPosixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5413 struct kstatfs
*FSData
)
5415 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5416 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5417 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5418 FILE_SYSTEM_POSIX_INFO
*response_data
;
5420 int bytes_returned
= 0;
5421 __u16 params
, byte_count
;
5423 cifs_dbg(FYI
, "In QFSPosixInfo\n");
5425 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5430 params
= 2; /* level */
5431 pSMB
->TotalDataCount
= 0;
5432 pSMB
->DataCount
= 0;
5433 pSMB
->DataOffset
= 0;
5434 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5435 /* BB find exact max SMB PDU from sess structure BB */
5436 pSMB
->MaxDataCount
= cpu_to_le16(100);
5437 pSMB
->MaxSetupCount
= 0;
5441 pSMB
->Reserved2
= 0;
5442 byte_count
= params
+ 1 /* pad */ ;
5443 pSMB
->ParameterCount
= cpu_to_le16(params
);
5444 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5445 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5446 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5447 pSMB
->SetupCount
= 1;
5448 pSMB
->Reserved3
= 0;
5449 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5450 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_FS_INFO
);
5451 inc_rfc1001_len(pSMB
, byte_count
);
5452 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5454 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5455 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5457 cifs_dbg(FYI
, "Send error in QFSUnixInfo = %d\n", rc
);
5458 } else { /* decode response */
5459 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5461 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5462 rc
= -EIO
; /* bad smb */
5464 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5466 (FILE_SYSTEM_POSIX_INFO
5467 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5470 le32_to_cpu(response_data
->BlockSize
);
5472 * much prefer larger but if server doesn't report
5473 * a valid size than 4K is a reasonable minimum
5475 if (FSData
->f_bsize
< 512)
5476 FSData
->f_bsize
= 4096;
5479 le64_to_cpu(response_data
->TotalBlocks
);
5481 le64_to_cpu(response_data
->BlocksAvail
);
5482 if (response_data
->UserBlocksAvail
== cpu_to_le64(-1)) {
5483 FSData
->f_bavail
= FSData
->f_bfree
;
5486 le64_to_cpu(response_data
->UserBlocksAvail
);
5488 if (response_data
->TotalFileNodes
!= cpu_to_le64(-1))
5490 le64_to_cpu(response_data
->TotalFileNodes
);
5491 if (response_data
->FreeFileNodes
!= cpu_to_le64(-1))
5493 le64_to_cpu(response_data
->FreeFileNodes
);
5496 cifs_buf_release(pSMB
);
5506 * We can not use write of zero bytes trick to set file size due to need for
5507 * large file support. Also note that this SetPathInfo is preferred to
5508 * SetFileInfo based method in next routine which is only needed to work around
5509 * a sharing violation bugin Samba which this routine can run into.
5512 CIFSSMBSetEOF(const unsigned int xid
, struct cifs_tcon
*tcon
,
5513 const char *file_name
, __u64 size
, struct cifs_sb_info
*cifs_sb
,
5514 bool set_allocation
)
5516 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5517 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5518 struct file_end_of_file_info
*parm_data
;
5521 int bytes_returned
= 0;
5522 int remap
= cifs_remap(cifs_sb
);
5524 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
5526 cifs_dbg(FYI
, "In SetEOF\n");
5528 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5533 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5535 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5536 PATH_MAX
, cifs_sb
->local_nls
, remap
);
5537 name_len
++; /* trailing null */
5540 name_len
= copy_path_name(pSMB
->FileName
, file_name
);
5542 params
= 6 + name_len
;
5543 data_count
= sizeof(struct file_end_of_file_info
);
5544 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5545 pSMB
->MaxDataCount
= cpu_to_le16(4100);
5546 pSMB
->MaxSetupCount
= 0;
5550 pSMB
->Reserved2
= 0;
5551 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5552 InformationLevel
) - 4;
5553 offset
= param_offset
+ params
;
5554 if (set_allocation
) {
5555 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5556 pSMB
->InformationLevel
=
5557 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5559 pSMB
->InformationLevel
=
5560 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5561 } else /* Set File Size */ {
5562 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5563 pSMB
->InformationLevel
=
5564 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5566 pSMB
->InformationLevel
=
5567 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5571 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
5573 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5574 pSMB
->DataOffset
= cpu_to_le16(offset
);
5575 pSMB
->SetupCount
= 1;
5576 pSMB
->Reserved3
= 0;
5577 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5578 byte_count
= 3 /* pad */ + params
+ data_count
;
5579 pSMB
->DataCount
= cpu_to_le16(data_count
);
5580 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5581 pSMB
->ParameterCount
= cpu_to_le16(params
);
5582 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5583 pSMB
->Reserved4
= 0;
5584 inc_rfc1001_len(pSMB
, byte_count
);
5585 parm_data
->FileSize
= cpu_to_le64(size
);
5586 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5587 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5588 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5590 cifs_dbg(FYI
, "SetPathInfo (file size) returned %d\n", rc
);
5592 cifs_buf_release(pSMB
);
5601 CIFSSMBSetFileSize(const unsigned int xid
, struct cifs_tcon
*tcon
,
5602 struct cifsFileInfo
*cfile
, __u64 size
, bool set_allocation
)
5604 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5605 struct file_end_of_file_info
*parm_data
;
5607 __u16 params
, param_offset
, offset
, byte_count
, count
;
5609 cifs_dbg(FYI
, "SetFileSize (via SetFileInfo) %lld\n",
5611 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5616 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)cfile
->pid
);
5617 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(cfile
->pid
>> 16));
5620 pSMB
->MaxSetupCount
= 0;
5624 pSMB
->Reserved2
= 0;
5625 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5626 offset
= param_offset
+ params
;
5628 count
= sizeof(struct file_end_of_file_info
);
5629 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5630 /* BB find exact max SMB PDU from sess structure BB */
5631 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5632 pSMB
->SetupCount
= 1;
5633 pSMB
->Reserved3
= 0;
5634 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5635 byte_count
= 3 /* pad */ + params
+ count
;
5636 pSMB
->DataCount
= cpu_to_le16(count
);
5637 pSMB
->ParameterCount
= cpu_to_le16(params
);
5638 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5639 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5640 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5642 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
)
5644 pSMB
->DataOffset
= cpu_to_le16(offset
);
5645 parm_data
->FileSize
= cpu_to_le64(size
);
5646 pSMB
->Fid
= cfile
->fid
.netfid
;
5647 if (set_allocation
) {
5648 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5649 pSMB
->InformationLevel
=
5650 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5652 pSMB
->InformationLevel
=
5653 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5654 } else /* Set File Size */ {
5655 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5656 pSMB
->InformationLevel
=
5657 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5659 pSMB
->InformationLevel
=
5660 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5662 pSMB
->Reserved4
= 0;
5663 inc_rfc1001_len(pSMB
, byte_count
);
5664 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5665 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5666 cifs_small_buf_release(pSMB
);
5668 cifs_dbg(FYI
, "Send error in SetFileInfo (SetFileSize) = %d\n",
5672 /* Note: On -EAGAIN error only caller can retry on handle based calls
5673 since file handle passed in no longer valid */
5678 /* Some legacy servers such as NT4 require that the file times be set on
5679 an open handle, rather than by pathname - this is awkward due to
5680 potential access conflicts on the open, but it is unavoidable for these
5681 old servers since the only other choice is to go from 100 nanosecond DCE
5682 time and resort to the original setpathinfo level which takes the ancient
5683 DOS time format with 2 second granularity */
5685 CIFSSMBSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5686 const FILE_BASIC_INFO
*data
, __u16 fid
, __u32 pid_of_opener
)
5688 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5691 __u16 params
, param_offset
, offset
, byte_count
, count
;
5693 cifs_dbg(FYI
, "Set Times (via SetFileInfo)\n");
5694 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5699 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5700 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5703 pSMB
->MaxSetupCount
= 0;
5707 pSMB
->Reserved2
= 0;
5708 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5709 offset
= param_offset
+ params
;
5711 data_offset
= (char *)pSMB
+
5712 offsetof(struct smb_hdr
, Protocol
) + offset
;
5714 count
= sizeof(FILE_BASIC_INFO
);
5715 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5716 /* BB find max SMB PDU from sess */
5717 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5718 pSMB
->SetupCount
= 1;
5719 pSMB
->Reserved3
= 0;
5720 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5721 byte_count
= 3 /* pad */ + params
+ count
;
5722 pSMB
->DataCount
= cpu_to_le16(count
);
5723 pSMB
->ParameterCount
= cpu_to_le16(params
);
5724 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5725 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5726 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5727 pSMB
->DataOffset
= cpu_to_le16(offset
);
5729 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5730 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5732 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5733 pSMB
->Reserved4
= 0;
5734 inc_rfc1001_len(pSMB
, byte_count
);
5735 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5736 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5737 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5738 cifs_small_buf_release(pSMB
);
5740 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5743 /* Note: On -EAGAIN error only caller can retry on handle based calls
5744 since file handle passed in no longer valid */
5750 CIFSSMBSetFileDisposition(const unsigned int xid
, struct cifs_tcon
*tcon
,
5751 bool delete_file
, __u16 fid
, __u32 pid_of_opener
)
5753 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5756 __u16 params
, param_offset
, offset
, byte_count
, count
;
5758 cifs_dbg(FYI
, "Set File Disposition (via SetFileInfo)\n");
5759 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5764 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5765 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5768 pSMB
->MaxSetupCount
= 0;
5772 pSMB
->Reserved2
= 0;
5773 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5774 offset
= param_offset
+ params
;
5776 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5779 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5780 /* BB find max SMB PDU from sess */
5781 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5782 pSMB
->SetupCount
= 1;
5783 pSMB
->Reserved3
= 0;
5784 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5785 byte_count
= 3 /* pad */ + params
+ count
;
5786 pSMB
->DataCount
= cpu_to_le16(count
);
5787 pSMB
->ParameterCount
= cpu_to_le16(params
);
5788 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5789 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5790 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5791 pSMB
->DataOffset
= cpu_to_le16(offset
);
5793 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO
);
5794 pSMB
->Reserved4
= 0;
5795 inc_rfc1001_len(pSMB
, byte_count
);
5796 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5797 *data_offset
= delete_file
? 1 : 0;
5798 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5799 cifs_small_buf_release(pSMB
);
5801 cifs_dbg(FYI
, "Send error in SetFileDisposition = %d\n", rc
);
5807 CIFSSMBSetPathInfoFB(const unsigned int xid
, struct cifs_tcon
*tcon
,
5808 const char *fileName
, const FILE_BASIC_INFO
*data
,
5809 const struct nls_table
*nls_codepage
,
5810 struct cifs_sb_info
*cifs_sb
)
5813 struct cifs_open_parms oparms
;
5814 struct cifs_fid fid
;
5818 oparms
.cifs_sb
= cifs_sb
;
5819 oparms
.desired_access
= GENERIC_WRITE
;
5820 oparms
.create_options
= cifs_create_options(cifs_sb
, 0);
5821 oparms
.disposition
= FILE_OPEN
;
5822 oparms
.path
= fileName
;
5824 oparms
.reconnect
= false;
5826 rc
= CIFS_open(xid
, &oparms
, &oplock
, NULL
);
5830 rc
= CIFSSMBSetFileInfo(xid
, tcon
, data
, fid
.netfid
, current
->tgid
);
5831 CIFSSMBClose(xid
, tcon
, fid
.netfid
);
5838 CIFSSMBSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5839 const char *fileName
, const FILE_BASIC_INFO
*data
,
5840 const struct nls_table
*nls_codepage
,
5841 struct cifs_sb_info
*cifs_sb
)
5843 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5844 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5847 int bytes_returned
= 0;
5849 __u16 params
, param_offset
, offset
, byte_count
, count
;
5850 int remap
= cifs_remap(cifs_sb
);
5852 cifs_dbg(FYI
, "In SetTimes\n");
5855 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5860 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5862 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5863 PATH_MAX
, nls_codepage
, remap
);
5864 name_len
++; /* trailing null */
5867 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
5870 params
= 6 + name_len
;
5871 count
= sizeof(FILE_BASIC_INFO
);
5872 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5873 /* BB find max SMB PDU from sess structure BB */
5874 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5875 pSMB
->MaxSetupCount
= 0;
5879 pSMB
->Reserved2
= 0;
5880 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5881 InformationLevel
) - 4;
5882 offset
= param_offset
+ params
;
5883 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5884 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5885 pSMB
->DataOffset
= cpu_to_le16(offset
);
5886 pSMB
->SetupCount
= 1;
5887 pSMB
->Reserved3
= 0;
5888 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5889 byte_count
= 3 /* pad */ + params
+ count
;
5891 pSMB
->DataCount
= cpu_to_le16(count
);
5892 pSMB
->ParameterCount
= cpu_to_le16(params
);
5893 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5894 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5895 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5896 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5898 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5899 pSMB
->Reserved4
= 0;
5900 inc_rfc1001_len(pSMB
, byte_count
);
5901 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5902 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5903 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5904 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5906 cifs_dbg(FYI
, "SetPathInfo (times) returned %d\n", rc
);
5908 cifs_buf_release(pSMB
);
5913 if (rc
== -EOPNOTSUPP
)
5914 return CIFSSMBSetPathInfoFB(xid
, tcon
, fileName
, data
,
5915 nls_codepage
, cifs_sb
);
5920 /* Can not be used to set time stamps yet (due to old DOS time format) */
5921 /* Can be used to set attributes */
5922 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5923 handling it anyway and NT4 was what we thought it would be needed for
5924 Do not delete it until we prove whether needed for Win9x though */
5926 CIFSSMBSetAttrLegacy(unsigned int xid
, struct cifs_tcon
*tcon
, char *fileName
,
5927 __u16 dos_attrs
, const struct nls_table
*nls_codepage
)
5929 SETATTR_REQ
*pSMB
= NULL
;
5930 SETATTR_RSP
*pSMBr
= NULL
;
5935 cifs_dbg(FYI
, "In SetAttrLegacy\n");
5938 rc
= smb_init(SMB_COM_SETATTR
, 8, tcon
, (void **) &pSMB
,
5943 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5945 ConvertToUTF16((__le16
*) pSMB
->fileName
, fileName
,
5946 PATH_MAX
, nls_codepage
);
5947 name_len
++; /* trailing null */
5950 name_len
= copy_path_name(pSMB
->fileName
, fileName
);
5952 pSMB
->attr
= cpu_to_le16(dos_attrs
);
5953 pSMB
->BufferFormat
= 0x04;
5954 inc_rfc1001_len(pSMB
, name_len
+ 1);
5955 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
5956 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5957 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5959 cifs_dbg(FYI
, "Error in LegacySetAttr = %d\n", rc
);
5961 cifs_buf_release(pSMB
);
5964 goto SetAttrLgcyRetry
;
5968 #endif /* temporarily unneeded SetAttr legacy function */
5971 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO
*data_offset
,
5972 const struct cifs_unix_set_info_args
*args
)
5974 u64 uid
= NO_CHANGE_64
, gid
= NO_CHANGE_64
;
5975 u64 mode
= args
->mode
;
5977 if (uid_valid(args
->uid
))
5978 uid
= from_kuid(&init_user_ns
, args
->uid
);
5979 if (gid_valid(args
->gid
))
5980 gid
= from_kgid(&init_user_ns
, args
->gid
);
5983 * Samba server ignores set of file size to zero due to bugs in some
5984 * older clients, but we should be precise - we use SetFileSize to
5985 * set file size and do not want to truncate file size to zero
5986 * accidentally as happened on one Samba server beta by putting
5987 * zero instead of -1 here
5989 data_offset
->EndOfFile
= cpu_to_le64(NO_CHANGE_64
);
5990 data_offset
->NumOfBytes
= cpu_to_le64(NO_CHANGE_64
);
5991 data_offset
->LastStatusChange
= cpu_to_le64(args
->ctime
);
5992 data_offset
->LastAccessTime
= cpu_to_le64(args
->atime
);
5993 data_offset
->LastModificationTime
= cpu_to_le64(args
->mtime
);
5994 data_offset
->Uid
= cpu_to_le64(uid
);
5995 data_offset
->Gid
= cpu_to_le64(gid
);
5996 /* better to leave device as zero when it is */
5997 data_offset
->DevMajor
= cpu_to_le64(MAJOR(args
->device
));
5998 data_offset
->DevMinor
= cpu_to_le64(MINOR(args
->device
));
5999 data_offset
->Permissions
= cpu_to_le64(mode
);
6002 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
6003 else if (S_ISDIR(mode
))
6004 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
6005 else if (S_ISLNK(mode
))
6006 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
6007 else if (S_ISCHR(mode
))
6008 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
6009 else if (S_ISBLK(mode
))
6010 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
6011 else if (S_ISFIFO(mode
))
6012 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
6013 else if (S_ISSOCK(mode
))
6014 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
6018 CIFSSMBUnixSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6019 const struct cifs_unix_set_info_args
*args
,
6020 u16 fid
, u32 pid_of_opener
)
6022 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
6025 u16 params
, param_offset
, offset
, byte_count
, count
;
6027 cifs_dbg(FYI
, "Set Unix Info (via SetFileInfo)\n");
6028 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
6033 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
6034 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
6037 pSMB
->MaxSetupCount
= 0;
6041 pSMB
->Reserved2
= 0;
6042 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
6043 offset
= param_offset
+ params
;
6045 data_offset
= (char *)pSMB
+
6046 offsetof(struct smb_hdr
, Protocol
) + offset
;
6048 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6050 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6051 /* BB find max SMB PDU from sess */
6052 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6053 pSMB
->SetupCount
= 1;
6054 pSMB
->Reserved3
= 0;
6055 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
6056 byte_count
= 3 /* pad */ + params
+ count
;
6057 pSMB
->DataCount
= cpu_to_le16(count
);
6058 pSMB
->ParameterCount
= cpu_to_le16(params
);
6059 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6060 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6061 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6062 pSMB
->DataOffset
= cpu_to_le16(offset
);
6064 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6065 pSMB
->Reserved4
= 0;
6066 inc_rfc1001_len(pSMB
, byte_count
);
6067 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6069 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO
*)data_offset
, args
);
6071 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
6072 cifs_small_buf_release(pSMB
);
6074 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
6077 /* Note: On -EAGAIN error only caller can retry on handle based calls
6078 since file handle passed in no longer valid */
6084 CIFSSMBUnixSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6085 const char *file_name
,
6086 const struct cifs_unix_set_info_args
*args
,
6087 const struct nls_table
*nls_codepage
, int remap
)
6089 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
6090 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
6093 int bytes_returned
= 0;
6094 FILE_UNIX_BASIC_INFO
*data_offset
;
6095 __u16 params
, param_offset
, offset
, count
, byte_count
;
6097 cifs_dbg(FYI
, "In SetUID/GID/Mode\n");
6099 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6104 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6106 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
6107 PATH_MAX
, nls_codepage
, remap
);
6108 name_len
++; /* trailing null */
6111 name_len
= copy_path_name(pSMB
->FileName
, file_name
);
6114 params
= 6 + name_len
;
6115 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6116 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6117 /* BB find max SMB PDU from sess structure BB */
6118 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6119 pSMB
->MaxSetupCount
= 0;
6123 pSMB
->Reserved2
= 0;
6124 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6125 InformationLevel
) - 4;
6126 offset
= param_offset
+ params
;
6128 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
6130 memset(data_offset
, 0, count
);
6131 pSMB
->DataOffset
= cpu_to_le16(offset
);
6132 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6133 pSMB
->SetupCount
= 1;
6134 pSMB
->Reserved3
= 0;
6135 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6136 byte_count
= 3 /* pad */ + params
+ count
;
6137 pSMB
->ParameterCount
= cpu_to_le16(params
);
6138 pSMB
->DataCount
= cpu_to_le16(count
);
6139 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6140 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6141 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6142 pSMB
->Reserved4
= 0;
6143 inc_rfc1001_len(pSMB
, byte_count
);
6145 cifs_fill_unix_set_info(data_offset
, args
);
6147 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6148 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6149 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6151 cifs_dbg(FYI
, "SetPathInfo (perms) returned %d\n", rc
);
6153 cifs_buf_release(pSMB
);
6159 #ifdef CONFIG_CIFS_XATTR
6161 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6162 * function used by listxattr and getxattr type calls. When ea_name is set,
6163 * it looks for that attribute name and stuffs that value into the EAData
6164 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6165 * buffer. In both cases, the return value is either the length of the
6166 * resulting data or a negative error code. If EAData is a NULL pointer then
6167 * the data isn't copied to it, but the length is returned.
6170 CIFSSMBQAllEAs(const unsigned int xid
, struct cifs_tcon
*tcon
,
6171 const unsigned char *searchName
, const unsigned char *ea_name
,
6172 char *EAData
, size_t buf_size
,
6173 struct cifs_sb_info
*cifs_sb
)
6175 /* BB assumes one setup word */
6176 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
6177 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
6178 int remap
= cifs_remap(cifs_sb
);
6179 struct nls_table
*nls_codepage
= cifs_sb
->local_nls
;
6183 struct fealist
*ea_response_data
;
6184 struct fea
*temp_fea
;
6187 __u16 params
, byte_count
, data_offset
;
6188 unsigned int ea_name_len
= ea_name
? strlen(ea_name
) : 0;
6190 cifs_dbg(FYI
, "In Query All EAs path %s\n", searchName
);
6192 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6197 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6199 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
6200 PATH_MAX
, nls_codepage
, remap
);
6201 list_len
++; /* trailing null */
6204 list_len
= copy_path_name(pSMB
->FileName
, searchName
);
6207 params
= 2 /* level */ + 4 /* reserved */ + list_len
/* includes NUL */;
6208 pSMB
->TotalDataCount
= 0;
6209 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6210 /* BB find exact max SMB PDU from sess structure BB */
6211 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
6212 pSMB
->MaxSetupCount
= 0;
6216 pSMB
->Reserved2
= 0;
6217 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
6218 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
6219 pSMB
->DataCount
= 0;
6220 pSMB
->DataOffset
= 0;
6221 pSMB
->SetupCount
= 1;
6222 pSMB
->Reserved3
= 0;
6223 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
6224 byte_count
= params
+ 1 /* pad */ ;
6225 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
6226 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6227 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
6228 pSMB
->Reserved4
= 0;
6229 inc_rfc1001_len(pSMB
, byte_count
);
6230 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6232 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6233 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6235 cifs_dbg(FYI
, "Send error in QueryAllEAs = %d\n", rc
);
6240 /* BB also check enough total bytes returned */
6241 /* BB we need to improve the validity checking
6242 of these trans2 responses */
6244 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
6245 if (rc
|| get_bcc(&pSMBr
->hdr
) < 4) {
6246 rc
= -EIO
; /* bad smb */
6250 /* check that length of list is not more than bcc */
6251 /* check that each entry does not go beyond length
6253 /* check that each element of each entry does not
6254 go beyond end of list */
6255 /* validate_trans2_offsets() */
6256 /* BB check if start of smb + data_offset > &bcc+ bcc */
6258 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
6259 ea_response_data
= (struct fealist
*)
6260 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
6262 list_len
= le32_to_cpu(ea_response_data
->list_len
);
6263 cifs_dbg(FYI
, "ea length %d\n", list_len
);
6264 if (list_len
<= 8) {
6265 cifs_dbg(FYI
, "empty EA list returned from server\n");
6266 /* didn't find the named attribute */
6272 /* make sure list_len doesn't go past end of SMB */
6273 end_of_smb
= (char *)pByteArea(&pSMBr
->hdr
) + get_bcc(&pSMBr
->hdr
);
6274 if ((char *)ea_response_data
+ list_len
> end_of_smb
) {
6275 cifs_dbg(FYI
, "EA list appears to go beyond SMB\n");
6280 /* account for ea list len */
6282 temp_fea
= ea_response_data
->list
;
6283 temp_ptr
= (char *)temp_fea
;
6284 while (list_len
> 0) {
6285 unsigned int name_len
;
6290 /* make sure we can read name_len and value_len */
6292 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6297 name_len
= temp_fea
->name_len
;
6298 value_len
= le16_to_cpu(temp_fea
->value_len
);
6299 list_len
-= name_len
+ 1 + value_len
;
6301 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6307 if (ea_name_len
== name_len
&&
6308 memcmp(ea_name
, temp_ptr
, name_len
) == 0) {
6309 temp_ptr
+= name_len
+ 1;
6313 if ((size_t)value_len
> buf_size
) {
6317 memcpy(EAData
, temp_ptr
, value_len
);
6321 /* account for prefix user. and trailing null */
6322 rc
+= (5 + 1 + name_len
);
6323 if (rc
< (int) buf_size
) {
6324 memcpy(EAData
, "user.", 5);
6326 memcpy(EAData
, temp_ptr
, name_len
);
6328 /* null terminate name */
6331 } else if (buf_size
== 0) {
6332 /* skip copy - calc size only */
6334 /* stop before overrun buffer */
6339 temp_ptr
+= name_len
+ 1 + value_len
;
6340 temp_fea
= (struct fea
*)temp_ptr
;
6343 /* didn't find the named attribute */
6348 cifs_buf_release(pSMB
);
6356 CIFSSMBSetEA(const unsigned int xid
, struct cifs_tcon
*tcon
,
6357 const char *fileName
, const char *ea_name
, const void *ea_value
,
6358 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
,
6359 struct cifs_sb_info
*cifs_sb
)
6361 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
6362 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
6363 struct fealist
*parm_data
;
6366 int bytes_returned
= 0;
6367 __u16 params
, param_offset
, byte_count
, offset
, count
;
6368 int remap
= cifs_remap(cifs_sb
);
6370 cifs_dbg(FYI
, "In SetEA\n");
6372 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6377 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6379 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
6380 PATH_MAX
, nls_codepage
, remap
);
6381 name_len
++; /* trailing null */
6384 name_len
= copy_path_name(pSMB
->FileName
, fileName
);
6387 params
= 6 + name_len
;
6389 /* done calculating parms using name_len of file name,
6390 now use name_len to calculate length of ea name
6391 we are going to create in the inode xattrs */
6392 if (ea_name
== NULL
)
6395 name_len
= strnlen(ea_name
, 255);
6397 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
;
6398 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6399 /* BB find max SMB PDU from sess */
6400 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6401 pSMB
->MaxSetupCount
= 0;
6405 pSMB
->Reserved2
= 0;
6406 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6407 InformationLevel
) - 4;
6408 offset
= param_offset
+ params
;
6409 pSMB
->InformationLevel
=
6410 cpu_to_le16(SMB_SET_FILE_EA
);
6412 parm_data
= (void *)pSMB
+ offsetof(struct smb_hdr
, Protocol
) + offset
;
6413 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6414 pSMB
->DataOffset
= cpu_to_le16(offset
);
6415 pSMB
->SetupCount
= 1;
6416 pSMB
->Reserved3
= 0;
6417 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6418 byte_count
= 3 /* pad */ + params
+ count
;
6419 pSMB
->DataCount
= cpu_to_le16(count
);
6420 parm_data
->list_len
= cpu_to_le32(count
);
6421 parm_data
->list
[0].EA_flags
= 0;
6422 /* we checked above that name len is less than 255 */
6423 parm_data
->list
[0].name_len
= (__u8
)name_len
;
6424 /* EA names are always ASCII */
6426 strncpy(parm_data
->list
[0].name
, ea_name
, name_len
);
6427 parm_data
->list
[0].name
[name_len
] = 0;
6428 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
6429 /* caller ensures that ea_value_len is less than 64K but
6430 we need to ensure that it fits within the smb */
6432 /*BB add length check to see if it would fit in
6433 negotiated SMB buffer size BB */
6434 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6436 memcpy(parm_data
->list
[0].name
+name_len
+1,
6437 ea_value
, ea_value_len
);
6439 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6440 pSMB
->ParameterCount
= cpu_to_le16(params
);
6441 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6442 pSMB
->Reserved4
= 0;
6443 inc_rfc1001_len(pSMB
, byte_count
);
6444 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6445 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6446 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6448 cifs_dbg(FYI
, "SetPathInfo (EA) returned %d\n", rc
);
6450 cifs_buf_release(pSMB
);