4 * Copyright (C) International Business Machines Corp., 2002,2010
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Contains the routines for constructing the SMB PDUs themselves
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
25 /* These are mostly routines that operate on a pathname, or on a tree id */
26 /* (mounted volume), but there are eight handle based routines which must be */
27 /* treated slightly differently for reconnection purposes since we never */
28 /* want to reuse a stale file handle and only the caller knows the file info */
31 #include <linux/kernel.h>
32 #include <linux/vfs.h>
33 #include <linux/slab.h>
34 #include <linux/posix_acl_xattr.h>
35 #include <linux/pagemap.h>
36 #include <linux/swap.h>
37 #include <linux/task_io_accounting_ops.h>
38 #include <linux/uaccess.h>
42 #include "cifsproto.h"
43 #include "cifs_unicode.h"
44 #include "cifs_debug.h"
46 #include "smbdirect.h"
48 #ifdef CONFIG_CIFS_POSIX
53 #ifdef CONFIG_CIFS_WEAK_PW_HASH
54 {LANMAN_PROT
, "\2LM1.2X002"},
55 {LANMAN2_PROT
, "\2LANMAN2.1"},
56 #endif /* weak password hashing for legacy clients */
57 {CIFS_PROT
, "\2NT LM 0.12"},
58 {POSIX_PROT
, "\2POSIX 2"},
66 #ifdef CONFIG_CIFS_WEAK_PW_HASH
67 {LANMAN_PROT
, "\2LM1.2X002"},
68 {LANMAN2_PROT
, "\2LANMAN2.1"},
69 #endif /* weak password hashing for legacy clients */
70 {CIFS_PROT
, "\2NT LM 0.12"},
75 /* define the number of elements in the cifs dialect array */
76 #ifdef CONFIG_CIFS_POSIX
77 #ifdef CONFIG_CIFS_WEAK_PW_HASH
78 #define CIFS_NUM_PROT 4
80 #define CIFS_NUM_PROT 2
81 #endif /* CIFS_WEAK_PW_HASH */
83 #ifdef CONFIG_CIFS_WEAK_PW_HASH
84 #define CIFS_NUM_PROT 3
86 #define CIFS_NUM_PROT 1
87 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
88 #endif /* CIFS_POSIX */
91 * Mark as invalid, all open files on tree connections since they
92 * were closed when session to server was lost.
95 cifs_mark_open_files_invalid(struct cifs_tcon
*tcon
)
97 struct cifsFileInfo
*open_file
= NULL
;
98 struct list_head
*tmp
;
99 struct list_head
*tmp1
;
101 /* list all files open on tree connection and mark them invalid */
102 spin_lock(&tcon
->open_file_lock
);
103 list_for_each_safe(tmp
, tmp1
, &tcon
->openFileList
) {
104 open_file
= list_entry(tmp
, struct cifsFileInfo
, tlist
);
105 open_file
->invalidHandle
= true;
106 open_file
->oplock_break_cancelled
= true;
108 spin_unlock(&tcon
->open_file_lock
);
110 mutex_lock(&tcon
->crfid
.fid_mutex
);
111 tcon
->crfid
.is_valid
= false;
112 memset(tcon
->crfid
.fid
, 0, sizeof(struct cifs_fid
));
113 mutex_unlock(&tcon
->crfid
.fid_mutex
);
116 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
121 /* reconnect the socket, tcon, and smb session if needed */
123 cifs_reconnect_tcon(struct cifs_tcon
*tcon
, int smb_command
)
126 struct cifs_ses
*ses
;
127 struct TCP_Server_Info
*server
;
128 struct nls_table
*nls_codepage
;
131 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
132 * tcp and smb session status done differently for those three - in the
139 server
= ses
->server
;
142 * only tree disconnect, open, and write, (and ulogoff which does not
143 * have tcon) are allowed as we start force umount
145 if (tcon
->tidStatus
== CifsExiting
) {
146 if (smb_command
!= SMB_COM_WRITE_ANDX
&&
147 smb_command
!= SMB_COM_OPEN_ANDX
&&
148 smb_command
!= SMB_COM_TREE_DISCONNECT
) {
149 cifs_dbg(FYI
, "can not send cmd %d while umounting\n",
156 * Give demultiplex thread up to 10 seconds to reconnect, should be
157 * greater than cifs socket timeout which is 7 seconds
159 while (server
->tcpStatus
== CifsNeedReconnect
) {
160 rc
= wait_event_interruptible_timeout(server
->response_q
,
161 (server
->tcpStatus
!= CifsNeedReconnect
),
164 cifs_dbg(FYI
, "%s: aborting reconnect due to a received"
165 " signal by the process\n", __func__
);
169 /* are we still trying to reconnect? */
170 if (server
->tcpStatus
!= CifsNeedReconnect
)
174 * on "soft" mounts we wait once. Hard mounts keep
175 * retrying until process is killed or server comes
179 cifs_dbg(FYI
, "gave up waiting on reconnect in smb_init\n");
184 if (!ses
->need_reconnect
&& !tcon
->need_reconnect
)
187 nls_codepage
= load_nls_default();
190 * need to prevent multiple threads trying to simultaneously
191 * reconnect the same SMB session
193 mutex_lock(&ses
->session_mutex
);
196 * Recheck after acquire mutex. If another thread is negotiating
197 * and the server never sends an answer the socket will be closed
198 * and tcpStatus set to reconnect.
200 if (server
->tcpStatus
== CifsNeedReconnect
) {
202 mutex_unlock(&ses
->session_mutex
);
206 rc
= cifs_negotiate_protocol(0, ses
);
207 if (rc
== 0 && ses
->need_reconnect
)
208 rc
= cifs_setup_session(0, ses
, nls_codepage
);
210 /* do we need to reconnect tcon? */
211 if (rc
|| !tcon
->need_reconnect
) {
212 mutex_unlock(&ses
->session_mutex
);
216 cifs_mark_open_files_invalid(tcon
);
217 rc
= CIFSTCon(0, ses
, tcon
->treeName
, tcon
, nls_codepage
);
218 mutex_unlock(&ses
->session_mutex
);
219 cifs_dbg(FYI
, "reconnect tcon rc = %d\n", rc
);
222 printk_once(KERN_WARNING
"reconnect tcon failed rc = %d\n", rc
);
226 atomic_inc(&tconInfoReconnectCount
);
228 /* tell server Unix caps we support */
229 if (ses
->capabilities
& CAP_UNIX
)
230 reset_cifs_unix_caps(0, tcon
, NULL
, NULL
);
233 * Removed call to reopen open files here. It is safer (and faster) to
234 * reopen files one at a time as needed in read and write.
236 * FIXME: what about file locks? don't we need to reclaim them ASAP?
241 * Check if handle based operation so we know whether we can continue
242 * or not without returning to caller to reset file handle
244 switch (smb_command
) {
245 case SMB_COM_READ_ANDX
:
246 case SMB_COM_WRITE_ANDX
:
248 case SMB_COM_FIND_CLOSE2
:
249 case SMB_COM_LOCKING_ANDX
:
253 unload_nls(nls_codepage
);
257 /* Allocate and return pointer to an SMB request buffer, and set basic
258 SMB information in the SMB header. If the return code is zero, this
259 function must have filled in request_buf pointer */
261 small_smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
266 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
270 *request_buf
= cifs_small_buf_get();
271 if (*request_buf
== NULL
) {
272 /* BB should we add a retry in here if not a writepage? */
276 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
,
280 cifs_stats_inc(&tcon
->num_smbs_sent
);
286 small_smb_init_no_tc(const int smb_command
, const int wct
,
287 struct cifs_ses
*ses
, void **request_buf
)
290 struct smb_hdr
*buffer
;
292 rc
= small_smb_init(smb_command
, wct
, NULL
, request_buf
);
296 buffer
= (struct smb_hdr
*)*request_buf
;
297 buffer
->Mid
= get_next_mid(ses
->server
);
298 if (ses
->capabilities
& CAP_UNICODE
)
299 buffer
->Flags2
|= SMBFLG2_UNICODE
;
300 if (ses
->capabilities
& CAP_STATUS32
)
301 buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
303 /* uid, tid can stay at zero as set in header assemble */
305 /* BB add support for turning on the signing when
306 this function is used after 1st of session setup requests */
311 /* If the return code is zero, this function must fill in request_buf pointer */
313 __smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
314 void **request_buf
, void **response_buf
)
316 *request_buf
= cifs_buf_get();
317 if (*request_buf
== NULL
) {
318 /* BB should we add a retry in here if not a writepage? */
321 /* Although the original thought was we needed the response buf for */
322 /* potential retries of smb operations it turns out we can determine */
323 /* from the mid flags when the request buffer can be resent without */
324 /* having to use a second distinct buffer for the response */
326 *response_buf
= *request_buf
;
328 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
, tcon
,
332 cifs_stats_inc(&tcon
->num_smbs_sent
);
337 /* If the return code is zero, this function must fill in request_buf pointer */
339 smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
340 void **request_buf
, void **response_buf
)
344 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
348 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
352 smb_init_no_reconnect(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
353 void **request_buf
, void **response_buf
)
355 if (tcon
->ses
->need_reconnect
|| tcon
->need_reconnect
)
358 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
361 static int validate_t2(struct smb_t2_rsp
*pSMB
)
363 unsigned int total_size
;
365 /* check for plausible wct */
366 if (pSMB
->hdr
.WordCount
< 10)
369 /* check for parm and data offset going beyond end of smb */
370 if (get_unaligned_le16(&pSMB
->t2_rsp
.ParameterOffset
) > 1024 ||
371 get_unaligned_le16(&pSMB
->t2_rsp
.DataOffset
) > 1024)
374 total_size
= get_unaligned_le16(&pSMB
->t2_rsp
.ParameterCount
);
375 if (total_size
>= 512)
378 /* check that bcc is at least as big as parms + data, and that it is
379 * less than negotiated smb buffer
381 total_size
+= get_unaligned_le16(&pSMB
->t2_rsp
.DataCount
);
382 if (total_size
> get_bcc(&pSMB
->hdr
) ||
383 total_size
>= CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
)
388 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB
,
389 sizeof(struct smb_t2_rsp
) + 16);
394 decode_ext_sec_blob(struct cifs_ses
*ses
, NEGOTIATE_RSP
*pSMBr
)
398 char *guid
= pSMBr
->u
.extended_response
.GUID
;
399 struct TCP_Server_Info
*server
= ses
->server
;
401 count
= get_bcc(&pSMBr
->hdr
);
402 if (count
< SMB1_CLIENT_GUID_SIZE
)
405 spin_lock(&cifs_tcp_ses_lock
);
406 if (server
->srv_count
> 1) {
407 spin_unlock(&cifs_tcp_ses_lock
);
408 if (memcmp(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
) != 0) {
409 cifs_dbg(FYI
, "server UID changed\n");
410 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
413 spin_unlock(&cifs_tcp_ses_lock
);
414 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
417 if (count
== SMB1_CLIENT_GUID_SIZE
) {
418 server
->sec_ntlmssp
= true;
420 count
-= SMB1_CLIENT_GUID_SIZE
;
421 rc
= decode_negTokenInit(
422 pSMBr
->u
.extended_response
.SecurityBlob
, count
, server
);
431 cifs_enable_signing(struct TCP_Server_Info
*server
, bool mnt_sign_required
)
433 bool srv_sign_required
= server
->sec_mode
& server
->vals
->signing_required
;
434 bool srv_sign_enabled
= server
->sec_mode
& server
->vals
->signing_enabled
;
435 bool mnt_sign_enabled
= global_secflags
& CIFSSEC_MAY_SIGN
;
438 * Is signing required by mnt options? If not then check
439 * global_secflags to see if it is there.
441 if (!mnt_sign_required
)
442 mnt_sign_required
= ((global_secflags
& CIFSSEC_MUST_SIGN
) ==
446 * If signing is required then it's automatically enabled too,
447 * otherwise, check to see if the secflags allow it.
449 mnt_sign_enabled
= mnt_sign_required
? mnt_sign_required
:
450 (global_secflags
& CIFSSEC_MAY_SIGN
);
452 /* If server requires signing, does client allow it? */
453 if (srv_sign_required
) {
454 if (!mnt_sign_enabled
) {
455 cifs_dbg(VFS
, "Server requires signing, but it's disabled in SecurityFlags!");
461 /* If client requires signing, does server allow it? */
462 if (mnt_sign_required
) {
463 if (!srv_sign_enabled
) {
464 cifs_dbg(VFS
, "Server does not support signing!");
470 if (cifs_rdma_enabled(server
) && server
->sign
)
471 cifs_dbg(VFS
, "Signing is enabled, and RDMA read/write will be disabled");
476 #ifdef CONFIG_CIFS_WEAK_PW_HASH
478 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
481 struct lanman_neg_rsp
*rsp
= (struct lanman_neg_rsp
*)pSMBr
;
483 if (server
->dialect
!= LANMAN_PROT
&& server
->dialect
!= LANMAN2_PROT
)
486 server
->sec_mode
= le16_to_cpu(rsp
->SecurityMode
);
487 server
->maxReq
= min_t(unsigned int,
488 le16_to_cpu(rsp
->MaxMpxCount
),
490 set_credits(server
, server
->maxReq
);
491 server
->maxBuf
= le16_to_cpu(rsp
->MaxBufSize
);
492 /* even though we do not use raw we might as well set this
493 accurately, in case we ever find a need for it */
494 if ((le16_to_cpu(rsp
->RawMode
) & RAW_ENABLE
) == RAW_ENABLE
) {
495 server
->max_rw
= 0xFF00;
496 server
->capabilities
= CAP_MPX_MODE
| CAP_RAW_MODE
;
498 server
->max_rw
= 0;/* do not need to use raw anyway */
499 server
->capabilities
= CAP_MPX_MODE
;
501 tmp
= (__s16
)le16_to_cpu(rsp
->ServerTimeZone
);
503 /* OS/2 often does not set timezone therefore
504 * we must use server time to calc time zone.
505 * Could deviate slightly from the right zone.
506 * Smallest defined timezone difference is 15 minutes
507 * (i.e. Nepal). Rounding up/down is done to match
510 int val
, seconds
, remain
, result
;
511 struct timespec64 ts
;
512 time64_t utc
= ktime_get_real_seconds();
513 ts
= cnvrtDosUnixTm(rsp
->SrvTime
.Date
,
514 rsp
->SrvTime
.Time
, 0);
515 cifs_dbg(FYI
, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n",
518 val
= (int)(utc
- ts
.tv_sec
);
520 result
= (seconds
/ MIN_TZ_ADJ
) * MIN_TZ_ADJ
;
521 remain
= seconds
% MIN_TZ_ADJ
;
522 if (remain
>= (MIN_TZ_ADJ
/ 2))
523 result
+= MIN_TZ_ADJ
;
526 server
->timeAdj
= result
;
528 server
->timeAdj
= (int)tmp
;
529 server
->timeAdj
*= 60; /* also in seconds */
531 cifs_dbg(FYI
, "server->timeAdj: %d seconds\n", server
->timeAdj
);
534 /* BB get server time for time conversions and add
535 code to use it and timezone since this is not UTC */
537 if (rsp
->EncryptionKeyLength
==
538 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE
)) {
539 memcpy(server
->cryptkey
, rsp
->EncryptionKey
,
540 CIFS_CRYPTO_KEY_SIZE
);
541 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
542 return -EIO
; /* need cryptkey unless plain text */
545 cifs_dbg(FYI
, "LANMAN negotiated\n");
550 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
552 cifs_dbg(VFS
, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
558 should_set_ext_sec_flag(enum securityEnum sectype
)
565 if (global_secflags
&
566 (CIFSSEC_MAY_KRB5
| CIFSSEC_MAY_NTLMSSP
))
575 CIFSSMBNegotiate(const unsigned int xid
, struct cifs_ses
*ses
)
578 NEGOTIATE_RSP
*pSMBr
;
582 struct TCP_Server_Info
*server
= ses
->server
;
586 WARN(1, "%s: server is NULL!\n", __func__
);
590 rc
= smb_init(SMB_COM_NEGOTIATE
, 0, NULL
/* no tcon yet */ ,
591 (void **) &pSMB
, (void **) &pSMBr
);
595 pSMB
->hdr
.Mid
= get_next_mid(server
);
596 pSMB
->hdr
.Flags2
|= (SMBFLG2_UNICODE
| SMBFLG2_ERR_STATUS
);
598 if (should_set_ext_sec_flag(ses
->sectype
)) {
599 cifs_dbg(FYI
, "Requesting extended security.");
600 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
605 * We know that all the name entries in the protocols array
606 * are short (< 16 bytes anyway) and are NUL terminated.
608 for (i
= 0; i
< CIFS_NUM_PROT
; i
++) {
609 size_t len
= strlen(protocols
[i
].name
) + 1;
611 memcpy(pSMB
->DialectsArray
+count
, protocols
[i
].name
, len
);
614 inc_rfc1001_len(pSMB
, count
);
615 pSMB
->ByteCount
= cpu_to_le16(count
);
617 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
618 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
622 server
->dialect
= le16_to_cpu(pSMBr
->DialectIndex
);
623 cifs_dbg(FYI
, "Dialect: %d\n", server
->dialect
);
624 /* Check wct = 1 error case */
625 if ((pSMBr
->hdr
.WordCount
< 13) || (server
->dialect
== BAD_PROT
)) {
626 /* core returns wct = 1, but we do not ask for core - otherwise
627 small wct just comes when dialect index is -1 indicating we
628 could not negotiate a common dialect */
631 } else if (pSMBr
->hdr
.WordCount
== 13) {
632 server
->negflavor
= CIFS_NEGFLAVOR_LANMAN
;
633 rc
= decode_lanman_negprot_rsp(server
, pSMBr
);
635 } else if (pSMBr
->hdr
.WordCount
!= 17) {
640 /* else wct == 17, NTLM or better */
642 server
->sec_mode
= pSMBr
->SecurityMode
;
643 if ((server
->sec_mode
& SECMODE_USER
) == 0)
644 cifs_dbg(FYI
, "share mode security\n");
646 /* one byte, so no need to convert this or EncryptionKeyLen from
648 server
->maxReq
= min_t(unsigned int, le16_to_cpu(pSMBr
->MaxMpxCount
),
650 set_credits(server
, server
->maxReq
);
651 /* probably no need to store and check maxvcs */
652 server
->maxBuf
= le32_to_cpu(pSMBr
->MaxBufferSize
);
653 server
->max_rw
= le32_to_cpu(pSMBr
->MaxRawSize
);
654 cifs_dbg(NOISY
, "Max buf = %d\n", ses
->server
->maxBuf
);
655 server
->capabilities
= le32_to_cpu(pSMBr
->Capabilities
);
656 server
->timeAdj
= (int)(__s16
)le16_to_cpu(pSMBr
->ServerTimeZone
);
657 server
->timeAdj
*= 60;
659 if (pSMBr
->EncryptionKeyLength
== CIFS_CRYPTO_KEY_SIZE
) {
660 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
661 memcpy(ses
->server
->cryptkey
, pSMBr
->u
.EncryptionKey
,
662 CIFS_CRYPTO_KEY_SIZE
);
663 } else if (pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
||
664 server
->capabilities
& CAP_EXTENDED_SECURITY
) {
665 server
->negflavor
= CIFS_NEGFLAVOR_EXTENDED
;
666 rc
= decode_ext_sec_blob(ses
, pSMBr
);
667 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
668 rc
= -EIO
; /* no crypt key only if plain text pwd */
670 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
671 server
->capabilities
&= ~CAP_EXTENDED_SECURITY
;
676 rc
= cifs_enable_signing(server
, ses
->sign
);
678 cifs_buf_release(pSMB
);
680 cifs_dbg(FYI
, "negprot rc %d\n", rc
);
685 CIFSSMBTDis(const unsigned int xid
, struct cifs_tcon
*tcon
)
687 struct smb_hdr
*smb_buffer
;
690 cifs_dbg(FYI
, "In tree disconnect\n");
692 /* BB: do we need to check this? These should never be NULL. */
693 if ((tcon
->ses
== NULL
) || (tcon
->ses
->server
== NULL
))
697 * No need to return error on this operation if tid invalidated and
698 * closed on server already e.g. due to tcp session crashing. Also,
699 * the tcon is no longer on the list, so no need to take lock before
702 if ((tcon
->need_reconnect
) || (tcon
->ses
->need_reconnect
))
705 rc
= small_smb_init(SMB_COM_TREE_DISCONNECT
, 0, tcon
,
706 (void **)&smb_buffer
);
710 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)smb_buffer
, 0);
711 cifs_small_buf_release(smb_buffer
);
713 cifs_dbg(FYI
, "Tree disconnect failed %d\n", rc
);
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 */
724 * This is a no-op for now. We're not really interested in the reply, but
725 * rather in the fact that the server sent one and that server->lstrp
728 * FIXME: maybe we should consider checking that the reply matches request?
731 cifs_echo_callback(struct mid_q_entry
*mid
)
733 struct TCP_Server_Info
*server
= mid
->callback_data
;
735 DeleteMidQEntry(mid
);
736 add_credits(server
, 1, CIFS_ECHO_OP
);
740 CIFSSMBEcho(struct TCP_Server_Info
*server
)
745 struct smb_rqst rqst
= { .rq_iov
= iov
,
748 cifs_dbg(FYI
, "In echo request\n");
750 rc
= small_smb_init(SMB_COM_ECHO
, 0, NULL
, (void **)&smb
);
754 if (server
->capabilities
& CAP_UNICODE
)
755 smb
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
757 /* set up echo request */
758 smb
->hdr
.Tid
= 0xffff;
759 smb
->hdr
.WordCount
= 1;
760 put_unaligned_le16(1, &smb
->EchoCount
);
761 put_bcc(1, &smb
->hdr
);
763 inc_rfc1001_len(smb
, 3);
766 iov
[0].iov_base
= smb
;
767 iov
[1].iov_len
= get_rfc1002_length(smb
);
768 iov
[1].iov_base
= (char *)smb
+ 4;
770 rc
= cifs_call_async(server
, &rqst
, NULL
, cifs_echo_callback
, NULL
,
771 server
, CIFS_ASYNC_OP
| CIFS_ECHO_OP
);
773 cifs_dbg(FYI
, "Echo request failed: %d\n", rc
);
775 cifs_small_buf_release(smb
);
781 CIFSSMBLogoff(const unsigned int xid
, struct cifs_ses
*ses
)
783 LOGOFF_ANDX_REQ
*pSMB
;
786 cifs_dbg(FYI
, "In SMBLogoff for session disconnect\n");
789 * BB: do we need to check validity of ses and server? They should
790 * always be valid since we have an active reference. If not, that
791 * should probably be a BUG()
793 if (!ses
|| !ses
->server
)
796 mutex_lock(&ses
->session_mutex
);
797 if (ses
->need_reconnect
)
798 goto session_already_dead
; /* no need to send SMBlogoff if uid
799 already closed due to reconnect */
800 rc
= small_smb_init(SMB_COM_LOGOFF_ANDX
, 2, NULL
, (void **)&pSMB
);
802 mutex_unlock(&ses
->session_mutex
);
806 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
808 if (ses
->server
->sign
)
809 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
811 pSMB
->hdr
.Uid
= ses
->Suid
;
813 pSMB
->AndXCommand
= 0xFF;
814 rc
= SendReceiveNoRsp(xid
, ses
, (char *) pSMB
, 0);
815 cifs_small_buf_release(pSMB
);
816 session_already_dead
:
817 mutex_unlock(&ses
->session_mutex
);
819 /* if session dead then we do not need to do ulogoff,
820 since server closed smb session, no sense reporting
828 CIFSPOSIXDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
,
829 const char *fileName
, __u16 type
,
830 const struct nls_table
*nls_codepage
, int remap
)
832 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
833 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
834 struct unlink_psx_rq
*pRqD
;
837 int bytes_returned
= 0;
838 __u16 params
, param_offset
, offset
, byte_count
;
840 cifs_dbg(FYI
, "In POSIX delete\n");
842 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
847 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
849 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
850 PATH_MAX
, nls_codepage
, remap
);
851 name_len
++; /* trailing null */
853 } else { /* BB add path length overrun check */
854 name_len
= strnlen(fileName
, PATH_MAX
);
855 name_len
++; /* trailing null */
856 strncpy(pSMB
->FileName
, fileName
, name_len
);
859 params
= 6 + name_len
;
860 pSMB
->MaxParameterCount
= cpu_to_le16(2);
861 pSMB
->MaxDataCount
= 0; /* BB double check this with jra */
862 pSMB
->MaxSetupCount
= 0;
867 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
868 InformationLevel
) - 4;
869 offset
= param_offset
+ params
;
871 /* Setup pointer to Request Data (inode type) */
872 pRqD
= (struct unlink_psx_rq
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
873 pRqD
->type
= cpu_to_le16(type
);
874 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
875 pSMB
->DataOffset
= cpu_to_le16(offset
);
876 pSMB
->SetupCount
= 1;
878 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
879 byte_count
= 3 /* pad */ + params
+ sizeof(struct unlink_psx_rq
);
881 pSMB
->DataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
882 pSMB
->TotalDataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
883 pSMB
->ParameterCount
= cpu_to_le16(params
);
884 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
885 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_UNLINK
);
887 inc_rfc1001_len(pSMB
, byte_count
);
888 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
889 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
890 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
892 cifs_dbg(FYI
, "Posix delete returned %d\n", rc
);
893 cifs_buf_release(pSMB
);
895 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
904 CIFSSMBDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
905 struct cifs_sb_info
*cifs_sb
)
907 DELETE_FILE_REQ
*pSMB
= NULL
;
908 DELETE_FILE_RSP
*pSMBr
= NULL
;
912 int remap
= cifs_remap(cifs_sb
);
915 rc
= smb_init(SMB_COM_DELETE
, 1, tcon
, (void **) &pSMB
,
920 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
921 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->fileName
, name
,
922 PATH_MAX
, cifs_sb
->local_nls
,
924 name_len
++; /* trailing null */
926 } else { /* BB improve check for buffer overruns BB */
927 name_len
= strnlen(name
, PATH_MAX
);
928 name_len
++; /* trailing null */
929 strncpy(pSMB
->fileName
, name
, name_len
);
931 pSMB
->SearchAttributes
=
932 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
);
933 pSMB
->BufferFormat
= 0x04;
934 inc_rfc1001_len(pSMB
, name_len
+ 1);
935 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
936 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
937 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
938 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
940 cifs_dbg(FYI
, "Error in RMFile = %d\n", rc
);
942 cifs_buf_release(pSMB
);
950 CIFSSMBRmDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
951 struct cifs_sb_info
*cifs_sb
)
953 DELETE_DIRECTORY_REQ
*pSMB
= NULL
;
954 DELETE_DIRECTORY_RSP
*pSMBr
= NULL
;
958 int remap
= cifs_remap(cifs_sb
);
960 cifs_dbg(FYI
, "In CIFSSMBRmDir\n");
962 rc
= smb_init(SMB_COM_DELETE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
967 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
968 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
969 PATH_MAX
, cifs_sb
->local_nls
,
971 name_len
++; /* trailing null */
973 } else { /* BB improve check for buffer overruns BB */
974 name_len
= strnlen(name
, PATH_MAX
);
975 name_len
++; /* trailing null */
976 strncpy(pSMB
->DirName
, name
, name_len
);
979 pSMB
->BufferFormat
= 0x04;
980 inc_rfc1001_len(pSMB
, name_len
+ 1);
981 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
982 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
983 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
984 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_rmdirs
);
986 cifs_dbg(FYI
, "Error in RMDir = %d\n", rc
);
988 cifs_buf_release(pSMB
);
995 CIFSSMBMkDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
996 struct cifs_sb_info
*cifs_sb
)
999 CREATE_DIRECTORY_REQ
*pSMB
= NULL
;
1000 CREATE_DIRECTORY_RSP
*pSMBr
= NULL
;
1003 int remap
= cifs_remap(cifs_sb
);
1005 cifs_dbg(FYI
, "In CIFSSMBMkDir\n");
1007 rc
= smb_init(SMB_COM_CREATE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
1012 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1013 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
1014 PATH_MAX
, cifs_sb
->local_nls
,
1016 name_len
++; /* trailing null */
1018 } else { /* BB improve check for buffer overruns BB */
1019 name_len
= strnlen(name
, PATH_MAX
);
1020 name_len
++; /* trailing null */
1021 strncpy(pSMB
->DirName
, name
, name_len
);
1024 pSMB
->BufferFormat
= 0x04;
1025 inc_rfc1001_len(pSMB
, name_len
+ 1);
1026 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1027 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1028 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1029 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_mkdirs
);
1031 cifs_dbg(FYI
, "Error in Mkdir = %d\n", rc
);
1033 cifs_buf_release(pSMB
);
1040 CIFSPOSIXCreate(const unsigned int xid
, struct cifs_tcon
*tcon
,
1041 __u32 posix_flags
, __u64 mode
, __u16
*netfid
,
1042 FILE_UNIX_BASIC_INFO
*pRetData
, __u32
*pOplock
,
1043 const char *name
, const struct nls_table
*nls_codepage
,
1046 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
1047 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
1050 int bytes_returned
= 0;
1051 __u16 params
, param_offset
, offset
, byte_count
, count
;
1052 OPEN_PSX_REQ
*pdata
;
1053 OPEN_PSX_RSP
*psx_rsp
;
1055 cifs_dbg(FYI
, "In POSIX Create\n");
1057 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1062 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1064 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, name
,
1065 PATH_MAX
, nls_codepage
, remap
);
1066 name_len
++; /* trailing null */
1068 } else { /* BB improve the check for buffer overruns BB */
1069 name_len
= strnlen(name
, PATH_MAX
);
1070 name_len
++; /* trailing null */
1071 strncpy(pSMB
->FileName
, name
, name_len
);
1074 params
= 6 + name_len
;
1075 count
= sizeof(OPEN_PSX_REQ
);
1076 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1077 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* large enough */
1078 pSMB
->MaxSetupCount
= 0;
1082 pSMB
->Reserved2
= 0;
1083 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
1084 InformationLevel
) - 4;
1085 offset
= param_offset
+ params
;
1086 pdata
= (OPEN_PSX_REQ
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
1087 pdata
->Level
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
1088 pdata
->Permissions
= cpu_to_le64(mode
);
1089 pdata
->PosixOpenFlags
= cpu_to_le32(posix_flags
);
1090 pdata
->OpenFlags
= cpu_to_le32(*pOplock
);
1091 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
1092 pSMB
->DataOffset
= cpu_to_le16(offset
);
1093 pSMB
->SetupCount
= 1;
1094 pSMB
->Reserved3
= 0;
1095 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
1096 byte_count
= 3 /* pad */ + params
+ count
;
1098 pSMB
->DataCount
= cpu_to_le16(count
);
1099 pSMB
->ParameterCount
= cpu_to_le16(params
);
1100 pSMB
->TotalDataCount
= pSMB
->DataCount
;
1101 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1102 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_OPEN
);
1103 pSMB
->Reserved4
= 0;
1104 inc_rfc1001_len(pSMB
, byte_count
);
1105 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1106 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1107 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1109 cifs_dbg(FYI
, "Posix create returned %d\n", rc
);
1110 goto psx_create_err
;
1113 cifs_dbg(FYI
, "copying inode info\n");
1114 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
1116 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)) {
1117 rc
= -EIO
; /* bad smb */
1118 goto psx_create_err
;
1121 /* copy return information to pRetData */
1122 psx_rsp
= (OPEN_PSX_RSP
*)((char *) &pSMBr
->hdr
.Protocol
1123 + le16_to_cpu(pSMBr
->t2
.DataOffset
));
1125 *pOplock
= le16_to_cpu(psx_rsp
->OplockFlags
);
1127 *netfid
= psx_rsp
->Fid
; /* cifs fid stays in le */
1128 /* Let caller know file was created so we can set the mode. */
1129 /* Do we care about the CreateAction in any other cases? */
1130 if (cpu_to_le32(FILE_CREATE
) == psx_rsp
->CreateAction
)
1131 *pOplock
|= CIFS_CREATE_ACTION
;
1132 /* check to make sure response data is there */
1133 if (psx_rsp
->ReturnedLevel
!= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
)) {
1134 pRetData
->Type
= cpu_to_le32(-1); /* unknown */
1135 cifs_dbg(NOISY
, "unknown type\n");
1137 if (get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)
1138 + sizeof(FILE_UNIX_BASIC_INFO
)) {
1139 cifs_dbg(VFS
, "Open response data too small\n");
1140 pRetData
->Type
= cpu_to_le32(-1);
1141 goto psx_create_err
;
1143 memcpy((char *) pRetData
,
1144 (char *)psx_rsp
+ sizeof(OPEN_PSX_RSP
),
1145 sizeof(FILE_UNIX_BASIC_INFO
));
1149 cifs_buf_release(pSMB
);
1151 if (posix_flags
& SMB_O_DIRECTORY
)
1152 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixmkdirs
);
1154 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixopens
);
1162 static __u16
convert_disposition(int disposition
)
1166 switch (disposition
) {
1167 case FILE_SUPERSEDE
:
1168 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1171 ofun
= SMBOPEN_OAPPEND
;
1174 ofun
= SMBOPEN_OCREATE
;
1177 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OAPPEND
;
1179 case FILE_OVERWRITE
:
1180 ofun
= SMBOPEN_OTRUNC
;
1182 case FILE_OVERWRITE_IF
:
1183 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1186 cifs_dbg(FYI
, "unknown disposition %d\n", disposition
);
1187 ofun
= SMBOPEN_OAPPEND
; /* regular open */
1193 access_flags_to_smbopen_mode(const int access_flags
)
1195 int masked_flags
= access_flags
& (GENERIC_READ
| GENERIC_WRITE
);
1197 if (masked_flags
== GENERIC_READ
)
1198 return SMBOPEN_READ
;
1199 else if (masked_flags
== GENERIC_WRITE
)
1200 return SMBOPEN_WRITE
;
1202 /* just go for read/write */
1203 return SMBOPEN_READWRITE
;
1207 SMBLegacyOpen(const unsigned int xid
, struct cifs_tcon
*tcon
,
1208 const char *fileName
, const int openDisposition
,
1209 const int access_flags
, const int create_options
, __u16
*netfid
,
1210 int *pOplock
, FILE_ALL_INFO
*pfile_info
,
1211 const struct nls_table
*nls_codepage
, int remap
)
1214 OPENX_REQ
*pSMB
= NULL
;
1215 OPENX_RSP
*pSMBr
= NULL
;
1221 rc
= smb_init(SMB_COM_OPEN_ANDX
, 15, tcon
, (void **) &pSMB
,
1226 pSMB
->AndXCommand
= 0xFF; /* none */
1228 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1229 count
= 1; /* account for one byte pad to word boundary */
1231 cifsConvertToUTF16((__le16
*) (pSMB
->fileName
+ 1),
1232 fileName
, PATH_MAX
, nls_codepage
, remap
);
1233 name_len
++; /* trailing null */
1235 } else { /* BB improve check for buffer overruns BB */
1236 count
= 0; /* no pad */
1237 name_len
= strnlen(fileName
, PATH_MAX
);
1238 name_len
++; /* trailing null */
1239 strncpy(pSMB
->fileName
, fileName
, name_len
);
1241 if (*pOplock
& REQ_OPLOCK
)
1242 pSMB
->OpenFlags
= cpu_to_le16(REQ_OPLOCK
);
1243 else if (*pOplock
& REQ_BATCHOPLOCK
)
1244 pSMB
->OpenFlags
= cpu_to_le16(REQ_BATCHOPLOCK
);
1246 pSMB
->OpenFlags
|= cpu_to_le16(REQ_MORE_INFO
);
1247 pSMB
->Mode
= cpu_to_le16(access_flags_to_smbopen_mode(access_flags
));
1248 pSMB
->Mode
|= cpu_to_le16(0x40); /* deny none */
1249 /* set file as system file if special file such
1250 as fifo and server expecting SFU style and
1251 no Unix extensions */
1253 if (create_options
& CREATE_OPTION_SPECIAL
)
1254 pSMB
->FileAttributes
= cpu_to_le16(ATTR_SYSTEM
);
1255 else /* BB FIXME BB */
1256 pSMB
->FileAttributes
= cpu_to_le16(0/*ATTR_NORMAL*/);
1258 if (create_options
& CREATE_OPTION_READONLY
)
1259 pSMB
->FileAttributes
|= cpu_to_le16(ATTR_READONLY
);
1262 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1263 CREATE_OPTIONS_MASK); */
1264 /* BB FIXME END BB */
1266 pSMB
->Sattr
= cpu_to_le16(ATTR_HIDDEN
| ATTR_SYSTEM
| ATTR_DIRECTORY
);
1267 pSMB
->OpenFunction
= cpu_to_le16(convert_disposition(openDisposition
));
1269 inc_rfc1001_len(pSMB
, count
);
1271 pSMB
->ByteCount
= cpu_to_le16(count
);
1272 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1273 (struct smb_hdr
*)pSMBr
, &bytes_returned
, 0);
1274 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1276 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1278 /* BB verify if wct == 15 */
1280 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1282 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
1283 /* Let caller know file was created so we can set the mode. */
1284 /* Do we care about the CreateAction in any other cases? */
1286 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1287 *pOplock |= CIFS_CREATE_ACTION; */
1291 pfile_info
->CreationTime
= 0; /* BB convert CreateTime*/
1292 pfile_info
->LastAccessTime
= 0; /* BB fixme */
1293 pfile_info
->LastWriteTime
= 0; /* BB fixme */
1294 pfile_info
->ChangeTime
= 0; /* BB fixme */
1295 pfile_info
->Attributes
=
1296 cpu_to_le32(le16_to_cpu(pSMBr
->FileAttributes
));
1297 /* the file_info buf is endian converted by caller */
1298 pfile_info
->AllocationSize
=
1299 cpu_to_le64(le32_to_cpu(pSMBr
->EndOfFile
));
1300 pfile_info
->EndOfFile
= pfile_info
->AllocationSize
;
1301 pfile_info
->NumberOfLinks
= cpu_to_le32(1);
1302 pfile_info
->DeletePending
= 0;
1306 cifs_buf_release(pSMB
);
1313 CIFS_open(const unsigned int xid
, struct cifs_open_parms
*oparms
, int *oplock
,
1317 OPEN_REQ
*req
= NULL
;
1318 OPEN_RSP
*rsp
= NULL
;
1322 struct cifs_sb_info
*cifs_sb
= oparms
->cifs_sb
;
1323 struct cifs_tcon
*tcon
= oparms
->tcon
;
1324 int remap
= cifs_remap(cifs_sb
);
1325 const struct nls_table
*nls
= cifs_sb
->local_nls
;
1326 int create_options
= oparms
->create_options
;
1327 int desired_access
= oparms
->desired_access
;
1328 int disposition
= oparms
->disposition
;
1329 const char *path
= oparms
->path
;
1332 rc
= smb_init(SMB_COM_NT_CREATE_ANDX
, 24, tcon
, (void **)&req
,
1337 /* no commands go after this */
1338 req
->AndXCommand
= 0xFF;
1340 if (req
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1341 /* account for one byte pad to word boundary */
1343 name_len
= cifsConvertToUTF16((__le16
*)(req
->fileName
+ 1),
1344 path
, PATH_MAX
, nls
, remap
);
1348 req
->NameLength
= cpu_to_le16(name_len
);
1350 /* BB improve check for buffer overruns BB */
1353 name_len
= strnlen(path
, PATH_MAX
);
1356 req
->NameLength
= cpu_to_le16(name_len
);
1357 strncpy(req
->fileName
, path
, name_len
);
1360 if (*oplock
& REQ_OPLOCK
)
1361 req
->OpenFlags
= cpu_to_le32(REQ_OPLOCK
);
1362 else if (*oplock
& REQ_BATCHOPLOCK
)
1363 req
->OpenFlags
= cpu_to_le32(REQ_BATCHOPLOCK
);
1365 req
->DesiredAccess
= cpu_to_le32(desired_access
);
1366 req
->AllocationSize
= 0;
1369 * Set file as system file if special file such as fifo and server
1370 * expecting SFU style and no Unix extensions.
1372 if (create_options
& CREATE_OPTION_SPECIAL
)
1373 req
->FileAttributes
= cpu_to_le32(ATTR_SYSTEM
);
1375 req
->FileAttributes
= cpu_to_le32(ATTR_NORMAL
);
1378 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1379 * sensitive checks for other servers such as Samba.
1381 if (tcon
->ses
->capabilities
& CAP_UNIX
)
1382 req
->FileAttributes
|= cpu_to_le32(ATTR_POSIX_SEMANTICS
);
1384 if (create_options
& CREATE_OPTION_READONLY
)
1385 req
->FileAttributes
|= cpu_to_le32(ATTR_READONLY
);
1387 req
->ShareAccess
= cpu_to_le32(FILE_SHARE_ALL
);
1388 req
->CreateDisposition
= cpu_to_le32(disposition
);
1389 req
->CreateOptions
= cpu_to_le32(create_options
& CREATE_OPTIONS_MASK
);
1391 /* BB Expirement with various impersonation levels and verify */
1392 req
->ImpersonationLevel
= cpu_to_le32(SECURITY_IMPERSONATION
);
1393 req
->SecurityFlags
= SECURITY_CONTEXT_TRACKING
|SECURITY_EFFECTIVE_ONLY
;
1396 inc_rfc1001_len(req
, count
);
1398 req
->ByteCount
= cpu_to_le16(count
);
1399 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*)req
,
1400 (struct smb_hdr
*)rsp
, &bytes_returned
, 0);
1401 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1403 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1404 cifs_buf_release(req
);
1410 /* 1 byte no need to le_to_cpu */
1411 *oplock
= rsp
->OplockLevel
;
1412 /* cifs fid stays in le */
1413 oparms
->fid
->netfid
= rsp
->Fid
;
1415 /* Let caller know file was created so we can set the mode. */
1416 /* Do we care about the CreateAction in any other cases? */
1417 if (cpu_to_le32(FILE_CREATE
) == rsp
->CreateAction
)
1418 *oplock
|= CIFS_CREATE_ACTION
;
1421 /* copy from CreationTime to Attributes */
1422 memcpy((char *)buf
, (char *)&rsp
->CreationTime
, 36);
1423 /* the file_info buf is endian converted by caller */
1424 buf
->AllocationSize
= rsp
->AllocationSize
;
1425 buf
->EndOfFile
= rsp
->EndOfFile
;
1426 buf
->NumberOfLinks
= cpu_to_le32(1);
1427 buf
->DeletePending
= 0;
1430 cifs_buf_release(req
);
1435 * Discard any remaining data in the current SMB. To do this, we borrow the
1439 cifs_discard_remaining_data(struct TCP_Server_Info
*server
)
1441 unsigned int rfclen
= server
->pdu_size
;
1442 int remaining
= rfclen
+ server
->vals
->header_preamble_size
-
1445 while (remaining
> 0) {
1448 length
= cifs_read_from_socket(server
, server
->bigbuf
,
1449 min_t(unsigned int, remaining
,
1450 CIFSMaxBufSize
+ MAX_HEADER_SIZE(server
)));
1453 server
->total_read
+= length
;
1454 remaining
-= length
;
1461 cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1464 struct cifs_readdata
*rdata
= mid
->callback_data
;
1466 length
= cifs_discard_remaining_data(server
);
1467 dequeue_mid(mid
, rdata
->result
);
1468 mid
->resp_buf
= server
->smallbuf
;
1469 server
->smallbuf
= NULL
;
1474 cifs_readv_receive(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1477 unsigned int data_offset
, data_len
;
1478 struct cifs_readdata
*rdata
= mid
->callback_data
;
1479 char *buf
= server
->smallbuf
;
1480 unsigned int buflen
= server
->pdu_size
+
1481 server
->vals
->header_preamble_size
;
1482 bool use_rdma_mr
= false;
1484 cifs_dbg(FYI
, "%s: mid=%llu offset=%llu bytes=%u\n",
1485 __func__
, mid
->mid
, rdata
->offset
, rdata
->bytes
);
1488 * read the rest of READ_RSP header (sans Data array), or whatever we
1489 * can if there's not enough data. At this point, we've read down to
1492 len
= min_t(unsigned int, buflen
, server
->vals
->read_rsp_size
) -
1493 HEADER_SIZE(server
) + 1;
1495 length
= cifs_read_from_socket(server
,
1496 buf
+ HEADER_SIZE(server
) - 1, len
);
1499 server
->total_read
+= length
;
1501 if (server
->ops
->is_session_expired
&&
1502 server
->ops
->is_session_expired(buf
)) {
1503 cifs_reconnect(server
);
1504 wake_up(&server
->response_q
);
1508 if (server
->ops
->is_status_pending
&&
1509 server
->ops
->is_status_pending(buf
, server
, 0)) {
1510 cifs_discard_remaining_data(server
);
1514 /* Was the SMB read successful? */
1515 rdata
->result
= server
->ops
->map_error(buf
, false);
1516 if (rdata
->result
!= 0) {
1517 cifs_dbg(FYI
, "%s: server returned error %d\n",
1518 __func__
, rdata
->result
);
1519 return cifs_readv_discard(server
, mid
);
1522 /* Is there enough to get to the rest of the READ_RSP header? */
1523 if (server
->total_read
< server
->vals
->read_rsp_size
) {
1524 cifs_dbg(FYI
, "%s: server returned short header. got=%u expected=%zu\n",
1525 __func__
, server
->total_read
,
1526 server
->vals
->read_rsp_size
);
1527 rdata
->result
= -EIO
;
1528 return cifs_readv_discard(server
, mid
);
1531 data_offset
= server
->ops
->read_data_offset(buf
) +
1532 server
->vals
->header_preamble_size
;
1533 if (data_offset
< server
->total_read
) {
1535 * win2k8 sometimes sends an offset of 0 when the read
1536 * is beyond the EOF. Treat it as if the data starts just after
1539 cifs_dbg(FYI
, "%s: data offset (%u) inside read response header\n",
1540 __func__
, data_offset
);
1541 data_offset
= server
->total_read
;
1542 } else if (data_offset
> MAX_CIFS_SMALL_BUFFER_SIZE
) {
1543 /* data_offset is beyond the end of smallbuf */
1544 cifs_dbg(FYI
, "%s: data offset (%u) beyond end of smallbuf\n",
1545 __func__
, data_offset
);
1546 rdata
->result
= -EIO
;
1547 return cifs_readv_discard(server
, mid
);
1550 cifs_dbg(FYI
, "%s: total_read=%u data_offset=%u\n",
1551 __func__
, server
->total_read
, data_offset
);
1553 len
= data_offset
- server
->total_read
;
1555 /* read any junk before data into the rest of smallbuf */
1556 length
= cifs_read_from_socket(server
,
1557 buf
+ server
->total_read
, len
);
1560 server
->total_read
+= length
;
1563 /* set up first iov for signature check */
1564 rdata
->iov
[0].iov_base
= buf
;
1565 rdata
->iov
[0].iov_len
= 4;
1566 rdata
->iov
[1].iov_base
= buf
+ 4;
1567 rdata
->iov
[1].iov_len
= server
->total_read
- 4;
1568 cifs_dbg(FYI
, "0: iov_base=%p iov_len=%u\n",
1569 rdata
->iov
[0].iov_base
, server
->total_read
);
1571 /* how much data is in the response? */
1572 #ifdef CONFIG_CIFS_SMB_DIRECT
1573 use_rdma_mr
= rdata
->mr
;
1575 data_len
= server
->ops
->read_data_length(buf
, use_rdma_mr
);
1576 if (!use_rdma_mr
&& (data_offset
+ data_len
> buflen
)) {
1577 /* data_len is corrupt -- discard frame */
1578 rdata
->result
= -EIO
;
1579 return cifs_readv_discard(server
, mid
);
1582 length
= rdata
->read_into_pages(server
, rdata
, data_len
);
1586 server
->total_read
+= length
;
1588 cifs_dbg(FYI
, "total_read=%u buflen=%u remaining=%u\n",
1589 server
->total_read
, buflen
, data_len
);
1591 /* discard anything left over */
1592 if (server
->total_read
< buflen
)
1593 return cifs_readv_discard(server
, mid
);
1595 dequeue_mid(mid
, false);
1596 mid
->resp_buf
= server
->smallbuf
;
1597 server
->smallbuf
= NULL
;
1602 cifs_readv_callback(struct mid_q_entry
*mid
)
1604 struct cifs_readdata
*rdata
= mid
->callback_data
;
1605 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1606 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
1607 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1609 .rq_pages
= rdata
->pages
,
1610 .rq_offset
= rdata
->page_offset
,
1611 .rq_npages
= rdata
->nr_pages
,
1612 .rq_pagesz
= rdata
->pagesz
,
1613 .rq_tailsz
= rdata
->tailsz
};
1615 cifs_dbg(FYI
, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1616 __func__
, mid
->mid
, mid
->mid_state
, rdata
->result
,
1619 switch (mid
->mid_state
) {
1620 case MID_RESPONSE_RECEIVED
:
1621 /* result already set, check signature */
1625 rc
= cifs_verify_signature(&rqst
, server
,
1626 mid
->sequence_number
);
1628 cifs_dbg(VFS
, "SMB signature verification returned error = %d\n",
1631 /* FIXME: should this be counted toward the initiating task? */
1632 task_io_account_read(rdata
->got_bytes
);
1633 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1635 case MID_REQUEST_SUBMITTED
:
1636 case MID_RETRY_NEEDED
:
1637 rdata
->result
= -EAGAIN
;
1638 if (server
->sign
&& rdata
->got_bytes
)
1639 /* reset bytes number since we can not check a sign */
1640 rdata
->got_bytes
= 0;
1641 /* FIXME: should this be counted toward the initiating task? */
1642 task_io_account_read(rdata
->got_bytes
);
1643 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1646 rdata
->result
= -EIO
;
1649 queue_work(cifsiod_wq
, &rdata
->work
);
1650 DeleteMidQEntry(mid
);
1651 add_credits(server
, 1, 0);
1654 /* cifs_async_readv - send an async write, and set up mid to handle result */
1656 cifs_async_readv(struct cifs_readdata
*rdata
)
1659 READ_REQ
*smb
= NULL
;
1661 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1662 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1665 cifs_dbg(FYI
, "%s: offset=%llu bytes=%u\n",
1666 __func__
, rdata
->offset
, rdata
->bytes
);
1668 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1671 wct
= 10; /* old style read */
1672 if ((rdata
->offset
>> 32) > 0) {
1673 /* can not handle this big offset for old */
1678 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **)&smb
);
1682 smb
->hdr
.Pid
= cpu_to_le16((__u16
)rdata
->pid
);
1683 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(rdata
->pid
>> 16));
1685 smb
->AndXCommand
= 0xFF; /* none */
1686 smb
->Fid
= rdata
->cfile
->fid
.netfid
;
1687 smb
->OffsetLow
= cpu_to_le32(rdata
->offset
& 0xFFFFFFFF);
1689 smb
->OffsetHigh
= cpu_to_le32(rdata
->offset
>> 32);
1691 smb
->MaxCount
= cpu_to_le16(rdata
->bytes
& 0xFFFF);
1692 smb
->MaxCountHigh
= cpu_to_le32(rdata
->bytes
>> 16);
1696 /* old style read */
1697 struct smb_com_readx_req
*smbr
=
1698 (struct smb_com_readx_req
*)smb
;
1699 smbr
->ByteCount
= 0;
1702 /* 4 for RFC1001 length + 1 for BCC */
1703 rdata
->iov
[0].iov_base
= smb
;
1704 rdata
->iov
[0].iov_len
= 4;
1705 rdata
->iov
[1].iov_base
= (char *)smb
+ 4;
1706 rdata
->iov
[1].iov_len
= get_rfc1002_length(smb
);
1708 kref_get(&rdata
->refcount
);
1709 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, cifs_readv_receive
,
1710 cifs_readv_callback
, NULL
, rdata
, 0);
1713 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1715 kref_put(&rdata
->refcount
, cifs_readdata_release
);
1717 cifs_small_buf_release(smb
);
1722 CIFSSMBRead(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1723 unsigned int *nbytes
, char **buf
, int *pbuf_type
)
1726 READ_REQ
*pSMB
= NULL
;
1727 READ_RSP
*pSMBr
= NULL
;
1728 char *pReadData
= NULL
;
1730 int resp_buf_type
= 0;
1732 struct kvec rsp_iov
;
1733 __u32 pid
= io_parms
->pid
;
1734 __u16 netfid
= io_parms
->netfid
;
1735 __u64 offset
= io_parms
->offset
;
1736 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1737 unsigned int count
= io_parms
->length
;
1739 cifs_dbg(FYI
, "Reading %d bytes on fid %d\n", count
, netfid
);
1740 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1743 wct
= 10; /* old style read */
1744 if ((offset
>> 32) > 0) {
1745 /* can not handle this big offset for old */
1751 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **) &pSMB
);
1755 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1756 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1758 /* tcon and ses pointer are checked in smb_init */
1759 if (tcon
->ses
->server
== NULL
)
1760 return -ECONNABORTED
;
1762 pSMB
->AndXCommand
= 0xFF; /* none */
1764 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1766 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1768 pSMB
->Remaining
= 0;
1769 pSMB
->MaxCount
= cpu_to_le16(count
& 0xFFFF);
1770 pSMB
->MaxCountHigh
= cpu_to_le32(count
>> 16);
1772 pSMB
->ByteCount
= 0; /* no need to do le conversion since 0 */
1774 /* old style read */
1775 struct smb_com_readx_req
*pSMBW
=
1776 (struct smb_com_readx_req
*)pSMB
;
1777 pSMBW
->ByteCount
= 0;
1780 iov
[0].iov_base
= (char *)pSMB
;
1781 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
1782 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1, &resp_buf_type
,
1783 CIFS_LOG_ERROR
, &rsp_iov
);
1784 cifs_small_buf_release(pSMB
);
1785 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1786 pSMBr
= (READ_RSP
*)rsp_iov
.iov_base
;
1788 cifs_dbg(VFS
, "Send error in read = %d\n", rc
);
1790 int data_length
= le16_to_cpu(pSMBr
->DataLengthHigh
);
1791 data_length
= data_length
<< 16;
1792 data_length
+= le16_to_cpu(pSMBr
->DataLength
);
1793 *nbytes
= data_length
;
1795 /*check that DataLength would not go beyond end of SMB */
1796 if ((data_length
> CIFSMaxBufSize
)
1797 || (data_length
> count
)) {
1798 cifs_dbg(FYI
, "bad length %d for count %d\n",
1799 data_length
, count
);
1803 pReadData
= (char *) (&pSMBr
->hdr
.Protocol
) +
1804 le16_to_cpu(pSMBr
->DataOffset
);
1805 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1806 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1808 }*/ /* can not use copy_to_user when using page cache*/
1810 memcpy(*buf
, pReadData
, data_length
);
1815 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
1816 } else if (resp_buf_type
!= CIFS_NO_BUFFER
) {
1817 /* return buffer to caller to free */
1818 *buf
= rsp_iov
.iov_base
;
1819 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1820 *pbuf_type
= CIFS_SMALL_BUFFER
;
1821 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1822 *pbuf_type
= CIFS_LARGE_BUFFER
;
1823 } /* else no valid buffer on return - leave as null */
1825 /* Note: On -EAGAIN error only caller can retry on handle based calls
1826 since file handle passed in no longer valid */
1832 CIFSSMBWrite(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1833 unsigned int *nbytes
, const char *buf
)
1836 WRITE_REQ
*pSMB
= NULL
;
1837 WRITE_RSP
*pSMBr
= NULL
;
1838 int bytes_returned
, wct
;
1841 __u32 pid
= io_parms
->pid
;
1842 __u16 netfid
= io_parms
->netfid
;
1843 __u64 offset
= io_parms
->offset
;
1844 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1845 unsigned int count
= io_parms
->length
;
1849 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1850 if (tcon
->ses
== NULL
)
1851 return -ECONNABORTED
;
1853 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1857 if ((offset
>> 32) > 0) {
1858 /* can not handle big offset for old srv */
1863 rc
= smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
,
1868 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1869 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1871 /* tcon and ses pointer are checked in smb_init */
1872 if (tcon
->ses
->server
== NULL
)
1873 return -ECONNABORTED
;
1875 pSMB
->AndXCommand
= 0xFF; /* none */
1877 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1879 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1881 pSMB
->Reserved
= 0xFFFFFFFF;
1882 pSMB
->WriteMode
= 0;
1883 pSMB
->Remaining
= 0;
1885 /* Can increase buffer size if buffer is big enough in some cases ie we
1886 can send more if LARGE_WRITE_X capability returned by the server and if
1887 our buffer is big enough or if we convert to iovecs on socket writes
1888 and eliminate the copy to the CIFS buffer */
1889 if (tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
) {
1890 bytes_sent
= min_t(const unsigned int, CIFSMaxBufSize
, count
);
1892 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
)
1896 if (bytes_sent
> count
)
1899 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1901 memcpy(pSMB
->Data
, buf
, bytes_sent
);
1902 else if (count
!= 0) {
1904 cifs_buf_release(pSMB
);
1906 } /* else setting file size with write of zero bytes */
1908 byte_count
= bytes_sent
+ 1; /* pad */
1909 else /* wct == 12 */
1910 byte_count
= bytes_sent
+ 5; /* bigger pad, smaller smb hdr */
1912 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
& 0xFFFF);
1913 pSMB
->DataLengthHigh
= cpu_to_le16(bytes_sent
>> 16);
1914 inc_rfc1001_len(pSMB
, byte_count
);
1917 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1918 else { /* old style write has byte count 4 bytes earlier
1920 struct smb_com_writex_req
*pSMBW
=
1921 (struct smb_com_writex_req
*)pSMB
;
1922 pSMBW
->ByteCount
= cpu_to_le16(byte_count
);
1925 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1926 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1927 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
1929 cifs_dbg(FYI
, "Send error in write = %d\n", rc
);
1931 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
1932 *nbytes
= (*nbytes
) << 16;
1933 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
1936 * Mask off high 16 bits when bytes written as returned by the
1937 * server is greater than bytes requested by the client. Some
1938 * OS/2 servers are known to set incorrect CountHigh values.
1940 if (*nbytes
> count
)
1944 cifs_buf_release(pSMB
);
1946 /* Note: On -EAGAIN error only caller can retry on handle based calls
1947 since file handle passed in no longer valid */
1953 cifs_writedata_release(struct kref
*refcount
)
1955 struct cifs_writedata
*wdata
= container_of(refcount
,
1956 struct cifs_writedata
, refcount
);
1957 #ifdef CONFIG_CIFS_SMB_DIRECT
1959 smbd_deregister_mr(wdata
->mr
);
1965 cifsFileInfo_put(wdata
->cfile
);
1967 kvfree(wdata
->pages
);
1972 * Write failed with a retryable error. Resend the write request. It's also
1973 * possible that the page was redirtied so re-clean the page.
1976 cifs_writev_requeue(struct cifs_writedata
*wdata
)
1979 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
1980 struct TCP_Server_Info
*server
;
1981 unsigned int rest_len
;
1983 server
= tlink_tcon(wdata
->cfile
->tlink
)->ses
->server
;
1985 rest_len
= wdata
->bytes
;
1987 struct cifs_writedata
*wdata2
;
1988 unsigned int j
, nr_pages
, wsize
, tailsz
, cur_len
;
1990 wsize
= server
->ops
->wp_retry_size(inode
);
1991 if (wsize
< rest_len
) {
1992 nr_pages
= wsize
/ PAGE_SIZE
;
1997 cur_len
= nr_pages
* PAGE_SIZE
;
2000 nr_pages
= DIV_ROUND_UP(rest_len
, PAGE_SIZE
);
2002 tailsz
= rest_len
- (nr_pages
- 1) * PAGE_SIZE
;
2005 wdata2
= cifs_writedata_alloc(nr_pages
, cifs_writev_complete
);
2011 for (j
= 0; j
< nr_pages
; j
++) {
2012 wdata2
->pages
[j
] = wdata
->pages
[i
+ j
];
2013 lock_page(wdata2
->pages
[j
]);
2014 clear_page_dirty_for_io(wdata2
->pages
[j
]);
2017 wdata2
->sync_mode
= wdata
->sync_mode
;
2018 wdata2
->nr_pages
= nr_pages
;
2019 wdata2
->offset
= page_offset(wdata2
->pages
[0]);
2020 wdata2
->pagesz
= PAGE_SIZE
;
2021 wdata2
->tailsz
= tailsz
;
2022 wdata2
->bytes
= cur_len
;
2024 wdata2
->cfile
= find_writable_file(CIFS_I(inode
), false);
2025 if (!wdata2
->cfile
) {
2026 cifs_dbg(VFS
, "No writable handles for inode\n");
2030 wdata2
->pid
= wdata2
->cfile
->pid
;
2031 rc
= server
->ops
->async_writev(wdata2
, cifs_writedata_release
);
2033 for (j
= 0; j
< nr_pages
; j
++) {
2034 unlock_page(wdata2
->pages
[j
]);
2035 if (rc
!= 0 && rc
!= -EAGAIN
) {
2036 SetPageError(wdata2
->pages
[j
]);
2037 end_page_writeback(wdata2
->pages
[j
]);
2038 put_page(wdata2
->pages
[j
]);
2043 kref_put(&wdata2
->refcount
, cifs_writedata_release
);
2049 rest_len
-= cur_len
;
2051 } while (i
< wdata
->nr_pages
);
2053 mapping_set_error(inode
->i_mapping
, rc
);
2054 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2058 cifs_writev_complete(struct work_struct
*work
)
2060 struct cifs_writedata
*wdata
= container_of(work
,
2061 struct cifs_writedata
, work
);
2062 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
2065 if (wdata
->result
== 0) {
2066 spin_lock(&inode
->i_lock
);
2067 cifs_update_eof(CIFS_I(inode
), wdata
->offset
, wdata
->bytes
);
2068 spin_unlock(&inode
->i_lock
);
2069 cifs_stats_bytes_written(tlink_tcon(wdata
->cfile
->tlink
),
2071 } else if (wdata
->sync_mode
== WB_SYNC_ALL
&& wdata
->result
== -EAGAIN
)
2072 return cifs_writev_requeue(wdata
);
2074 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
2075 struct page
*page
= wdata
->pages
[i
];
2076 if (wdata
->result
== -EAGAIN
)
2077 __set_page_dirty_nobuffers(page
);
2078 else if (wdata
->result
< 0)
2080 end_page_writeback(page
);
2083 if (wdata
->result
!= -EAGAIN
)
2084 mapping_set_error(inode
->i_mapping
, wdata
->result
);
2085 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2088 struct cifs_writedata
*
2089 cifs_writedata_alloc(unsigned int nr_pages
, work_func_t complete
)
2091 struct page
**pages
=
2092 kcalloc(nr_pages
, sizeof(struct page
*), GFP_NOFS
);
2094 return cifs_writedata_direct_alloc(pages
, complete
);
2099 struct cifs_writedata
*
2100 cifs_writedata_direct_alloc(struct page
**pages
, work_func_t complete
)
2102 struct cifs_writedata
*wdata
;
2104 wdata
= kzalloc(sizeof(*wdata
), GFP_NOFS
);
2105 if (wdata
!= NULL
) {
2106 wdata
->pages
= pages
;
2107 kref_init(&wdata
->refcount
);
2108 INIT_LIST_HEAD(&wdata
->list
);
2109 init_completion(&wdata
->done
);
2110 INIT_WORK(&wdata
->work
, complete
);
2116 * Check the mid_state and signature on received buffer (if any), and queue the
2117 * workqueue completion task.
2120 cifs_writev_callback(struct mid_q_entry
*mid
)
2122 struct cifs_writedata
*wdata
= mid
->callback_data
;
2123 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2124 unsigned int written
;
2125 WRITE_RSP
*smb
= (WRITE_RSP
*)mid
->resp_buf
;
2127 switch (mid
->mid_state
) {
2128 case MID_RESPONSE_RECEIVED
:
2129 wdata
->result
= cifs_check_receive(mid
, tcon
->ses
->server
, 0);
2130 if (wdata
->result
!= 0)
2133 written
= le16_to_cpu(smb
->CountHigh
);
2135 written
+= le16_to_cpu(smb
->Count
);
2137 * Mask off high 16 bits when bytes written as returned
2138 * by the server is greater than bytes requested by the
2139 * client. OS/2 servers are known to set incorrect
2142 if (written
> wdata
->bytes
)
2145 if (written
< wdata
->bytes
)
2146 wdata
->result
= -ENOSPC
;
2148 wdata
->bytes
= written
;
2150 case MID_REQUEST_SUBMITTED
:
2151 case MID_RETRY_NEEDED
:
2152 wdata
->result
= -EAGAIN
;
2155 wdata
->result
= -EIO
;
2159 queue_work(cifsiod_wq
, &wdata
->work
);
2160 DeleteMidQEntry(mid
);
2161 add_credits(tcon
->ses
->server
, 1, 0);
2164 /* cifs_async_writev - send an async write, and set up mid to handle result */
2166 cifs_async_writev(struct cifs_writedata
*wdata
,
2167 void (*release
)(struct kref
*kref
))
2170 WRITE_REQ
*smb
= NULL
;
2172 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2174 struct smb_rqst rqst
= { };
2176 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2180 if (wdata
->offset
>> 32 > 0) {
2181 /* can not handle big offset for old srv */
2186 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **)&smb
);
2188 goto async_writev_out
;
2190 smb
->hdr
.Pid
= cpu_to_le16((__u16
)wdata
->pid
);
2191 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(wdata
->pid
>> 16));
2193 smb
->AndXCommand
= 0xFF; /* none */
2194 smb
->Fid
= wdata
->cfile
->fid
.netfid
;
2195 smb
->OffsetLow
= cpu_to_le32(wdata
->offset
& 0xFFFFFFFF);
2197 smb
->OffsetHigh
= cpu_to_le32(wdata
->offset
>> 32);
2198 smb
->Reserved
= 0xFFFFFFFF;
2203 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2205 /* 4 for RFC1001 length + 1 for BCC */
2207 iov
[0].iov_base
= smb
;
2208 iov
[1].iov_len
= get_rfc1002_length(smb
) + 1;
2209 iov
[1].iov_base
= (char *)smb
+ 4;
2213 rqst
.rq_pages
= wdata
->pages
;
2214 rqst
.rq_offset
= wdata
->page_offset
;
2215 rqst
.rq_npages
= wdata
->nr_pages
;
2216 rqst
.rq_pagesz
= wdata
->pagesz
;
2217 rqst
.rq_tailsz
= wdata
->tailsz
;
2219 cifs_dbg(FYI
, "async write at %llu %u bytes\n",
2220 wdata
->offset
, wdata
->bytes
);
2222 smb
->DataLengthLow
= cpu_to_le16(wdata
->bytes
& 0xFFFF);
2223 smb
->DataLengthHigh
= cpu_to_le16(wdata
->bytes
>> 16);
2226 inc_rfc1001_len(&smb
->hdr
, wdata
->bytes
+ 1);
2227 put_bcc(wdata
->bytes
+ 1, &smb
->hdr
);
2230 struct smb_com_writex_req
*smbw
=
2231 (struct smb_com_writex_req
*)smb
;
2232 inc_rfc1001_len(&smbw
->hdr
, wdata
->bytes
+ 5);
2233 put_bcc(wdata
->bytes
+ 5, &smbw
->hdr
);
2234 iov
[1].iov_len
+= 4; /* pad bigger by four bytes */
2237 kref_get(&wdata
->refcount
);
2238 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, NULL
,
2239 cifs_writev_callback
, NULL
, wdata
, 0);
2242 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2244 kref_put(&wdata
->refcount
, release
);
2247 cifs_small_buf_release(smb
);
2252 CIFSSMBWrite2(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
2253 unsigned int *nbytes
, struct kvec
*iov
, int n_vec
)
2256 WRITE_REQ
*pSMB
= NULL
;
2259 int resp_buf_type
= 0;
2260 __u32 pid
= io_parms
->pid
;
2261 __u16 netfid
= io_parms
->netfid
;
2262 __u64 offset
= io_parms
->offset
;
2263 struct cifs_tcon
*tcon
= io_parms
->tcon
;
2264 unsigned int count
= io_parms
->length
;
2265 struct kvec rsp_iov
;
2269 cifs_dbg(FYI
, "write2 at %lld %d bytes\n", (long long)offset
, count
);
2271 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2275 if ((offset
>> 32) > 0) {
2276 /* can not handle big offset for old srv */
2280 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
);
2284 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
2285 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
2287 /* tcon and ses pointer are checked in smb_init */
2288 if (tcon
->ses
->server
== NULL
)
2289 return -ECONNABORTED
;
2291 pSMB
->AndXCommand
= 0xFF; /* none */
2293 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
2295 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
2296 pSMB
->Reserved
= 0xFFFFFFFF;
2297 pSMB
->WriteMode
= 0;
2298 pSMB
->Remaining
= 0;
2301 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2303 pSMB
->DataLengthLow
= cpu_to_le16(count
& 0xFFFF);
2304 pSMB
->DataLengthHigh
= cpu_to_le16(count
>> 16);
2305 /* header + 1 byte pad */
2306 smb_hdr_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 1;
2308 inc_rfc1001_len(pSMB
, count
+ 1);
2309 else /* wct == 12 */
2310 inc_rfc1001_len(pSMB
, count
+ 5); /* smb data starts later */
2312 pSMB
->ByteCount
= cpu_to_le16(count
+ 1);
2313 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2314 struct smb_com_writex_req
*pSMBW
=
2315 (struct smb_com_writex_req
*)pSMB
;
2316 pSMBW
->ByteCount
= cpu_to_le16(count
+ 5);
2318 iov
[0].iov_base
= pSMB
;
2320 iov
[0].iov_len
= smb_hdr_len
+ 4;
2321 else /* wct == 12 pad bigger by four bytes */
2322 iov
[0].iov_len
= smb_hdr_len
+ 8;
2324 rc
= SendReceive2(xid
, tcon
->ses
, iov
, n_vec
+ 1, &resp_buf_type
, 0,
2326 cifs_small_buf_release(pSMB
);
2327 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2329 cifs_dbg(FYI
, "Send error Write2 = %d\n", rc
);
2330 } else if (resp_buf_type
== 0) {
2331 /* presumably this can not happen, but best to be safe */
2334 WRITE_RSP
*pSMBr
= (WRITE_RSP
*)rsp_iov
.iov_base
;
2335 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2336 *nbytes
= (*nbytes
) << 16;
2337 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2340 * Mask off high 16 bits when bytes written as returned by the
2341 * server is greater than bytes requested by the client. OS/2
2342 * servers are known to set incorrect CountHigh values.
2344 if (*nbytes
> count
)
2348 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2350 /* Note: On -EAGAIN error only caller can retry on handle based calls
2351 since file handle passed in no longer valid */
2356 int cifs_lockv(const unsigned int xid
, struct cifs_tcon
*tcon
,
2357 const __u16 netfid
, const __u8 lock_type
, const __u32 num_unlock
,
2358 const __u32 num_lock
, LOCKING_ANDX_RANGE
*buf
)
2361 LOCK_REQ
*pSMB
= NULL
;
2363 struct kvec rsp_iov
;
2367 cifs_dbg(FYI
, "cifs_lockv num lock %d num unlock %d\n",
2368 num_lock
, num_unlock
);
2370 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2375 pSMB
->NumberOfLocks
= cpu_to_le16(num_lock
);
2376 pSMB
->NumberOfUnlocks
= cpu_to_le16(num_unlock
);
2377 pSMB
->LockType
= lock_type
;
2378 pSMB
->AndXCommand
= 0xFF; /* none */
2379 pSMB
->Fid
= netfid
; /* netfid stays le */
2381 count
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2382 inc_rfc1001_len(pSMB
, count
);
2383 pSMB
->ByteCount
= cpu_to_le16(count
);
2385 iov
[0].iov_base
= (char *)pSMB
;
2386 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4 -
2387 (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2388 iov
[1].iov_base
= (char *)buf
;
2389 iov
[1].iov_len
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2391 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2392 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 2, &resp_buf_type
, CIFS_NO_RESP
,
2394 cifs_small_buf_release(pSMB
);
2396 cifs_dbg(FYI
, "Send error in cifs_lockv = %d\n", rc
);
2402 CIFSSMBLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2403 const __u16 smb_file_id
, const __u32 netpid
, const __u64 len
,
2404 const __u64 offset
, const __u32 numUnlock
,
2405 const __u32 numLock
, const __u8 lockType
,
2406 const bool waitFlag
, const __u8 oplock_level
)
2409 LOCK_REQ
*pSMB
= NULL
;
2410 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2415 cifs_dbg(FYI
, "CIFSSMBLock timeout %d numLock %d\n",
2416 (int)waitFlag
, numLock
);
2417 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2422 if (lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
2423 /* no response expected */
2424 flags
= CIFS_ASYNC_OP
| CIFS_OBREAK_OP
;
2426 } else if (waitFlag
) {
2427 flags
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2428 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
2433 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
2434 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
2435 pSMB
->LockType
= lockType
;
2436 pSMB
->OplockLevel
= oplock_level
;
2437 pSMB
->AndXCommand
= 0xFF; /* none */
2438 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
2440 if ((numLock
!= 0) || (numUnlock
!= 0)) {
2441 pSMB
->Locks
[0].Pid
= cpu_to_le16(netpid
);
2442 /* BB where to store pid high? */
2443 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
2444 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
2445 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
2446 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
2447 count
= sizeof(LOCKING_ANDX_RANGE
);
2452 inc_rfc1001_len(pSMB
, count
);
2453 pSMB
->ByteCount
= cpu_to_le16(count
);
2456 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2457 (struct smb_hdr
*) pSMB
, &bytes_returned
);
2459 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)pSMB
, flags
);
2460 cifs_small_buf_release(pSMB
);
2461 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2463 cifs_dbg(FYI
, "Send error in Lock = %d\n", rc
);
2465 /* Note: On -EAGAIN error only caller can retry on handle based calls
2466 since file handle passed in no longer valid */
2471 CIFSSMBPosixLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2472 const __u16 smb_file_id
, const __u32 netpid
,
2473 const loff_t start_offset
, const __u64 len
,
2474 struct file_lock
*pLockData
, const __u16 lock_type
,
2475 const bool waitFlag
)
2477 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2478 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2479 struct cifs_posix_lock
*parm_data
;
2482 int bytes_returned
= 0;
2483 int resp_buf_type
= 0;
2484 __u16 params
, param_offset
, offset
, byte_count
, count
;
2486 struct kvec rsp_iov
;
2488 cifs_dbg(FYI
, "Posix Lock\n");
2490 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
2495 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)pSMB
;
2498 pSMB
->MaxSetupCount
= 0;
2501 pSMB
->Reserved2
= 0;
2502 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2503 offset
= param_offset
+ params
;
2505 count
= sizeof(struct cifs_posix_lock
);
2506 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2507 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2508 pSMB
->SetupCount
= 1;
2509 pSMB
->Reserved3
= 0;
2511 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
2513 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2514 byte_count
= 3 /* pad */ + params
+ count
;
2515 pSMB
->DataCount
= cpu_to_le16(count
);
2516 pSMB
->ParameterCount
= cpu_to_le16(params
);
2517 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2518 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2519 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2520 parm_data
= (struct cifs_posix_lock
*)
2521 (((char *) &pSMB
->hdr
.Protocol
) + offset
);
2523 parm_data
->lock_type
= cpu_to_le16(lock_type
);
2525 timeout
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2526 parm_data
->lock_flags
= cpu_to_le16(1);
2527 pSMB
->Timeout
= cpu_to_le32(-1);
2531 parm_data
->pid
= cpu_to_le32(netpid
);
2532 parm_data
->start
= cpu_to_le64(start_offset
);
2533 parm_data
->length
= cpu_to_le64(len
); /* normalize negative numbers */
2535 pSMB
->DataOffset
= cpu_to_le16(offset
);
2536 pSMB
->Fid
= smb_file_id
;
2537 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_LOCK
);
2538 pSMB
->Reserved4
= 0;
2539 inc_rfc1001_len(pSMB
, byte_count
);
2540 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2542 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2543 (struct smb_hdr
*) pSMBr
, &bytes_returned
);
2545 iov
[0].iov_base
= (char *)pSMB
;
2546 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
2547 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
2548 &resp_buf_type
, timeout
, &rsp_iov
);
2549 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)rsp_iov
.iov_base
;
2551 cifs_small_buf_release(pSMB
);
2554 cifs_dbg(FYI
, "Send error in Posix Lock = %d\n", rc
);
2555 } else if (pLockData
) {
2556 /* lock structure can be returned on get */
2559 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2561 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(*parm_data
)) {
2562 rc
= -EIO
; /* bad smb */
2565 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
2566 data_count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2567 if (data_count
< sizeof(struct cifs_posix_lock
)) {
2571 parm_data
= (struct cifs_posix_lock
*)
2572 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2573 if (parm_data
->lock_type
== cpu_to_le16(CIFS_UNLCK
))
2574 pLockData
->fl_type
= F_UNLCK
;
2576 if (parm_data
->lock_type
==
2577 cpu_to_le16(CIFS_RDLCK
))
2578 pLockData
->fl_type
= F_RDLCK
;
2579 else if (parm_data
->lock_type
==
2580 cpu_to_le16(CIFS_WRLCK
))
2581 pLockData
->fl_type
= F_WRLCK
;
2583 pLockData
->fl_start
= le64_to_cpu(parm_data
->start
);
2584 pLockData
->fl_end
= pLockData
->fl_start
+
2585 le64_to_cpu(parm_data
->length
) - 1;
2586 pLockData
->fl_pid
= -le32_to_cpu(parm_data
->pid
);
2591 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2593 /* Note: On -EAGAIN error only caller can retry on handle based calls
2594 since file handle passed in no longer valid */
2601 CIFSSMBClose(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2604 CLOSE_REQ
*pSMB
= NULL
;
2605 cifs_dbg(FYI
, "In CIFSSMBClose\n");
2607 /* do not retry on dead session on close */
2608 rc
= small_smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
);
2614 pSMB
->FileID
= (__u16
) smb_file_id
;
2615 pSMB
->LastWriteTime
= 0xFFFFFFFF;
2616 pSMB
->ByteCount
= 0;
2617 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2618 cifs_small_buf_release(pSMB
);
2619 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_closes
);
2622 /* EINTR is expected when user ctl-c to kill app */
2623 cifs_dbg(VFS
, "Send error in Close = %d\n", rc
);
2627 /* Since session is dead, file will be closed on server already */
2635 CIFSSMBFlush(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2638 FLUSH_REQ
*pSMB
= NULL
;
2639 cifs_dbg(FYI
, "In CIFSSMBFlush\n");
2641 rc
= small_smb_init(SMB_COM_FLUSH
, 1, tcon
, (void **) &pSMB
);
2645 pSMB
->FileID
= (__u16
) smb_file_id
;
2646 pSMB
->ByteCount
= 0;
2647 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2648 cifs_small_buf_release(pSMB
);
2649 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_flushes
);
2651 cifs_dbg(VFS
, "Send error in Flush = %d\n", rc
);
2657 CIFSSMBRename(const unsigned int xid
, struct cifs_tcon
*tcon
,
2658 const char *from_name
, const char *to_name
,
2659 struct cifs_sb_info
*cifs_sb
)
2662 RENAME_REQ
*pSMB
= NULL
;
2663 RENAME_RSP
*pSMBr
= NULL
;
2665 int name_len
, name_len2
;
2667 int remap
= cifs_remap(cifs_sb
);
2669 cifs_dbg(FYI
, "In CIFSSMBRename\n");
2671 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
2676 pSMB
->BufferFormat
= 0x04;
2677 pSMB
->SearchAttributes
=
2678 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2681 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2682 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2683 from_name
, PATH_MAX
,
2684 cifs_sb
->local_nls
, remap
);
2685 name_len
++; /* trailing null */
2687 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2688 /* protocol requires ASCII signature byte on Unicode string */
2689 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2691 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2692 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2694 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2695 name_len2
*= 2; /* convert to bytes */
2696 } else { /* BB improve the check for buffer overruns BB */
2697 name_len
= strnlen(from_name
, PATH_MAX
);
2698 name_len
++; /* trailing null */
2699 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
2700 name_len2
= strnlen(to_name
, PATH_MAX
);
2701 name_len2
++; /* trailing null */
2702 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2703 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
2704 name_len2
++; /* trailing null */
2705 name_len2
++; /* signature byte */
2708 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2709 inc_rfc1001_len(pSMB
, count
);
2710 pSMB
->ByteCount
= cpu_to_le16(count
);
2712 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2713 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2714 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_renames
);
2716 cifs_dbg(FYI
, "Send error in rename = %d\n", rc
);
2718 cifs_buf_release(pSMB
);
2726 int CIFSSMBRenameOpenFile(const unsigned int xid
, struct cifs_tcon
*pTcon
,
2727 int netfid
, const char *target_name
,
2728 const struct nls_table
*nls_codepage
, int remap
)
2730 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2731 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2732 struct set_file_rename
*rename_info
;
2734 char dummy_string
[30];
2736 int bytes_returned
= 0;
2738 __u16 params
, param_offset
, offset
, count
, byte_count
;
2740 cifs_dbg(FYI
, "Rename to File by handle\n");
2741 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
2747 pSMB
->MaxSetupCount
= 0;
2751 pSMB
->Reserved2
= 0;
2752 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2753 offset
= param_offset
+ params
;
2755 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2756 rename_info
= (struct set_file_rename
*) data_offset
;
2757 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2758 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2759 pSMB
->SetupCount
= 1;
2760 pSMB
->Reserved3
= 0;
2761 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2762 byte_count
= 3 /* pad */ + params
;
2763 pSMB
->ParameterCount
= cpu_to_le16(params
);
2764 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2765 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2766 pSMB
->DataOffset
= cpu_to_le16(offset
);
2767 /* construct random name ".cifs_tmp<inodenum><mid>" */
2768 rename_info
->overwrite
= cpu_to_le32(1);
2769 rename_info
->root_fid
= 0;
2770 /* unicode only call */
2771 if (target_name
== NULL
) {
2772 sprintf(dummy_string
, "cifs%x", pSMB
->hdr
.Mid
);
2774 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2775 dummy_string
, 24, nls_codepage
, remap
);
2778 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2779 target_name
, PATH_MAX
, nls_codepage
,
2782 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
2783 count
= 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str
);
2784 byte_count
+= count
;
2785 pSMB
->DataCount
= cpu_to_le16(count
);
2786 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2788 pSMB
->InformationLevel
=
2789 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
2790 pSMB
->Reserved4
= 0;
2791 inc_rfc1001_len(pSMB
, byte_count
);
2792 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2793 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
2794 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2795 cifs_stats_inc(&pTcon
->stats
.cifs_stats
.num_t2renames
);
2797 cifs_dbg(FYI
, "Send error in Rename (by file handle) = %d\n",
2800 cifs_buf_release(pSMB
);
2802 /* Note: On -EAGAIN error only caller can retry on handle based calls
2803 since file handle passed in no longer valid */
2809 CIFSSMBCopy(const unsigned int xid
, struct cifs_tcon
*tcon
,
2810 const char *fromName
, const __u16 target_tid
, const char *toName
,
2811 const int flags
, const struct nls_table
*nls_codepage
, int remap
)
2814 COPY_REQ
*pSMB
= NULL
;
2815 COPY_RSP
*pSMBr
= NULL
;
2817 int name_len
, name_len2
;
2820 cifs_dbg(FYI
, "In CIFSSMBCopy\n");
2822 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
2827 pSMB
->BufferFormat
= 0x04;
2828 pSMB
->Tid2
= target_tid
;
2830 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
2832 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2833 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2834 fromName
, PATH_MAX
, nls_codepage
,
2836 name_len
++; /* trailing null */
2838 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2839 /* protocol requires ASCII signature byte on Unicode string */
2840 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2842 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2843 toName
, PATH_MAX
, nls_codepage
, remap
);
2844 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2845 name_len2
*= 2; /* convert to bytes */
2846 } else { /* BB improve the check for buffer overruns BB */
2847 name_len
= strnlen(fromName
, PATH_MAX
);
2848 name_len
++; /* trailing null */
2849 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
2850 name_len2
= strnlen(toName
, PATH_MAX
);
2851 name_len2
++; /* trailing null */
2852 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2853 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
2854 name_len2
++; /* trailing null */
2855 name_len2
++; /* signature byte */
2858 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2859 inc_rfc1001_len(pSMB
, count
);
2860 pSMB
->ByteCount
= cpu_to_le16(count
);
2862 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2863 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2865 cifs_dbg(FYI
, "Send error in copy = %d with %d files copied\n",
2866 rc
, le16_to_cpu(pSMBr
->CopyCount
));
2868 cifs_buf_release(pSMB
);
2877 CIFSUnixCreateSymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2878 const char *fromName
, const char *toName
,
2879 const struct nls_table
*nls_codepage
, int remap
)
2881 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2882 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2885 int name_len_target
;
2887 int bytes_returned
= 0;
2888 __u16 params
, param_offset
, offset
, byte_count
;
2890 cifs_dbg(FYI
, "In Symlink Unix style\n");
2892 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2897 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2899 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fromName
,
2900 /* find define for this maxpathcomponent */
2901 PATH_MAX
, nls_codepage
, remap
);
2902 name_len
++; /* trailing null */
2905 } else { /* BB improve the check for buffer overruns BB */
2906 name_len
= strnlen(fromName
, PATH_MAX
);
2907 name_len
++; /* trailing null */
2908 strncpy(pSMB
->FileName
, fromName
, name_len
);
2910 params
= 6 + name_len
;
2911 pSMB
->MaxSetupCount
= 0;
2915 pSMB
->Reserved2
= 0;
2916 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2917 InformationLevel
) - 4;
2918 offset
= param_offset
+ params
;
2920 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2921 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2923 cifsConvertToUTF16((__le16
*) data_offset
, toName
,
2924 /* find define for this maxpathcomponent */
2925 PATH_MAX
, nls_codepage
, remap
);
2926 name_len_target
++; /* trailing null */
2927 name_len_target
*= 2;
2928 } else { /* BB improve the check for buffer overruns BB */
2929 name_len_target
= strnlen(toName
, PATH_MAX
);
2930 name_len_target
++; /* trailing null */
2931 strncpy(data_offset
, toName
, name_len_target
);
2934 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2935 /* BB find exact max on data count below from sess */
2936 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2937 pSMB
->SetupCount
= 1;
2938 pSMB
->Reserved3
= 0;
2939 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2940 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2941 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2942 pSMB
->ParameterCount
= cpu_to_le16(params
);
2943 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2944 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2945 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2946 pSMB
->DataOffset
= cpu_to_le16(offset
);
2947 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
2948 pSMB
->Reserved4
= 0;
2949 inc_rfc1001_len(pSMB
, byte_count
);
2950 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2951 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2952 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2953 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_symlinks
);
2955 cifs_dbg(FYI
, "Send error in SetPathInfo create symlink = %d\n",
2958 cifs_buf_release(pSMB
);
2961 goto createSymLinkRetry
;
2967 CIFSUnixCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2968 const char *fromName
, const char *toName
,
2969 const struct nls_table
*nls_codepage
, int remap
)
2971 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2972 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2975 int name_len_target
;
2977 int bytes_returned
= 0;
2978 __u16 params
, param_offset
, offset
, byte_count
;
2980 cifs_dbg(FYI
, "In Create Hard link Unix style\n");
2981 createHardLinkRetry
:
2982 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2987 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2988 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->FileName
, toName
,
2989 PATH_MAX
, nls_codepage
, remap
);
2990 name_len
++; /* trailing null */
2993 } else { /* BB improve the check for buffer overruns BB */
2994 name_len
= strnlen(toName
, PATH_MAX
);
2995 name_len
++; /* trailing null */
2996 strncpy(pSMB
->FileName
, toName
, name_len
);
2998 params
= 6 + name_len
;
2999 pSMB
->MaxSetupCount
= 0;
3003 pSMB
->Reserved2
= 0;
3004 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3005 InformationLevel
) - 4;
3006 offset
= param_offset
+ params
;
3008 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
3009 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3011 cifsConvertToUTF16((__le16
*) data_offset
, fromName
,
3012 PATH_MAX
, nls_codepage
, remap
);
3013 name_len_target
++; /* trailing null */
3014 name_len_target
*= 2;
3015 } else { /* BB improve the check for buffer overruns BB */
3016 name_len_target
= strnlen(fromName
, PATH_MAX
);
3017 name_len_target
++; /* trailing null */
3018 strncpy(data_offset
, fromName
, name_len_target
);
3021 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3022 /* BB find exact max on data count below from sess*/
3023 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3024 pSMB
->SetupCount
= 1;
3025 pSMB
->Reserved3
= 0;
3026 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3027 byte_count
= 3 /* pad */ + params
+ name_len_target
;
3028 pSMB
->ParameterCount
= cpu_to_le16(params
);
3029 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3030 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
3031 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3032 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3033 pSMB
->DataOffset
= cpu_to_le16(offset
);
3034 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
3035 pSMB
->Reserved4
= 0;
3036 inc_rfc1001_len(pSMB
, byte_count
);
3037 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3038 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3039 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3040 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3042 cifs_dbg(FYI
, "Send error in SetPathInfo (hard link) = %d\n",
3045 cifs_buf_release(pSMB
);
3047 goto createHardLinkRetry
;
3053 CIFSCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3054 const char *from_name
, const char *to_name
,
3055 struct cifs_sb_info
*cifs_sb
)
3058 NT_RENAME_REQ
*pSMB
= NULL
;
3059 RENAME_RSP
*pSMBr
= NULL
;
3061 int name_len
, name_len2
;
3063 int remap
= cifs_remap(cifs_sb
);
3065 cifs_dbg(FYI
, "In CIFSCreateHardLink\n");
3066 winCreateHardLinkRetry
:
3068 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
3073 pSMB
->SearchAttributes
=
3074 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
3076 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
3077 pSMB
->ClusterCount
= 0;
3079 pSMB
->BufferFormat
= 0x04;
3081 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3083 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, from_name
,
3084 PATH_MAX
, cifs_sb
->local_nls
, remap
);
3085 name_len
++; /* trailing null */
3088 /* protocol specifies ASCII buffer format (0x04) for unicode */
3089 pSMB
->OldFileName
[name_len
] = 0x04;
3090 pSMB
->OldFileName
[name_len
+ 1] = 0x00; /* pad */
3092 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
3093 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
3095 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
3096 name_len2
*= 2; /* convert to bytes */
3097 } else { /* BB improve the check for buffer overruns BB */
3098 name_len
= strnlen(from_name
, PATH_MAX
);
3099 name_len
++; /* trailing null */
3100 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
3101 name_len2
= strnlen(to_name
, PATH_MAX
);
3102 name_len2
++; /* trailing null */
3103 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
3104 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
3105 name_len2
++; /* trailing null */
3106 name_len2
++; /* signature byte */
3109 count
= 1 /* string type byte */ + name_len
+ name_len2
;
3110 inc_rfc1001_len(pSMB
, count
);
3111 pSMB
->ByteCount
= cpu_to_le16(count
);
3113 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3114 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3115 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3117 cifs_dbg(FYI
, "Send error in hard link (NT rename) = %d\n", rc
);
3119 cifs_buf_release(pSMB
);
3121 goto winCreateHardLinkRetry
;
3127 CIFSSMBUnixQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3128 const unsigned char *searchName
, char **symlinkinfo
,
3129 const struct nls_table
*nls_codepage
, int remap
)
3131 /* SMB_QUERY_FILE_UNIX_LINK */
3132 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3133 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3137 __u16 params
, byte_count
;
3140 cifs_dbg(FYI
, "In QPathSymLinkInfo (Unix) for path %s\n", searchName
);
3143 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3148 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3150 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3151 searchName
, PATH_MAX
, nls_codepage
,
3153 name_len
++; /* trailing null */
3155 } else { /* BB improve the check for buffer overruns BB */
3156 name_len
= strnlen(searchName
, PATH_MAX
);
3157 name_len
++; /* trailing null */
3158 strncpy(pSMB
->FileName
, searchName
, name_len
);
3161 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3162 pSMB
->TotalDataCount
= 0;
3163 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3164 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3165 pSMB
->MaxSetupCount
= 0;
3169 pSMB
->Reserved2
= 0;
3170 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3171 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3172 pSMB
->DataCount
= 0;
3173 pSMB
->DataOffset
= 0;
3174 pSMB
->SetupCount
= 1;
3175 pSMB
->Reserved3
= 0;
3176 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3177 byte_count
= params
+ 1 /* pad */ ;
3178 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3179 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3180 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
3181 pSMB
->Reserved4
= 0;
3182 inc_rfc1001_len(pSMB
, byte_count
);
3183 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3185 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3186 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3188 cifs_dbg(FYI
, "Send error in QuerySymLinkInfo = %d\n", rc
);
3190 /* decode response */
3192 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3193 /* BB also check enough total bytes returned */
3194 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3198 u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3200 data_start
= ((char *) &pSMBr
->hdr
.Protocol
) +
3201 le16_to_cpu(pSMBr
->t2
.DataOffset
);
3203 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3208 /* BB FIXME investigate remapping reserved chars here */
3209 *symlinkinfo
= cifs_strndup_from_utf16(data_start
,
3210 count
, is_unicode
, nls_codepage
);
3215 cifs_buf_release(pSMB
);
3217 goto querySymLinkRetry
;
3222 * Recent Windows versions now create symlinks more frequently
3223 * and they use the "reparse point" mechanism below. We can of course
3224 * do symlinks nicely to Samba and other servers which support the
3225 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3226 * "MF" symlinks optionally, but for recent Windows we really need to
3227 * reenable the code below and fix the cifs_symlink callers to handle this.
3228 * In the interim this code has been moved to its own config option so
3229 * it is not compiled in by default until callers fixed up and more tested.
3232 CIFSSMBQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3233 __u16 fid
, char **symlinkinfo
,
3234 const struct nls_table
*nls_codepage
)
3238 struct smb_com_transaction_ioctl_req
*pSMB
;
3239 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3241 unsigned int sub_len
;
3243 struct reparse_symlink_data
*reparse_buf
;
3244 struct reparse_posix_data
*posix_buf
;
3245 __u32 data_offset
, data_count
;
3248 cifs_dbg(FYI
, "In Windows reparse style QueryLink for fid %u\n", fid
);
3249 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3254 pSMB
->TotalParameterCount
= 0 ;
3255 pSMB
->TotalDataCount
= 0;
3256 pSMB
->MaxParameterCount
= cpu_to_le32(2);
3257 /* BB find exact data count max from sess structure BB */
3258 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3259 pSMB
->MaxSetupCount
= 4;
3261 pSMB
->ParameterOffset
= 0;
3262 pSMB
->DataCount
= 0;
3263 pSMB
->DataOffset
= 0;
3264 pSMB
->SetupCount
= 4;
3265 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3266 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3267 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
3268 pSMB
->IsFsctl
= 1; /* FSCTL */
3269 pSMB
->IsRootFlag
= 0;
3270 pSMB
->Fid
= fid
; /* file handle always le */
3271 pSMB
->ByteCount
= 0;
3273 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3274 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3276 cifs_dbg(FYI
, "Send error in QueryReparseLinkInfo = %d\n", rc
);
3280 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3281 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3282 if (get_bcc(&pSMBr
->hdr
) < 2 || data_offset
> 512) {
3283 /* BB also check enough total bytes returned */
3284 rc
= -EIO
; /* bad smb */
3287 if (!data_count
|| (data_count
> 2048)) {
3289 cifs_dbg(FYI
, "Invalid return data count on get reparse info ioctl\n");
3292 end_of_smb
= 2 + get_bcc(&pSMBr
->hdr
) + (char *)&pSMBr
->ByteCount
;
3293 reparse_buf
= (struct reparse_symlink_data
*)
3294 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
3295 if ((char *)reparse_buf
>= end_of_smb
) {
3299 if (reparse_buf
->ReparseTag
== cpu_to_le32(IO_REPARSE_TAG_NFS
)) {
3300 cifs_dbg(FYI
, "NFS style reparse tag\n");
3301 posix_buf
= (struct reparse_posix_data
*)reparse_buf
;
3303 if (posix_buf
->InodeType
!= cpu_to_le64(NFS_SPECFILE_LNK
)) {
3304 cifs_dbg(FYI
, "unsupported file type 0x%llx\n",
3305 le64_to_cpu(posix_buf
->InodeType
));
3310 sub_len
= le16_to_cpu(reparse_buf
->ReparseDataLength
);
3311 if (posix_buf
->PathBuffer
+ sub_len
> end_of_smb
) {
3312 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3316 *symlinkinfo
= cifs_strndup_from_utf16(posix_buf
->PathBuffer
,
3317 sub_len
, is_unicode
, nls_codepage
);
3319 } else if (reparse_buf
->ReparseTag
!=
3320 cpu_to_le32(IO_REPARSE_TAG_SYMLINK
)) {
3325 /* Reparse tag is NTFS symlink */
3326 sub_start
= le16_to_cpu(reparse_buf
->SubstituteNameOffset
) +
3327 reparse_buf
->PathBuffer
;
3328 sub_len
= le16_to_cpu(reparse_buf
->SubstituteNameLength
);
3329 if (sub_start
+ sub_len
> end_of_smb
) {
3330 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3334 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3339 /* BB FIXME investigate remapping reserved chars here */
3340 *symlinkinfo
= cifs_strndup_from_utf16(sub_start
, sub_len
, is_unicode
,
3345 cifs_buf_release(pSMB
);
3348 * Note: On -EAGAIN error only caller can retry on handle based calls
3349 * since file handle passed in no longer valid.
3355 CIFSSMB_set_compression(const unsigned int xid
, struct cifs_tcon
*tcon
,
3360 struct smb_com_transaction_compr_ioctl_req
*pSMB
;
3361 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3363 cifs_dbg(FYI
, "Set compression for %u\n", fid
);
3364 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3369 pSMB
->compression_state
= cpu_to_le16(COMPRESSION_FORMAT_DEFAULT
);
3371 pSMB
->TotalParameterCount
= 0;
3372 pSMB
->TotalDataCount
= cpu_to_le32(2);
3373 pSMB
->MaxParameterCount
= 0;
3374 pSMB
->MaxDataCount
= 0;
3375 pSMB
->MaxSetupCount
= 4;
3377 pSMB
->ParameterOffset
= 0;
3378 pSMB
->DataCount
= cpu_to_le32(2);
3380 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req
,
3381 compression_state
) - 4); /* 84 */
3382 pSMB
->SetupCount
= 4;
3383 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3384 pSMB
->ParameterCount
= 0;
3385 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_SET_COMPRESSION
);
3386 pSMB
->IsFsctl
= 1; /* FSCTL */
3387 pSMB
->IsRootFlag
= 0;
3388 pSMB
->Fid
= fid
; /* file handle always le */
3389 /* 3 byte pad, followed by 2 byte compress state */
3390 pSMB
->ByteCount
= cpu_to_le16(5);
3391 inc_rfc1001_len(pSMB
, 5);
3393 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3394 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3396 cifs_dbg(FYI
, "Send error in SetCompression = %d\n", rc
);
3398 cifs_buf_release(pSMB
);
3401 * Note: On -EAGAIN error only caller can retry on handle based calls
3402 * since file handle passed in no longer valid.
3408 #ifdef CONFIG_CIFS_POSIX
3410 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3411 static void cifs_convert_ace(struct posix_acl_xattr_entry
*ace
,
3412 struct cifs_posix_ace
*cifs_ace
)
3414 /* u8 cifs fields do not need le conversion */
3415 ace
->e_perm
= cpu_to_le16(cifs_ace
->cifs_e_perm
);
3416 ace
->e_tag
= cpu_to_le16(cifs_ace
->cifs_e_tag
);
3417 ace
->e_id
= cpu_to_le32(le64_to_cpu(cifs_ace
->cifs_uid
));
3419 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3420 ace->e_perm, ace->e_tag, ace->e_id);
3426 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3427 static int cifs_copy_posix_acl(char *trgt
, char *src
, const int buflen
,
3428 const int acl_type
, const int size_of_data_area
)
3433 struct cifs_posix_ace
*pACE
;
3434 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)src
;
3435 struct posix_acl_xattr_header
*local_acl
= (void *)trgt
;
3437 if (le16_to_cpu(cifs_acl
->version
) != CIFS_ACL_VERSION
)
3440 if (acl_type
== ACL_TYPE_ACCESS
) {
3441 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3442 pACE
= &cifs_acl
->ace_array
[0];
3443 size
= sizeof(struct cifs_posix_acl
);
3444 size
+= sizeof(struct cifs_posix_ace
) * count
;
3445 /* check if we would go beyond end of SMB */
3446 if (size_of_data_area
< size
) {
3447 cifs_dbg(FYI
, "bad CIFS POSIX ACL size %d vs. %d\n",
3448 size_of_data_area
, size
);
3451 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3452 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3453 size
= sizeof(struct cifs_posix_acl
);
3454 size
+= sizeof(struct cifs_posix_ace
) * count
;
3455 /* skip past access ACEs to get to default ACEs */
3456 pACE
= &cifs_acl
->ace_array
[count
];
3457 count
= le16_to_cpu(cifs_acl
->default_entry_count
);
3458 size
+= sizeof(struct cifs_posix_ace
) * count
;
3459 /* check if we would go beyond end of SMB */
3460 if (size_of_data_area
< size
)
3467 size
= posix_acl_xattr_size(count
);
3468 if ((buflen
== 0) || (local_acl
== NULL
)) {
3469 /* used to query ACL EA size */
3470 } else if (size
> buflen
) {
3472 } else /* buffer big enough */ {
3473 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3475 local_acl
->a_version
= cpu_to_le32(POSIX_ACL_XATTR_VERSION
);
3476 for (i
= 0; i
< count
; i
++) {
3477 cifs_convert_ace(&ace
[i
], pACE
);
3484 static __u16
convert_ace_to_cifs_ace(struct cifs_posix_ace
*cifs_ace
,
3485 const struct posix_acl_xattr_entry
*local_ace
)
3487 __u16 rc
= 0; /* 0 = ACL converted ok */
3489 cifs_ace
->cifs_e_perm
= le16_to_cpu(local_ace
->e_perm
);
3490 cifs_ace
->cifs_e_tag
= le16_to_cpu(local_ace
->e_tag
);
3491 /* BB is there a better way to handle the large uid? */
3492 if (local_ace
->e_id
== cpu_to_le32(-1)) {
3493 /* Probably no need to le convert -1 on any arch but can not hurt */
3494 cifs_ace
->cifs_uid
= cpu_to_le64(-1);
3496 cifs_ace
->cifs_uid
= cpu_to_le64(le32_to_cpu(local_ace
->e_id
));
3498 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3499 ace->e_perm, ace->e_tag, ace->e_id);
3504 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3505 static __u16
ACL_to_cifs_posix(char *parm_data
, const char *pACL
,
3506 const int buflen
, const int acl_type
)
3509 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)parm_data
;
3510 struct posix_acl_xattr_header
*local_acl
= (void *)pACL
;
3511 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3515 if ((buflen
== 0) || (pACL
== NULL
) || (cifs_acl
== NULL
))
3518 count
= posix_acl_xattr_count((size_t)buflen
);
3519 cifs_dbg(FYI
, "setting acl with %d entries from buf of length %d and version of %d\n",
3520 count
, buflen
, le32_to_cpu(local_acl
->a_version
));
3521 if (le32_to_cpu(local_acl
->a_version
) != 2) {
3522 cifs_dbg(FYI
, "unknown POSIX ACL version %d\n",
3523 le32_to_cpu(local_acl
->a_version
));
3526 cifs_acl
->version
= cpu_to_le16(1);
3527 if (acl_type
== ACL_TYPE_ACCESS
) {
3528 cifs_acl
->access_entry_count
= cpu_to_le16(count
);
3529 cifs_acl
->default_entry_count
= cpu_to_le16(0xFFFF);
3530 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3531 cifs_acl
->default_entry_count
= cpu_to_le16(count
);
3532 cifs_acl
->access_entry_count
= cpu_to_le16(0xFFFF);
3534 cifs_dbg(FYI
, "unknown ACL type %d\n", acl_type
);
3537 for (i
= 0; i
< count
; i
++) {
3538 rc
= convert_ace_to_cifs_ace(&cifs_acl
->ace_array
[i
], &ace
[i
]);
3540 /* ACE not converted */
3545 rc
= (__u16
)(count
* sizeof(struct cifs_posix_ace
));
3546 rc
+= sizeof(struct cifs_posix_acl
);
3547 /* BB add check to make sure ACL does not overflow SMB */
3553 CIFSSMBGetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3554 const unsigned char *searchName
,
3555 char *acl_inf
, const int buflen
, const int acl_type
,
3556 const struct nls_table
*nls_codepage
, int remap
)
3558 /* SMB_QUERY_POSIX_ACL */
3559 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3560 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3564 __u16 params
, byte_count
;
3566 cifs_dbg(FYI
, "In GetPosixACL (Unix) for path %s\n", searchName
);
3569 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3574 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3576 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3577 searchName
, PATH_MAX
, nls_codepage
,
3579 name_len
++; /* trailing null */
3581 pSMB
->FileName
[name_len
] = 0;
3582 pSMB
->FileName
[name_len
+1] = 0;
3583 } else { /* BB improve the check for buffer overruns BB */
3584 name_len
= strnlen(searchName
, PATH_MAX
);
3585 name_len
++; /* trailing null */
3586 strncpy(pSMB
->FileName
, searchName
, name_len
);
3589 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3590 pSMB
->TotalDataCount
= 0;
3591 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3592 /* BB find exact max data count below from sess structure BB */
3593 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3594 pSMB
->MaxSetupCount
= 0;
3598 pSMB
->Reserved2
= 0;
3599 pSMB
->ParameterOffset
= cpu_to_le16(
3600 offsetof(struct smb_com_transaction2_qpi_req
,
3601 InformationLevel
) - 4);
3602 pSMB
->DataCount
= 0;
3603 pSMB
->DataOffset
= 0;
3604 pSMB
->SetupCount
= 1;
3605 pSMB
->Reserved3
= 0;
3606 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3607 byte_count
= params
+ 1 /* pad */ ;
3608 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3609 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3610 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_ACL
);
3611 pSMB
->Reserved4
= 0;
3612 inc_rfc1001_len(pSMB
, byte_count
);
3613 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3615 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3616 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3617 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3619 cifs_dbg(FYI
, "Send error in Query POSIX ACL = %d\n", rc
);
3621 /* decode response */
3623 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3624 /* BB also check enough total bytes returned */
3625 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3626 rc
= -EIO
; /* bad smb */
3628 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3629 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3630 rc
= cifs_copy_posix_acl(acl_inf
,
3631 (char *)&pSMBr
->hdr
.Protocol
+data_offset
,
3632 buflen
, acl_type
, count
);
3635 cifs_buf_release(pSMB
);
3642 CIFSSMBSetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3643 const unsigned char *fileName
,
3644 const char *local_acl
, const int buflen
,
3646 const struct nls_table
*nls_codepage
, int remap
)
3648 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3649 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3653 int bytes_returned
= 0;
3654 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
3656 cifs_dbg(FYI
, "In SetPosixACL (Unix) for path %s\n", fileName
);
3658 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3662 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3664 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
3665 PATH_MAX
, nls_codepage
, remap
);
3666 name_len
++; /* trailing null */
3668 } else { /* BB improve the check for buffer overruns BB */
3669 name_len
= strnlen(fileName
, PATH_MAX
);
3670 name_len
++; /* trailing null */
3671 strncpy(pSMB
->FileName
, fileName
, name_len
);
3673 params
= 6 + name_len
;
3674 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3675 /* BB find max SMB size from sess */
3676 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3677 pSMB
->MaxSetupCount
= 0;
3681 pSMB
->Reserved2
= 0;
3682 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3683 InformationLevel
) - 4;
3684 offset
= param_offset
+ params
;
3685 parm_data
= ((char *) &pSMB
->hdr
.Protocol
) + offset
;
3686 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3688 /* convert to on the wire format for POSIX ACL */
3689 data_count
= ACL_to_cifs_posix(parm_data
, local_acl
, buflen
, acl_type
);
3691 if (data_count
== 0) {
3693 goto setACLerrorExit
;
3695 pSMB
->DataOffset
= cpu_to_le16(offset
);
3696 pSMB
->SetupCount
= 1;
3697 pSMB
->Reserved3
= 0;
3698 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3699 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_ACL
);
3700 byte_count
= 3 /* pad */ + params
+ data_count
;
3701 pSMB
->DataCount
= cpu_to_le16(data_count
);
3702 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3703 pSMB
->ParameterCount
= cpu_to_le16(params
);
3704 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3705 pSMB
->Reserved4
= 0;
3706 inc_rfc1001_len(pSMB
, byte_count
);
3707 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3708 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3709 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3711 cifs_dbg(FYI
, "Set POSIX ACL returned %d\n", rc
);
3714 cifs_buf_release(pSMB
);
3720 /* BB fix tabs in this function FIXME BB */
3722 CIFSGetExtAttr(const unsigned int xid
, struct cifs_tcon
*tcon
,
3723 const int netfid
, __u64
*pExtAttrBits
, __u64
*pMask
)
3726 struct smb_t2_qfi_req
*pSMB
= NULL
;
3727 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3729 __u16 params
, byte_count
;
3731 cifs_dbg(FYI
, "In GetExtAttr\n");
3736 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3741 params
= 2 /* level */ + 2 /* fid */;
3742 pSMB
->t2
.TotalDataCount
= 0;
3743 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3744 /* BB find exact max data count below from sess structure BB */
3745 pSMB
->t2
.MaxDataCount
= cpu_to_le16(4000);
3746 pSMB
->t2
.MaxSetupCount
= 0;
3747 pSMB
->t2
.Reserved
= 0;
3749 pSMB
->t2
.Timeout
= 0;
3750 pSMB
->t2
.Reserved2
= 0;
3751 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3753 pSMB
->t2
.DataCount
= 0;
3754 pSMB
->t2
.DataOffset
= 0;
3755 pSMB
->t2
.SetupCount
= 1;
3756 pSMB
->t2
.Reserved3
= 0;
3757 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3758 byte_count
= params
+ 1 /* pad */ ;
3759 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3760 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3761 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_ATTR_FLAGS
);
3764 inc_rfc1001_len(pSMB
, byte_count
);
3765 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3767 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3768 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3770 cifs_dbg(FYI
, "error %d in GetExtAttr\n", rc
);
3772 /* decode response */
3773 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3774 /* BB also check enough total bytes returned */
3775 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3776 /* If rc should we check for EOPNOSUPP and
3777 disable the srvino flag? or in caller? */
3778 rc
= -EIO
; /* bad smb */
3780 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3781 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3782 struct file_chattr_info
*pfinfo
;
3783 /* BB Do we need a cast or hash here ? */
3785 cifs_dbg(FYI
, "Illegal size ret in GetExtAttr\n");
3789 pfinfo
= (struct file_chattr_info
*)
3790 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
3791 *pExtAttrBits
= le64_to_cpu(pfinfo
->mode
);
3792 *pMask
= le64_to_cpu(pfinfo
->mask
);
3796 cifs_buf_release(pSMB
);
3798 goto GetExtAttrRetry
;
3802 #endif /* CONFIG_POSIX */
3804 #ifdef CONFIG_CIFS_ACL
3806 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3807 * all NT TRANSACTS that we init here have total parm and data under about 400
3808 * bytes (to fit in small cifs buffer size), which is the case so far, it
3809 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3810 * returned setup area) and MaxParameterCount (returned parms size) must be set
3814 smb_init_nttransact(const __u16 sub_command
, const int setup_count
,
3815 const int parm_len
, struct cifs_tcon
*tcon
,
3820 struct smb_com_ntransact_req
*pSMB
;
3822 rc
= small_smb_init(SMB_COM_NT_TRANSACT
, 19 + setup_count
, tcon
,
3826 *ret_buf
= (void *)pSMB
;
3828 pSMB
->TotalParameterCount
= cpu_to_le32(parm_len
);
3829 pSMB
->TotalDataCount
= 0;
3830 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3831 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3832 pSMB
->DataCount
= pSMB
->TotalDataCount
;
3833 temp_offset
= offsetof(struct smb_com_ntransact_req
, Parms
) +
3834 (setup_count
* 2) - 4 /* for rfc1001 length itself */;
3835 pSMB
->ParameterOffset
= cpu_to_le32(temp_offset
);
3836 pSMB
->DataOffset
= cpu_to_le32(temp_offset
+ parm_len
);
3837 pSMB
->SetupCount
= setup_count
; /* no need to le convert byte fields */
3838 pSMB
->SubCommand
= cpu_to_le16(sub_command
);
3843 validate_ntransact(char *buf
, char **ppparm
, char **ppdata
,
3844 __u32
*pparmlen
, __u32
*pdatalen
)
3847 __u32 data_count
, data_offset
, parm_count
, parm_offset
;
3848 struct smb_com_ntransact_rsp
*pSMBr
;
3857 pSMBr
= (struct smb_com_ntransact_rsp
*)buf
;
3859 bcc
= get_bcc(&pSMBr
->hdr
);
3860 end_of_smb
= 2 /* sizeof byte count */ + bcc
+
3861 (char *)&pSMBr
->ByteCount
;
3863 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3864 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3865 parm_offset
= le32_to_cpu(pSMBr
->ParameterOffset
);
3866 parm_count
= le32_to_cpu(pSMBr
->ParameterCount
);
3868 *ppparm
= (char *)&pSMBr
->hdr
.Protocol
+ parm_offset
;
3869 *ppdata
= (char *)&pSMBr
->hdr
.Protocol
+ data_offset
;
3871 /* should we also check that parm and data areas do not overlap? */
3872 if (*ppparm
> end_of_smb
) {
3873 cifs_dbg(FYI
, "parms start after end of smb\n");
3875 } else if (parm_count
+ *ppparm
> end_of_smb
) {
3876 cifs_dbg(FYI
, "parm end after end of smb\n");
3878 } else if (*ppdata
> end_of_smb
) {
3879 cifs_dbg(FYI
, "data starts after end of smb\n");
3881 } else if (data_count
+ *ppdata
> end_of_smb
) {
3882 cifs_dbg(FYI
, "data %p + count %d (%p) past smb end %p start %p\n",
3883 *ppdata
, data_count
, (data_count
+ *ppdata
),
3886 } else if (parm_count
+ data_count
> bcc
) {
3887 cifs_dbg(FYI
, "parm count and data count larger than SMB\n");
3890 *pdatalen
= data_count
;
3891 *pparmlen
= parm_count
;
3895 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3897 CIFSSMBGetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3898 struct cifs_ntsd
**acl_inf
, __u32
*pbuflen
)
3902 QUERY_SEC_DESC_REQ
*pSMB
;
3904 struct kvec rsp_iov
;
3906 cifs_dbg(FYI
, "GetCifsACL\n");
3911 rc
= smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC
, 0,
3912 8 /* parm len */, tcon
, (void **) &pSMB
);
3916 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3917 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3918 pSMB
->MaxSetupCount
= 0;
3919 pSMB
->Fid
= fid
; /* file handle always le */
3920 pSMB
->AclFlags
= cpu_to_le32(CIFS_ACL_OWNER
| CIFS_ACL_GROUP
|
3922 pSMB
->ByteCount
= cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3923 inc_rfc1001_len(pSMB
, 11);
3924 iov
[0].iov_base
= (char *)pSMB
;
3925 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
3927 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovec */, &buf_type
,
3929 cifs_small_buf_release(pSMB
);
3930 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3932 cifs_dbg(FYI
, "Send error in QuerySecDesc = %d\n", rc
);
3933 } else { /* decode response */
3937 struct smb_com_ntransact_rsp
*pSMBr
;
3940 /* validate_nttransact */
3941 rc
= validate_ntransact(rsp_iov
.iov_base
, (char **)&parm
,
3942 &pdata
, &parm_len
, pbuflen
);
3945 pSMBr
= (struct smb_com_ntransact_rsp
*)rsp_iov
.iov_base
;
3947 cifs_dbg(FYI
, "smb %p parm %p data %p\n",
3948 pSMBr
, parm
, *acl_inf
);
3950 if (le32_to_cpu(pSMBr
->ParameterCount
) != 4) {
3951 rc
= -EIO
; /* bad smb */
3956 /* BB check that data area is minimum length and as big as acl_len */
3958 acl_len
= le32_to_cpu(*parm
);
3959 if (acl_len
!= *pbuflen
) {
3960 cifs_dbg(VFS
, "acl length %d does not match %d\n",
3962 if (*pbuflen
> acl_len
)
3966 /* check if buffer is big enough for the acl
3967 header followed by the smallest SID */
3968 if ((*pbuflen
< sizeof(struct cifs_ntsd
) + 8) ||
3969 (*pbuflen
>= 64 * 1024)) {
3970 cifs_dbg(VFS
, "bad acl length %d\n", *pbuflen
);
3974 *acl_inf
= kmemdup(pdata
, *pbuflen
, GFP_KERNEL
);
3975 if (*acl_inf
== NULL
) {
3982 free_rsp_buf(buf_type
, rsp_iov
.iov_base
);
3987 CIFSSMBSetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3988 struct cifs_ntsd
*pntsd
, __u32 acllen
, int aclflag
)
3990 __u16 byte_count
, param_count
, data_count
, param_offset
, data_offset
;
3992 int bytes_returned
= 0;
3993 SET_SEC_DESC_REQ
*pSMB
= NULL
;
3997 rc
= smb_init(SMB_COM_NT_TRANSACT
, 19, tcon
, (void **) &pSMB
, &pSMBr
);
4001 pSMB
->MaxSetupCount
= 0;
4005 param_offset
= offsetof(struct smb_com_transaction_ssec_req
, Fid
) - 4;
4006 data_count
= acllen
;
4007 data_offset
= param_offset
+ param_count
;
4008 byte_count
= 3 /* pad */ + param_count
;
4010 pSMB
->DataCount
= cpu_to_le32(data_count
);
4011 pSMB
->TotalDataCount
= pSMB
->DataCount
;
4012 pSMB
->MaxParameterCount
= cpu_to_le32(4);
4013 pSMB
->MaxDataCount
= cpu_to_le32(16384);
4014 pSMB
->ParameterCount
= cpu_to_le32(param_count
);
4015 pSMB
->ParameterOffset
= cpu_to_le32(param_offset
);
4016 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4017 pSMB
->DataOffset
= cpu_to_le32(data_offset
);
4018 pSMB
->SetupCount
= 0;
4019 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC
);
4020 pSMB
->ByteCount
= cpu_to_le16(byte_count
+data_count
);
4022 pSMB
->Fid
= fid
; /* file handle always le */
4023 pSMB
->Reserved2
= 0;
4024 pSMB
->AclFlags
= cpu_to_le32(aclflag
);
4026 if (pntsd
&& acllen
) {
4027 memcpy((char *)pSMBr
+ offsetof(struct smb_hdr
, Protocol
) +
4028 data_offset
, pntsd
, acllen
);
4029 inc_rfc1001_len(pSMB
, byte_count
+ data_count
);
4031 inc_rfc1001_len(pSMB
, byte_count
);
4033 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4034 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4036 cifs_dbg(FYI
, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4037 bytes_returned
, rc
);
4039 cifs_dbg(FYI
, "Set CIFS ACL returned %d\n", rc
);
4040 cifs_buf_release(pSMB
);
4043 goto setCifsAclRetry
;
4048 #endif /* CONFIG_CIFS_ACL */
4050 /* Legacy Query Path Information call for lookup to old servers such
4053 SMBQueryInformation(const unsigned int xid
, struct cifs_tcon
*tcon
,
4054 const char *search_name
, FILE_ALL_INFO
*data
,
4055 const struct nls_table
*nls_codepage
, int remap
)
4057 QUERY_INFORMATION_REQ
*pSMB
;
4058 QUERY_INFORMATION_RSP
*pSMBr
;
4063 cifs_dbg(FYI
, "In SMBQPath path %s\n", search_name
);
4065 rc
= smb_init(SMB_COM_QUERY_INFORMATION
, 0, tcon
, (void **) &pSMB
,
4070 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4072 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4073 search_name
, PATH_MAX
, nls_codepage
,
4075 name_len
++; /* trailing null */
4078 name_len
= strnlen(search_name
, PATH_MAX
);
4079 name_len
++; /* trailing null */
4080 strncpy(pSMB
->FileName
, search_name
, name_len
);
4082 pSMB
->BufferFormat
= 0x04;
4083 name_len
++; /* account for buffer type byte */
4084 inc_rfc1001_len(pSMB
, (__u16
)name_len
);
4085 pSMB
->ByteCount
= cpu_to_le16(name_len
);
4087 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4088 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4090 cifs_dbg(FYI
, "Send error in QueryInfo = %d\n", rc
);
4092 struct timespec64 ts
;
4093 __u32 time
= le32_to_cpu(pSMBr
->last_write_time
);
4095 /* decode response */
4096 /* BB FIXME - add time zone adjustment BB */
4097 memset(data
, 0, sizeof(FILE_ALL_INFO
));
4100 /* decode time fields */
4101 data
->ChangeTime
= cpu_to_le64(cifs_UnixTimeToNT(ts
));
4102 data
->LastWriteTime
= data
->ChangeTime
;
4103 data
->LastAccessTime
= 0;
4104 data
->AllocationSize
=
4105 cpu_to_le64(le32_to_cpu(pSMBr
->size
));
4106 data
->EndOfFile
= data
->AllocationSize
;
4108 cpu_to_le32(le16_to_cpu(pSMBr
->attr
));
4110 rc
= -EIO
; /* bad buffer passed in */
4112 cifs_buf_release(pSMB
);
4121 CIFSSMBQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4122 u16 netfid
, FILE_ALL_INFO
*pFindData
)
4124 struct smb_t2_qfi_req
*pSMB
= NULL
;
4125 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4128 __u16 params
, byte_count
;
4131 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4136 params
= 2 /* level */ + 2 /* fid */;
4137 pSMB
->t2
.TotalDataCount
= 0;
4138 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4139 /* BB find exact max data count below from sess structure BB */
4140 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4141 pSMB
->t2
.MaxSetupCount
= 0;
4142 pSMB
->t2
.Reserved
= 0;
4144 pSMB
->t2
.Timeout
= 0;
4145 pSMB
->t2
.Reserved2
= 0;
4146 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4148 pSMB
->t2
.DataCount
= 0;
4149 pSMB
->t2
.DataOffset
= 0;
4150 pSMB
->t2
.SetupCount
= 1;
4151 pSMB
->t2
.Reserved3
= 0;
4152 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4153 byte_count
= params
+ 1 /* pad */ ;
4154 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4155 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4156 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4159 inc_rfc1001_len(pSMB
, byte_count
);
4160 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4162 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4163 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4165 cifs_dbg(FYI
, "Send error in QFileInfo = %d", rc
);
4166 } else { /* decode response */
4167 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4169 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4171 else if (get_bcc(&pSMBr
->hdr
) < 40)
4172 rc
= -EIO
; /* bad smb */
4173 else if (pFindData
) {
4174 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4175 memcpy((char *) pFindData
,
4176 (char *) &pSMBr
->hdr
.Protocol
+
4177 data_offset
, sizeof(FILE_ALL_INFO
));
4181 cifs_buf_release(pSMB
);
4183 goto QFileInfoRetry
;
4189 CIFSSMBQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4190 const char *search_name
, FILE_ALL_INFO
*data
,
4191 int legacy
/* old style infolevel */,
4192 const struct nls_table
*nls_codepage
, int remap
)
4194 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4195 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4196 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4200 __u16 params
, byte_count
;
4202 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4204 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4209 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4211 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, search_name
,
4212 PATH_MAX
, nls_codepage
, remap
);
4213 name_len
++; /* trailing null */
4215 } else { /* BB improve the check for buffer overruns BB */
4216 name_len
= strnlen(search_name
, PATH_MAX
);
4217 name_len
++; /* trailing null */
4218 strncpy(pSMB
->FileName
, search_name
, name_len
);
4221 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4222 pSMB
->TotalDataCount
= 0;
4223 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4224 /* BB find exact max SMB PDU from sess structure BB */
4225 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4226 pSMB
->MaxSetupCount
= 0;
4230 pSMB
->Reserved2
= 0;
4231 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4232 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4233 pSMB
->DataCount
= 0;
4234 pSMB
->DataOffset
= 0;
4235 pSMB
->SetupCount
= 1;
4236 pSMB
->Reserved3
= 0;
4237 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4238 byte_count
= params
+ 1 /* pad */ ;
4239 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4240 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4242 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
4244 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4245 pSMB
->Reserved4
= 0;
4246 inc_rfc1001_len(pSMB
, byte_count
);
4247 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4249 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4250 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4252 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4253 } else { /* decode response */
4254 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4256 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4258 else if (!legacy
&& get_bcc(&pSMBr
->hdr
) < 40)
4259 rc
= -EIO
; /* bad smb */
4260 else if (legacy
&& get_bcc(&pSMBr
->hdr
) < 24)
4261 rc
= -EIO
; /* 24 or 26 expected but we do not read
4265 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4268 * On legacy responses we do not read the last field,
4269 * EAsize, fortunately since it varies by subdialect and
4270 * also note it differs on Set vs Get, ie two bytes or 4
4271 * bytes depending but we don't care here.
4274 size
= sizeof(FILE_INFO_STANDARD
);
4276 size
= sizeof(FILE_ALL_INFO
);
4277 memcpy((char *) data
, (char *) &pSMBr
->hdr
.Protocol
+
4282 cifs_buf_release(pSMB
);
4284 goto QPathInfoRetry
;
4290 CIFSSMBUnixQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4291 u16 netfid
, FILE_UNIX_BASIC_INFO
*pFindData
)
4293 struct smb_t2_qfi_req
*pSMB
= NULL
;
4294 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4297 __u16 params
, byte_count
;
4300 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4305 params
= 2 /* level */ + 2 /* fid */;
4306 pSMB
->t2
.TotalDataCount
= 0;
4307 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4308 /* BB find exact max data count below from sess structure BB */
4309 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4310 pSMB
->t2
.MaxSetupCount
= 0;
4311 pSMB
->t2
.Reserved
= 0;
4313 pSMB
->t2
.Timeout
= 0;
4314 pSMB
->t2
.Reserved2
= 0;
4315 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4317 pSMB
->t2
.DataCount
= 0;
4318 pSMB
->t2
.DataOffset
= 0;
4319 pSMB
->t2
.SetupCount
= 1;
4320 pSMB
->t2
.Reserved3
= 0;
4321 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4322 byte_count
= params
+ 1 /* pad */ ;
4323 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4324 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4325 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4328 inc_rfc1001_len(pSMB
, byte_count
);
4329 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4331 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4332 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4334 cifs_dbg(FYI
, "Send error in UnixQFileInfo = %d", rc
);
4335 } else { /* decode response */
4336 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4338 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4339 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4340 rc
= -EIO
; /* bad smb */
4342 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4343 memcpy((char *) pFindData
,
4344 (char *) &pSMBr
->hdr
.Protocol
+
4346 sizeof(FILE_UNIX_BASIC_INFO
));
4350 cifs_buf_release(pSMB
);
4352 goto UnixQFileInfoRetry
;
4358 CIFSSMBUnixQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4359 const unsigned char *searchName
,
4360 FILE_UNIX_BASIC_INFO
*pFindData
,
4361 const struct nls_table
*nls_codepage
, int remap
)
4363 /* SMB_QUERY_FILE_UNIX_BASIC */
4364 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4365 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4367 int bytes_returned
= 0;
4369 __u16 params
, byte_count
;
4371 cifs_dbg(FYI
, "In QPathInfo (Unix) the path %s\n", searchName
);
4373 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4378 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4380 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4381 PATH_MAX
, nls_codepage
, remap
);
4382 name_len
++; /* trailing null */
4384 } else { /* BB improve the check for buffer overruns BB */
4385 name_len
= strnlen(searchName
, PATH_MAX
);
4386 name_len
++; /* trailing null */
4387 strncpy(pSMB
->FileName
, searchName
, name_len
);
4390 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4391 pSMB
->TotalDataCount
= 0;
4392 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4393 /* BB find exact max SMB PDU from sess structure BB */
4394 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4395 pSMB
->MaxSetupCount
= 0;
4399 pSMB
->Reserved2
= 0;
4400 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4401 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4402 pSMB
->DataCount
= 0;
4403 pSMB
->DataOffset
= 0;
4404 pSMB
->SetupCount
= 1;
4405 pSMB
->Reserved3
= 0;
4406 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4407 byte_count
= params
+ 1 /* pad */ ;
4408 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4409 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4410 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4411 pSMB
->Reserved4
= 0;
4412 inc_rfc1001_len(pSMB
, byte_count
);
4413 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4415 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4416 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4418 cifs_dbg(FYI
, "Send error in UnixQPathInfo = %d", rc
);
4419 } else { /* decode response */
4420 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4422 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4423 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4424 rc
= -EIO
; /* bad smb */
4426 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4427 memcpy((char *) pFindData
,
4428 (char *) &pSMBr
->hdr
.Protocol
+
4430 sizeof(FILE_UNIX_BASIC_INFO
));
4433 cifs_buf_release(pSMB
);
4435 goto UnixQPathInfoRetry
;
4440 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4442 CIFSFindFirst(const unsigned int xid
, struct cifs_tcon
*tcon
,
4443 const char *searchName
, struct cifs_sb_info
*cifs_sb
,
4444 __u16
*pnetfid
, __u16 search_flags
,
4445 struct cifs_search_info
*psrch_inf
, bool msearch
)
4447 /* level 257 SMB_ */
4448 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
4449 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
4450 T2_FFIRST_RSP_PARMS
*parms
;
4452 int bytes_returned
= 0;
4453 int name_len
, remap
;
4454 __u16 params
, byte_count
;
4455 struct nls_table
*nls_codepage
;
4457 cifs_dbg(FYI
, "In FindFirst for %s\n", searchName
);
4460 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4465 nls_codepage
= cifs_sb
->local_nls
;
4466 remap
= cifs_remap(cifs_sb
);
4468 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4470 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4471 PATH_MAX
, nls_codepage
, remap
);
4472 /* We can not add the asterik earlier in case
4473 it got remapped to 0xF03A as if it were part of the
4474 directory name instead of a wildcard */
4477 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4478 pSMB
->FileName
[name_len
+1] = 0;
4479 pSMB
->FileName
[name_len
+2] = '*';
4480 pSMB
->FileName
[name_len
+3] = 0;
4481 name_len
+= 4; /* now the trailing null */
4482 /* null terminate just in case */
4483 pSMB
->FileName
[name_len
] = 0;
4484 pSMB
->FileName
[name_len
+1] = 0;
4487 } else { /* BB add check for overrun of SMB buf BB */
4488 name_len
= strnlen(searchName
, PATH_MAX
);
4489 /* BB fix here and in unicode clause above ie
4490 if (name_len > buffersize-header)
4491 free buffer exit; BB */
4492 strncpy(pSMB
->FileName
, searchName
, name_len
);
4494 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4495 pSMB
->FileName
[name_len
+1] = '*';
4496 pSMB
->FileName
[name_len
+2] = 0;
4501 params
= 12 + name_len
/* includes null */ ;
4502 pSMB
->TotalDataCount
= 0; /* no EAs */
4503 pSMB
->MaxParameterCount
= cpu_to_le16(10);
4504 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4505 pSMB
->MaxSetupCount
= 0;
4509 pSMB
->Reserved2
= 0;
4510 byte_count
= params
+ 1 /* pad */ ;
4511 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4512 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4513 pSMB
->ParameterOffset
= cpu_to_le16(
4514 offsetof(struct smb_com_transaction2_ffirst_req
, SearchAttributes
)
4516 pSMB
->DataCount
= 0;
4517 pSMB
->DataOffset
= 0;
4518 pSMB
->SetupCount
= 1; /* one byte, no need to make endian neutral */
4519 pSMB
->Reserved3
= 0;
4520 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
4521 pSMB
->SearchAttributes
=
4522 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
4524 pSMB
->SearchCount
= cpu_to_le16(CIFSMaxBufSize
/sizeof(FILE_UNIX_INFO
));
4525 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4526 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4528 /* BB what should we set StorageType to? Does it matter? BB */
4529 pSMB
->SearchStorageType
= 0;
4530 inc_rfc1001_len(pSMB
, byte_count
);
4531 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4533 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4534 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4535 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_ffirst
);
4537 if (rc
) {/* BB add logic to retry regular search if Unix search
4538 rejected unexpectedly by server */
4539 /* BB Add code to handle unsupported level rc */
4540 cifs_dbg(FYI
, "Error in FindFirst = %d\n", rc
);
4542 cifs_buf_release(pSMB
);
4544 /* BB eventually could optimize out free and realloc of buf */
4547 goto findFirstRetry
;
4548 } else { /* decode response */
4549 /* BB remember to free buffer if error BB */
4550 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4554 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4555 psrch_inf
->unicode
= true;
4557 psrch_inf
->unicode
= false;
4559 psrch_inf
->ntwrk_buf_start
= (char *)pSMBr
;
4560 psrch_inf
->smallBuf
= 0;
4561 psrch_inf
->srch_entries_start
=
4562 (char *) &pSMBr
->hdr
.Protocol
+
4563 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4564 parms
= (T2_FFIRST_RSP_PARMS
*)((char *) &pSMBr
->hdr
.Protocol
+
4565 le16_to_cpu(pSMBr
->t2
.ParameterOffset
));
4567 if (parms
->EndofSearch
)
4568 psrch_inf
->endOfSearch
= true;
4570 psrch_inf
->endOfSearch
= false;
4572 psrch_inf
->entries_in_buffer
=
4573 le16_to_cpu(parms
->SearchCount
);
4574 psrch_inf
->index_of_last_entry
= 2 /* skip . and .. */ +
4575 psrch_inf
->entries_in_buffer
;
4576 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4577 if (CIFSMaxBufSize
< lnoff
) {
4578 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4579 psrch_inf
->last_entry
= NULL
;
4583 psrch_inf
->last_entry
= psrch_inf
->srch_entries_start
+
4587 *pnetfid
= parms
->SearchHandle
;
4589 cifs_buf_release(pSMB
);
4596 int CIFSFindNext(const unsigned int xid
, struct cifs_tcon
*tcon
,
4597 __u16 searchHandle
, __u16 search_flags
,
4598 struct cifs_search_info
*psrch_inf
)
4600 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
4601 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
4602 T2_FNEXT_RSP_PARMS
*parms
;
4603 char *response_data
;
4606 unsigned int name_len
;
4607 __u16 params
, byte_count
;
4609 cifs_dbg(FYI
, "In FindNext\n");
4611 if (psrch_inf
->endOfSearch
)
4614 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4619 params
= 14; /* includes 2 bytes of null string, converted to LE below*/
4621 pSMB
->TotalDataCount
= 0; /* no EAs */
4622 pSMB
->MaxParameterCount
= cpu_to_le16(8);
4623 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4624 pSMB
->MaxSetupCount
= 0;
4628 pSMB
->Reserved2
= 0;
4629 pSMB
->ParameterOffset
= cpu_to_le16(
4630 offsetof(struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
4631 pSMB
->DataCount
= 0;
4632 pSMB
->DataOffset
= 0;
4633 pSMB
->SetupCount
= 1;
4634 pSMB
->Reserved3
= 0;
4635 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
4636 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
4638 cpu_to_le16(CIFSMaxBufSize
/ sizeof(FILE_UNIX_INFO
));
4639 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4640 pSMB
->ResumeKey
= psrch_inf
->resume_key
;
4641 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4643 name_len
= psrch_inf
->resume_name_len
;
4645 if (name_len
< PATH_MAX
) {
4646 memcpy(pSMB
->ResumeFileName
, psrch_inf
->presume_name
, name_len
);
4647 byte_count
+= name_len
;
4648 /* 14 byte parm len above enough for 2 byte null terminator */
4649 pSMB
->ResumeFileName
[name_len
] = 0;
4650 pSMB
->ResumeFileName
[name_len
+1] = 0;
4653 goto FNext2_err_exit
;
4655 byte_count
= params
+ 1 /* pad */ ;
4656 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4657 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4658 inc_rfc1001_len(pSMB
, byte_count
);
4659 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4661 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4662 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4663 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fnext
);
4666 psrch_inf
->endOfSearch
= true;
4667 cifs_buf_release(pSMB
);
4668 rc
= 0; /* search probably was closed at end of search*/
4670 cifs_dbg(FYI
, "FindNext returned = %d\n", rc
);
4671 } else { /* decode response */
4672 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4677 /* BB fixme add lock for file (srch_info) struct here */
4678 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4679 psrch_inf
->unicode
= true;
4681 psrch_inf
->unicode
= false;
4682 response_data
= (char *) &pSMBr
->hdr
.Protocol
+
4683 le16_to_cpu(pSMBr
->t2
.ParameterOffset
);
4684 parms
= (T2_FNEXT_RSP_PARMS
*)response_data
;
4685 response_data
= (char *)&pSMBr
->hdr
.Protocol
+
4686 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4687 if (psrch_inf
->smallBuf
)
4688 cifs_small_buf_release(
4689 psrch_inf
->ntwrk_buf_start
);
4691 cifs_buf_release(psrch_inf
->ntwrk_buf_start
);
4692 psrch_inf
->srch_entries_start
= response_data
;
4693 psrch_inf
->ntwrk_buf_start
= (char *)pSMB
;
4694 psrch_inf
->smallBuf
= 0;
4695 if (parms
->EndofSearch
)
4696 psrch_inf
->endOfSearch
= true;
4698 psrch_inf
->endOfSearch
= false;
4699 psrch_inf
->entries_in_buffer
=
4700 le16_to_cpu(parms
->SearchCount
);
4701 psrch_inf
->index_of_last_entry
+=
4702 psrch_inf
->entries_in_buffer
;
4703 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4704 if (CIFSMaxBufSize
< lnoff
) {
4705 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4706 psrch_inf
->last_entry
= NULL
;
4709 psrch_inf
->last_entry
=
4710 psrch_inf
->srch_entries_start
+ lnoff
;
4712 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4713 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4715 /* BB fixme add unlock here */
4720 /* BB On error, should we leave previous search buf (and count and
4721 last entry fields) intact or free the previous one? */
4723 /* Note: On -EAGAIN error only caller can retry on handle based calls
4724 since file handle passed in no longer valid */
4727 cifs_buf_release(pSMB
);
4732 CIFSFindClose(const unsigned int xid
, struct cifs_tcon
*tcon
,
4733 const __u16 searchHandle
)
4736 FINDCLOSE_REQ
*pSMB
= NULL
;
4738 cifs_dbg(FYI
, "In CIFSSMBFindClose\n");
4739 rc
= small_smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **)&pSMB
);
4741 /* no sense returning error if session restarted
4742 as file handle has been closed */
4748 pSMB
->FileID
= searchHandle
;
4749 pSMB
->ByteCount
= 0;
4750 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
4751 cifs_small_buf_release(pSMB
);
4753 cifs_dbg(VFS
, "Send error in FindClose = %d\n", rc
);
4755 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fclose
);
4757 /* Since session is dead, search handle closed on server already */
4765 CIFSGetSrvInodeNumber(const unsigned int xid
, struct cifs_tcon
*tcon
,
4766 const char *search_name
, __u64
*inode_number
,
4767 const struct nls_table
*nls_codepage
, int remap
)
4770 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4771 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4772 int name_len
, bytes_returned
;
4773 __u16 params
, byte_count
;
4775 cifs_dbg(FYI
, "In GetSrvInodeNum for %s\n", search_name
);
4779 GetInodeNumberRetry
:
4780 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4785 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4787 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4788 search_name
, PATH_MAX
, nls_codepage
,
4790 name_len
++; /* trailing null */
4792 } else { /* BB improve the check for buffer overruns BB */
4793 name_len
= strnlen(search_name
, PATH_MAX
);
4794 name_len
++; /* trailing null */
4795 strncpy(pSMB
->FileName
, search_name
, name_len
);
4798 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
4799 pSMB
->TotalDataCount
= 0;
4800 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4801 /* BB find exact max data count below from sess structure BB */
4802 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4803 pSMB
->MaxSetupCount
= 0;
4807 pSMB
->Reserved2
= 0;
4808 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4809 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4810 pSMB
->DataCount
= 0;
4811 pSMB
->DataOffset
= 0;
4812 pSMB
->SetupCount
= 1;
4813 pSMB
->Reserved3
= 0;
4814 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4815 byte_count
= params
+ 1 /* pad */ ;
4816 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4817 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4818 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO
);
4819 pSMB
->Reserved4
= 0;
4820 inc_rfc1001_len(pSMB
, byte_count
);
4821 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4823 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4824 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4826 cifs_dbg(FYI
, "error %d in QueryInternalInfo\n", rc
);
4828 /* decode response */
4829 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4830 /* BB also check enough total bytes returned */
4831 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
4832 /* If rc should we check for EOPNOSUPP and
4833 disable the srvino flag? or in caller? */
4834 rc
= -EIO
; /* bad smb */
4836 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4837 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
4838 struct file_internal_info
*pfinfo
;
4839 /* BB Do we need a cast or hash here ? */
4841 cifs_dbg(FYI
, "Illegal size ret in QryIntrnlInf\n");
4843 goto GetInodeNumOut
;
4845 pfinfo
= (struct file_internal_info
*)
4846 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
4847 *inode_number
= le64_to_cpu(pfinfo
->UniqueId
);
4851 cifs_buf_release(pSMB
);
4853 goto GetInodeNumberRetry
;
4858 CIFSGetDFSRefer(const unsigned int xid
, struct cifs_ses
*ses
,
4859 const char *search_name
, struct dfs_info3_param
**target_nodes
,
4860 unsigned int *num_of_nodes
,
4861 const struct nls_table
*nls_codepage
, int remap
)
4863 /* TRANS2_GET_DFS_REFERRAL */
4864 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
4865 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
4869 __u16 params
, byte_count
;
4871 *target_nodes
= NULL
;
4873 cifs_dbg(FYI
, "In GetDFSRefer the path %s\n", search_name
);
4874 if (ses
== NULL
|| ses
->tcon_ipc
== NULL
)
4878 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, ses
->tcon_ipc
, (void **) &pSMB
,
4883 /* server pointer checked in called function,
4884 but should never be null here anyway */
4885 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
4886 pSMB
->hdr
.Tid
= ses
->tcon_ipc
->tid
;
4887 pSMB
->hdr
.Uid
= ses
->Suid
;
4888 if (ses
->capabilities
& CAP_STATUS32
)
4889 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
4890 if (ses
->capabilities
& CAP_DFS
)
4891 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
4893 if (ses
->capabilities
& CAP_UNICODE
) {
4894 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
4896 cifsConvertToUTF16((__le16
*) pSMB
->RequestFileName
,
4897 search_name
, PATH_MAX
, nls_codepage
,
4899 name_len
++; /* trailing null */
4901 } else { /* BB improve the check for buffer overruns BB */
4902 name_len
= strnlen(search_name
, PATH_MAX
);
4903 name_len
++; /* trailing null */
4904 strncpy(pSMB
->RequestFileName
, search_name
, name_len
);
4907 if (ses
->server
->sign
)
4908 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
4910 pSMB
->hdr
.Uid
= ses
->Suid
;
4912 params
= 2 /* level */ + name_len
/*includes null */ ;
4913 pSMB
->TotalDataCount
= 0;
4914 pSMB
->DataCount
= 0;
4915 pSMB
->DataOffset
= 0;
4916 pSMB
->MaxParameterCount
= 0;
4917 /* BB find exact max SMB PDU from sess structure BB */
4918 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4919 pSMB
->MaxSetupCount
= 0;
4923 pSMB
->Reserved2
= 0;
4924 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4925 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
4926 pSMB
->SetupCount
= 1;
4927 pSMB
->Reserved3
= 0;
4928 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
4929 byte_count
= params
+ 3 /* pad */ ;
4930 pSMB
->ParameterCount
= cpu_to_le16(params
);
4931 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4932 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
4933 inc_rfc1001_len(pSMB
, byte_count
);
4934 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4936 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
4937 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4939 cifs_dbg(FYI
, "Send error in GetDFSRefer = %d\n", rc
);
4942 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4944 /* BB Also check if enough total bytes returned? */
4945 if (rc
|| get_bcc(&pSMBr
->hdr
) < 17) {
4946 rc
= -EIO
; /* bad smb */
4950 cifs_dbg(FYI
, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4951 get_bcc(&pSMBr
->hdr
), le16_to_cpu(pSMBr
->t2
.DataOffset
));
4953 /* parse returned result into more usable form */
4954 rc
= parse_dfs_referrals(&pSMBr
->dfs_data
,
4955 le16_to_cpu(pSMBr
->t2
.DataCount
),
4956 num_of_nodes
, target_nodes
, nls_codepage
,
4958 (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) != 0);
4961 cifs_buf_release(pSMB
);
4969 /* Query File System Info such as free space to old servers such as Win 9x */
4971 SMBOldQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4972 struct kstatfs
*FSData
)
4974 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4975 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4976 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4977 FILE_SYSTEM_ALLOC_INFO
*response_data
;
4979 int bytes_returned
= 0;
4980 __u16 params
, byte_count
;
4982 cifs_dbg(FYI
, "OldQFSInfo\n");
4984 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4989 params
= 2; /* level */
4990 pSMB
->TotalDataCount
= 0;
4991 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4992 pSMB
->MaxDataCount
= cpu_to_le16(1000);
4993 pSMB
->MaxSetupCount
= 0;
4997 pSMB
->Reserved2
= 0;
4998 byte_count
= params
+ 1 /* pad */ ;
4999 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5000 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5001 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5002 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5003 pSMB
->DataCount
= 0;
5004 pSMB
->DataOffset
= 0;
5005 pSMB
->SetupCount
= 1;
5006 pSMB
->Reserved3
= 0;
5007 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5008 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_ALLOCATION
);
5009 inc_rfc1001_len(pSMB
, byte_count
);
5010 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5012 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5013 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5015 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5016 } else { /* decode response */
5017 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5019 if (rc
|| get_bcc(&pSMBr
->hdr
) < 18)
5020 rc
= -EIO
; /* bad smb */
5022 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5023 cifs_dbg(FYI
, "qfsinf resp BCC: %d Offset %d\n",
5024 get_bcc(&pSMBr
->hdr
), data_offset
);
5026 response_data
= (FILE_SYSTEM_ALLOC_INFO
*)
5027 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
5029 le16_to_cpu(response_data
->BytesPerSector
) *
5030 le32_to_cpu(response_data
->
5031 SectorsPerAllocationUnit
);
5033 * much prefer larger but if server doesn't report
5034 * a valid size than 4K is a reasonable minimum
5036 if (FSData
->f_bsize
< 512)
5037 FSData
->f_bsize
= 4096;
5040 le32_to_cpu(response_data
->TotalAllocationUnits
);
5041 FSData
->f_bfree
= FSData
->f_bavail
=
5042 le32_to_cpu(response_data
->FreeAllocationUnits
);
5043 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5044 (unsigned long long)FSData
->f_blocks
,
5045 (unsigned long long)FSData
->f_bfree
,
5049 cifs_buf_release(pSMB
);
5052 goto oldQFSInfoRetry
;
5058 CIFSSMBQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5059 struct kstatfs
*FSData
)
5061 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5062 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5063 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5064 FILE_SYSTEM_INFO
*response_data
;
5066 int bytes_returned
= 0;
5067 __u16 params
, byte_count
;
5069 cifs_dbg(FYI
, "In QFSInfo\n");
5071 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5076 params
= 2; /* level */
5077 pSMB
->TotalDataCount
= 0;
5078 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5079 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5080 pSMB
->MaxSetupCount
= 0;
5084 pSMB
->Reserved2
= 0;
5085 byte_count
= params
+ 1 /* pad */ ;
5086 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5087 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5088 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5089 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5090 pSMB
->DataCount
= 0;
5091 pSMB
->DataOffset
= 0;
5092 pSMB
->SetupCount
= 1;
5093 pSMB
->Reserved3
= 0;
5094 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5095 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
5096 inc_rfc1001_len(pSMB
, byte_count
);
5097 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5099 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5100 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5102 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5103 } else { /* decode response */
5104 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5106 if (rc
|| get_bcc(&pSMBr
->hdr
) < 24)
5107 rc
= -EIO
; /* bad smb */
5109 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5113 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5116 le32_to_cpu(response_data
->BytesPerSector
) *
5117 le32_to_cpu(response_data
->
5118 SectorsPerAllocationUnit
);
5120 * much prefer larger but if server doesn't report
5121 * a valid size than 4K is a reasonable minimum
5123 if (FSData
->f_bsize
< 512)
5124 FSData
->f_bsize
= 4096;
5127 le64_to_cpu(response_data
->TotalAllocationUnits
);
5128 FSData
->f_bfree
= FSData
->f_bavail
=
5129 le64_to_cpu(response_data
->FreeAllocationUnits
);
5130 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5131 (unsigned long long)FSData
->f_blocks
,
5132 (unsigned long long)FSData
->f_bfree
,
5136 cifs_buf_release(pSMB
);
5145 CIFSSMBQFSAttributeInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5147 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5148 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5149 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5150 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
5152 int bytes_returned
= 0;
5153 __u16 params
, byte_count
;
5155 cifs_dbg(FYI
, "In QFSAttributeInfo\n");
5157 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5162 params
= 2; /* level */
5163 pSMB
->TotalDataCount
= 0;
5164 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5165 /* BB find exact max SMB PDU from sess structure BB */
5166 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5167 pSMB
->MaxSetupCount
= 0;
5171 pSMB
->Reserved2
= 0;
5172 byte_count
= params
+ 1 /* pad */ ;
5173 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5174 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5175 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5176 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5177 pSMB
->DataCount
= 0;
5178 pSMB
->DataOffset
= 0;
5179 pSMB
->SetupCount
= 1;
5180 pSMB
->Reserved3
= 0;
5181 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5182 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
5183 inc_rfc1001_len(pSMB
, byte_count
);
5184 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5186 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5187 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5189 cifs_dbg(VFS
, "Send error in QFSAttributeInfo = %d\n", rc
);
5190 } else { /* decode response */
5191 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5193 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5194 /* BB also check if enough bytes returned */
5195 rc
= -EIO
; /* bad smb */
5197 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5199 (FILE_SYSTEM_ATTRIBUTE_INFO
5200 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5202 memcpy(&tcon
->fsAttrInfo
, response_data
,
5203 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO
));
5206 cifs_buf_release(pSMB
);
5209 goto QFSAttributeRetry
;
5215 CIFSSMBQFSDeviceInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5217 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5218 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5219 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5220 FILE_SYSTEM_DEVICE_INFO
*response_data
;
5222 int bytes_returned
= 0;
5223 __u16 params
, byte_count
;
5225 cifs_dbg(FYI
, "In QFSDeviceInfo\n");
5227 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5232 params
= 2; /* level */
5233 pSMB
->TotalDataCount
= 0;
5234 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5235 /* BB find exact max SMB PDU from sess structure BB */
5236 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5237 pSMB
->MaxSetupCount
= 0;
5241 pSMB
->Reserved2
= 0;
5242 byte_count
= params
+ 1 /* pad */ ;
5243 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5244 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5245 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5246 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5248 pSMB
->DataCount
= 0;
5249 pSMB
->DataOffset
= 0;
5250 pSMB
->SetupCount
= 1;
5251 pSMB
->Reserved3
= 0;
5252 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5253 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
5254 inc_rfc1001_len(pSMB
, byte_count
);
5255 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5257 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5258 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5260 cifs_dbg(FYI
, "Send error in QFSDeviceInfo = %d\n", rc
);
5261 } else { /* decode response */
5262 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5264 if (rc
|| get_bcc(&pSMBr
->hdr
) <
5265 sizeof(FILE_SYSTEM_DEVICE_INFO
))
5266 rc
= -EIO
; /* bad smb */
5268 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5270 (FILE_SYSTEM_DEVICE_INFO
*)
5271 (((char *) &pSMBr
->hdr
.Protocol
) +
5273 memcpy(&tcon
->fsDevInfo
, response_data
,
5274 sizeof(FILE_SYSTEM_DEVICE_INFO
));
5277 cifs_buf_release(pSMB
);
5280 goto QFSDeviceRetry
;
5286 CIFSSMBQFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5288 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5289 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5290 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5291 FILE_SYSTEM_UNIX_INFO
*response_data
;
5293 int bytes_returned
= 0;
5294 __u16 params
, byte_count
;
5296 cifs_dbg(FYI
, "In QFSUnixInfo\n");
5298 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5299 (void **) &pSMB
, (void **) &pSMBr
);
5303 params
= 2; /* level */
5304 pSMB
->TotalDataCount
= 0;
5305 pSMB
->DataCount
= 0;
5306 pSMB
->DataOffset
= 0;
5307 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5308 /* BB find exact max SMB PDU from sess structure BB */
5309 pSMB
->MaxDataCount
= cpu_to_le16(100);
5310 pSMB
->MaxSetupCount
= 0;
5314 pSMB
->Reserved2
= 0;
5315 byte_count
= params
+ 1 /* pad */ ;
5316 pSMB
->ParameterCount
= cpu_to_le16(params
);
5317 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5318 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5319 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5320 pSMB
->SetupCount
= 1;
5321 pSMB
->Reserved3
= 0;
5322 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5323 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
5324 inc_rfc1001_len(pSMB
, byte_count
);
5325 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5327 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5328 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5330 cifs_dbg(VFS
, "Send error in QFSUnixInfo = %d\n", rc
);
5331 } else { /* decode response */
5332 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5334 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5335 rc
= -EIO
; /* bad smb */
5337 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5339 (FILE_SYSTEM_UNIX_INFO
5340 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5342 memcpy(&tcon
->fsUnixInfo
, response_data
,
5343 sizeof(FILE_SYSTEM_UNIX_INFO
));
5346 cifs_buf_release(pSMB
);
5356 CIFSSMBSetFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
, __u64 cap
)
5358 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5359 TRANSACTION2_SETFSI_REQ
*pSMB
= NULL
;
5360 TRANSACTION2_SETFSI_RSP
*pSMBr
= NULL
;
5362 int bytes_returned
= 0;
5363 __u16 params
, param_offset
, offset
, byte_count
;
5365 cifs_dbg(FYI
, "In SETFSUnixInfo\n");
5367 /* BB switch to small buf init to save memory */
5368 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5369 (void **) &pSMB
, (void **) &pSMBr
);
5373 params
= 4; /* 2 bytes zero followed by info level. */
5374 pSMB
->MaxSetupCount
= 0;
5378 pSMB
->Reserved2
= 0;
5379 param_offset
= offsetof(struct smb_com_transaction2_setfsi_req
, FileNum
)
5381 offset
= param_offset
+ params
;
5383 pSMB
->MaxParameterCount
= cpu_to_le16(4);
5384 /* BB find exact max SMB PDU from sess structure BB */
5385 pSMB
->MaxDataCount
= cpu_to_le16(100);
5386 pSMB
->SetupCount
= 1;
5387 pSMB
->Reserved3
= 0;
5388 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FS_INFORMATION
);
5389 byte_count
= 1 /* pad */ + params
+ 12;
5391 pSMB
->DataCount
= cpu_to_le16(12);
5392 pSMB
->ParameterCount
= cpu_to_le16(params
);
5393 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5394 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5395 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5396 pSMB
->DataOffset
= cpu_to_le16(offset
);
5400 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_CIFS_UNIX_INFO
);
5403 pSMB
->ClientUnixMajor
= cpu_to_le16(CIFS_UNIX_MAJOR_VERSION
);
5404 pSMB
->ClientUnixMinor
= cpu_to_le16(CIFS_UNIX_MINOR_VERSION
);
5405 pSMB
->ClientUnixCap
= cpu_to_le64(cap
);
5407 inc_rfc1001_len(pSMB
, byte_count
);
5408 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5410 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5411 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5413 cifs_dbg(VFS
, "Send error in SETFSUnixInfo = %d\n", rc
);
5414 } else { /* decode response */
5415 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5417 rc
= -EIO
; /* bad smb */
5419 cifs_buf_release(pSMB
);
5422 goto SETFSUnixRetry
;
5430 CIFSSMBQFSPosixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5431 struct kstatfs
*FSData
)
5433 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5434 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5435 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5436 FILE_SYSTEM_POSIX_INFO
*response_data
;
5438 int bytes_returned
= 0;
5439 __u16 params
, byte_count
;
5441 cifs_dbg(FYI
, "In QFSPosixInfo\n");
5443 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5448 params
= 2; /* level */
5449 pSMB
->TotalDataCount
= 0;
5450 pSMB
->DataCount
= 0;
5451 pSMB
->DataOffset
= 0;
5452 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5453 /* BB find exact max SMB PDU from sess structure BB */
5454 pSMB
->MaxDataCount
= cpu_to_le16(100);
5455 pSMB
->MaxSetupCount
= 0;
5459 pSMB
->Reserved2
= 0;
5460 byte_count
= params
+ 1 /* pad */ ;
5461 pSMB
->ParameterCount
= cpu_to_le16(params
);
5462 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5463 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5464 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5465 pSMB
->SetupCount
= 1;
5466 pSMB
->Reserved3
= 0;
5467 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5468 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_FS_INFO
);
5469 inc_rfc1001_len(pSMB
, byte_count
);
5470 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5472 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5473 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5475 cifs_dbg(FYI
, "Send error in QFSUnixInfo = %d\n", rc
);
5476 } else { /* decode response */
5477 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5479 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5480 rc
= -EIO
; /* bad smb */
5482 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5484 (FILE_SYSTEM_POSIX_INFO
5485 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5488 le32_to_cpu(response_data
->BlockSize
);
5490 * much prefer larger but if server doesn't report
5491 * a valid size than 4K is a reasonable minimum
5493 if (FSData
->f_bsize
< 512)
5494 FSData
->f_bsize
= 4096;
5497 le64_to_cpu(response_data
->TotalBlocks
);
5499 le64_to_cpu(response_data
->BlocksAvail
);
5500 if (response_data
->UserBlocksAvail
== cpu_to_le64(-1)) {
5501 FSData
->f_bavail
= FSData
->f_bfree
;
5504 le64_to_cpu(response_data
->UserBlocksAvail
);
5506 if (response_data
->TotalFileNodes
!= cpu_to_le64(-1))
5508 le64_to_cpu(response_data
->TotalFileNodes
);
5509 if (response_data
->FreeFileNodes
!= cpu_to_le64(-1))
5511 le64_to_cpu(response_data
->FreeFileNodes
);
5514 cifs_buf_release(pSMB
);
5524 * We can not use write of zero bytes trick to set file size due to need for
5525 * large file support. Also note that this SetPathInfo is preferred to
5526 * SetFileInfo based method in next routine which is only needed to work around
5527 * a sharing violation bugin Samba which this routine can run into.
5530 CIFSSMBSetEOF(const unsigned int xid
, struct cifs_tcon
*tcon
,
5531 const char *file_name
, __u64 size
, struct cifs_sb_info
*cifs_sb
,
5532 bool set_allocation
)
5534 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5535 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5536 struct file_end_of_file_info
*parm_data
;
5539 int bytes_returned
= 0;
5540 int remap
= cifs_remap(cifs_sb
);
5542 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
5544 cifs_dbg(FYI
, "In SetEOF\n");
5546 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5551 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5553 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5554 PATH_MAX
, cifs_sb
->local_nls
, remap
);
5555 name_len
++; /* trailing null */
5557 } else { /* BB improve the check for buffer overruns BB */
5558 name_len
= strnlen(file_name
, PATH_MAX
);
5559 name_len
++; /* trailing null */
5560 strncpy(pSMB
->FileName
, file_name
, name_len
);
5562 params
= 6 + name_len
;
5563 data_count
= sizeof(struct file_end_of_file_info
);
5564 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5565 pSMB
->MaxDataCount
= cpu_to_le16(4100);
5566 pSMB
->MaxSetupCount
= 0;
5570 pSMB
->Reserved2
= 0;
5571 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5572 InformationLevel
) - 4;
5573 offset
= param_offset
+ params
;
5574 if (set_allocation
) {
5575 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5576 pSMB
->InformationLevel
=
5577 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5579 pSMB
->InformationLevel
=
5580 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5581 } else /* Set File Size */ {
5582 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5583 pSMB
->InformationLevel
=
5584 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5586 pSMB
->InformationLevel
=
5587 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5591 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
5593 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5594 pSMB
->DataOffset
= cpu_to_le16(offset
);
5595 pSMB
->SetupCount
= 1;
5596 pSMB
->Reserved3
= 0;
5597 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5598 byte_count
= 3 /* pad */ + params
+ data_count
;
5599 pSMB
->DataCount
= cpu_to_le16(data_count
);
5600 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5601 pSMB
->ParameterCount
= cpu_to_le16(params
);
5602 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5603 pSMB
->Reserved4
= 0;
5604 inc_rfc1001_len(pSMB
, byte_count
);
5605 parm_data
->FileSize
= cpu_to_le64(size
);
5606 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5607 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5608 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5610 cifs_dbg(FYI
, "SetPathInfo (file size) returned %d\n", rc
);
5612 cifs_buf_release(pSMB
);
5621 CIFSSMBSetFileSize(const unsigned int xid
, struct cifs_tcon
*tcon
,
5622 struct cifsFileInfo
*cfile
, __u64 size
, bool set_allocation
)
5624 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5625 struct file_end_of_file_info
*parm_data
;
5627 __u16 params
, param_offset
, offset
, byte_count
, count
;
5629 cifs_dbg(FYI
, "SetFileSize (via SetFileInfo) %lld\n",
5631 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5636 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)cfile
->pid
);
5637 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(cfile
->pid
>> 16));
5640 pSMB
->MaxSetupCount
= 0;
5644 pSMB
->Reserved2
= 0;
5645 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5646 offset
= param_offset
+ params
;
5648 count
= sizeof(struct file_end_of_file_info
);
5649 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5650 /* BB find exact max SMB PDU from sess structure BB */
5651 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5652 pSMB
->SetupCount
= 1;
5653 pSMB
->Reserved3
= 0;
5654 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5655 byte_count
= 3 /* pad */ + params
+ count
;
5656 pSMB
->DataCount
= cpu_to_le16(count
);
5657 pSMB
->ParameterCount
= cpu_to_le16(params
);
5658 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5659 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5660 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5662 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
)
5664 pSMB
->DataOffset
= cpu_to_le16(offset
);
5665 parm_data
->FileSize
= cpu_to_le64(size
);
5666 pSMB
->Fid
= cfile
->fid
.netfid
;
5667 if (set_allocation
) {
5668 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5669 pSMB
->InformationLevel
=
5670 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5672 pSMB
->InformationLevel
=
5673 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5674 } else /* Set File Size */ {
5675 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5676 pSMB
->InformationLevel
=
5677 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5679 pSMB
->InformationLevel
=
5680 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5682 pSMB
->Reserved4
= 0;
5683 inc_rfc1001_len(pSMB
, byte_count
);
5684 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5685 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5686 cifs_small_buf_release(pSMB
);
5688 cifs_dbg(FYI
, "Send error in SetFileInfo (SetFileSize) = %d\n",
5692 /* Note: On -EAGAIN error only caller can retry on handle based calls
5693 since file handle passed in no longer valid */
5698 /* Some legacy servers such as NT4 require that the file times be set on
5699 an open handle, rather than by pathname - this is awkward due to
5700 potential access conflicts on the open, but it is unavoidable for these
5701 old servers since the only other choice is to go from 100 nanosecond DCE
5702 time and resort to the original setpathinfo level which takes the ancient
5703 DOS time format with 2 second granularity */
5705 CIFSSMBSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5706 const FILE_BASIC_INFO
*data
, __u16 fid
, __u32 pid_of_opener
)
5708 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5711 __u16 params
, param_offset
, offset
, byte_count
, count
;
5713 cifs_dbg(FYI
, "Set Times (via SetFileInfo)\n");
5714 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5719 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5720 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5723 pSMB
->MaxSetupCount
= 0;
5727 pSMB
->Reserved2
= 0;
5728 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5729 offset
= param_offset
+ params
;
5731 data_offset
= (char *)pSMB
+
5732 offsetof(struct smb_hdr
, Protocol
) + offset
;
5734 count
= sizeof(FILE_BASIC_INFO
);
5735 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5736 /* BB find max SMB PDU from sess */
5737 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5738 pSMB
->SetupCount
= 1;
5739 pSMB
->Reserved3
= 0;
5740 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5741 byte_count
= 3 /* pad */ + params
+ count
;
5742 pSMB
->DataCount
= cpu_to_le16(count
);
5743 pSMB
->ParameterCount
= cpu_to_le16(params
);
5744 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5745 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5746 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5747 pSMB
->DataOffset
= cpu_to_le16(offset
);
5749 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5750 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5752 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5753 pSMB
->Reserved4
= 0;
5754 inc_rfc1001_len(pSMB
, byte_count
);
5755 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5756 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5757 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5758 cifs_small_buf_release(pSMB
);
5760 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5763 /* Note: On -EAGAIN error only caller can retry on handle based calls
5764 since file handle passed in no longer valid */
5770 CIFSSMBSetFileDisposition(const unsigned int xid
, struct cifs_tcon
*tcon
,
5771 bool delete_file
, __u16 fid
, __u32 pid_of_opener
)
5773 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5776 __u16 params
, param_offset
, offset
, byte_count
, count
;
5778 cifs_dbg(FYI
, "Set File Disposition (via SetFileInfo)\n");
5779 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5784 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5785 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5788 pSMB
->MaxSetupCount
= 0;
5792 pSMB
->Reserved2
= 0;
5793 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5794 offset
= param_offset
+ params
;
5796 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5799 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5800 /* BB find max SMB PDU from sess */
5801 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5802 pSMB
->SetupCount
= 1;
5803 pSMB
->Reserved3
= 0;
5804 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5805 byte_count
= 3 /* pad */ + params
+ count
;
5806 pSMB
->DataCount
= cpu_to_le16(count
);
5807 pSMB
->ParameterCount
= cpu_to_le16(params
);
5808 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5809 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5810 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5811 pSMB
->DataOffset
= cpu_to_le16(offset
);
5813 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO
);
5814 pSMB
->Reserved4
= 0;
5815 inc_rfc1001_len(pSMB
, byte_count
);
5816 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5817 *data_offset
= delete_file
? 1 : 0;
5818 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5819 cifs_small_buf_release(pSMB
);
5821 cifs_dbg(FYI
, "Send error in SetFileDisposition = %d\n", rc
);
5827 CIFSSMBSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5828 const char *fileName
, const FILE_BASIC_INFO
*data
,
5829 const struct nls_table
*nls_codepage
, int remap
)
5831 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5832 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5835 int bytes_returned
= 0;
5837 __u16 params
, param_offset
, offset
, byte_count
, count
;
5839 cifs_dbg(FYI
, "In SetTimes\n");
5842 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5847 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5849 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5850 PATH_MAX
, nls_codepage
, remap
);
5851 name_len
++; /* trailing null */
5853 } else { /* BB improve the check for buffer overruns BB */
5854 name_len
= strnlen(fileName
, PATH_MAX
);
5855 name_len
++; /* trailing null */
5856 strncpy(pSMB
->FileName
, fileName
, name_len
);
5859 params
= 6 + name_len
;
5860 count
= sizeof(FILE_BASIC_INFO
);
5861 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5862 /* BB find max SMB PDU from sess structure BB */
5863 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5864 pSMB
->MaxSetupCount
= 0;
5868 pSMB
->Reserved2
= 0;
5869 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5870 InformationLevel
) - 4;
5871 offset
= param_offset
+ params
;
5872 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5873 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5874 pSMB
->DataOffset
= cpu_to_le16(offset
);
5875 pSMB
->SetupCount
= 1;
5876 pSMB
->Reserved3
= 0;
5877 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5878 byte_count
= 3 /* pad */ + params
+ count
;
5880 pSMB
->DataCount
= cpu_to_le16(count
);
5881 pSMB
->ParameterCount
= cpu_to_le16(params
);
5882 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5883 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5884 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5885 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5887 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5888 pSMB
->Reserved4
= 0;
5889 inc_rfc1001_len(pSMB
, byte_count
);
5890 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5891 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5892 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5893 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5895 cifs_dbg(FYI
, "SetPathInfo (times) returned %d\n", rc
);
5897 cifs_buf_release(pSMB
);
5905 /* Can not be used to set time stamps yet (due to old DOS time format) */
5906 /* Can be used to set attributes */
5907 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5908 handling it anyway and NT4 was what we thought it would be needed for
5909 Do not delete it until we prove whether needed for Win9x though */
5911 CIFSSMBSetAttrLegacy(unsigned int xid
, struct cifs_tcon
*tcon
, char *fileName
,
5912 __u16 dos_attrs
, const struct nls_table
*nls_codepage
)
5914 SETATTR_REQ
*pSMB
= NULL
;
5915 SETATTR_RSP
*pSMBr
= NULL
;
5920 cifs_dbg(FYI
, "In SetAttrLegacy\n");
5923 rc
= smb_init(SMB_COM_SETATTR
, 8, tcon
, (void **) &pSMB
,
5928 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5930 ConvertToUTF16((__le16
*) pSMB
->fileName
, fileName
,
5931 PATH_MAX
, nls_codepage
);
5932 name_len
++; /* trailing null */
5934 } else { /* BB improve the check for buffer overruns BB */
5935 name_len
= strnlen(fileName
, PATH_MAX
);
5936 name_len
++; /* trailing null */
5937 strncpy(pSMB
->fileName
, fileName
, name_len
);
5939 pSMB
->attr
= cpu_to_le16(dos_attrs
);
5940 pSMB
->BufferFormat
= 0x04;
5941 inc_rfc1001_len(pSMB
, name_len
+ 1);
5942 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
5943 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5944 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5946 cifs_dbg(FYI
, "Error in LegacySetAttr = %d\n", rc
);
5948 cifs_buf_release(pSMB
);
5951 goto SetAttrLgcyRetry
;
5955 #endif /* temporarily unneeded SetAttr legacy function */
5958 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO
*data_offset
,
5959 const struct cifs_unix_set_info_args
*args
)
5961 u64 uid
= NO_CHANGE_64
, gid
= NO_CHANGE_64
;
5962 u64 mode
= args
->mode
;
5964 if (uid_valid(args
->uid
))
5965 uid
= from_kuid(&init_user_ns
, args
->uid
);
5966 if (gid_valid(args
->gid
))
5967 gid
= from_kgid(&init_user_ns
, args
->gid
);
5970 * Samba server ignores set of file size to zero due to bugs in some
5971 * older clients, but we should be precise - we use SetFileSize to
5972 * set file size and do not want to truncate file size to zero
5973 * accidentally as happened on one Samba server beta by putting
5974 * zero instead of -1 here
5976 data_offset
->EndOfFile
= cpu_to_le64(NO_CHANGE_64
);
5977 data_offset
->NumOfBytes
= cpu_to_le64(NO_CHANGE_64
);
5978 data_offset
->LastStatusChange
= cpu_to_le64(args
->ctime
);
5979 data_offset
->LastAccessTime
= cpu_to_le64(args
->atime
);
5980 data_offset
->LastModificationTime
= cpu_to_le64(args
->mtime
);
5981 data_offset
->Uid
= cpu_to_le64(uid
);
5982 data_offset
->Gid
= cpu_to_le64(gid
);
5983 /* better to leave device as zero when it is */
5984 data_offset
->DevMajor
= cpu_to_le64(MAJOR(args
->device
));
5985 data_offset
->DevMinor
= cpu_to_le64(MINOR(args
->device
));
5986 data_offset
->Permissions
= cpu_to_le64(mode
);
5989 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
5990 else if (S_ISDIR(mode
))
5991 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
5992 else if (S_ISLNK(mode
))
5993 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
5994 else if (S_ISCHR(mode
))
5995 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
5996 else if (S_ISBLK(mode
))
5997 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
5998 else if (S_ISFIFO(mode
))
5999 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
6000 else if (S_ISSOCK(mode
))
6001 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
6005 CIFSSMBUnixSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6006 const struct cifs_unix_set_info_args
*args
,
6007 u16 fid
, u32 pid_of_opener
)
6009 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
6012 u16 params
, param_offset
, offset
, byte_count
, count
;
6014 cifs_dbg(FYI
, "Set Unix Info (via SetFileInfo)\n");
6015 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
6020 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
6021 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
6024 pSMB
->MaxSetupCount
= 0;
6028 pSMB
->Reserved2
= 0;
6029 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
6030 offset
= param_offset
+ params
;
6032 data_offset
= (char *)pSMB
+
6033 offsetof(struct smb_hdr
, Protocol
) + offset
;
6035 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6037 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6038 /* BB find max SMB PDU from sess */
6039 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6040 pSMB
->SetupCount
= 1;
6041 pSMB
->Reserved3
= 0;
6042 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
6043 byte_count
= 3 /* pad */ + params
+ count
;
6044 pSMB
->DataCount
= cpu_to_le16(count
);
6045 pSMB
->ParameterCount
= cpu_to_le16(params
);
6046 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6047 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6048 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6049 pSMB
->DataOffset
= cpu_to_le16(offset
);
6051 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6052 pSMB
->Reserved4
= 0;
6053 inc_rfc1001_len(pSMB
, byte_count
);
6054 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6056 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO
*)data_offset
, args
);
6058 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
6059 cifs_small_buf_release(pSMB
);
6061 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
6064 /* Note: On -EAGAIN error only caller can retry on handle based calls
6065 since file handle passed in no longer valid */
6071 CIFSSMBUnixSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6072 const char *file_name
,
6073 const struct cifs_unix_set_info_args
*args
,
6074 const struct nls_table
*nls_codepage
, int remap
)
6076 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
6077 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
6080 int bytes_returned
= 0;
6081 FILE_UNIX_BASIC_INFO
*data_offset
;
6082 __u16 params
, param_offset
, offset
, count
, byte_count
;
6084 cifs_dbg(FYI
, "In SetUID/GID/Mode\n");
6086 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6091 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6093 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
6094 PATH_MAX
, nls_codepage
, remap
);
6095 name_len
++; /* trailing null */
6097 } else { /* BB improve the check for buffer overruns BB */
6098 name_len
= strnlen(file_name
, PATH_MAX
);
6099 name_len
++; /* trailing null */
6100 strncpy(pSMB
->FileName
, file_name
, name_len
);
6103 params
= 6 + name_len
;
6104 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6105 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6106 /* BB find max SMB PDU from sess structure BB */
6107 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6108 pSMB
->MaxSetupCount
= 0;
6112 pSMB
->Reserved2
= 0;
6113 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6114 InformationLevel
) - 4;
6115 offset
= param_offset
+ params
;
6117 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
6119 memset(data_offset
, 0, count
);
6120 pSMB
->DataOffset
= cpu_to_le16(offset
);
6121 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6122 pSMB
->SetupCount
= 1;
6123 pSMB
->Reserved3
= 0;
6124 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6125 byte_count
= 3 /* pad */ + params
+ count
;
6126 pSMB
->ParameterCount
= cpu_to_le16(params
);
6127 pSMB
->DataCount
= cpu_to_le16(count
);
6128 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6129 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6130 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6131 pSMB
->Reserved4
= 0;
6132 inc_rfc1001_len(pSMB
, byte_count
);
6134 cifs_fill_unix_set_info(data_offset
, args
);
6136 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6137 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6138 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6140 cifs_dbg(FYI
, "SetPathInfo (perms) returned %d\n", rc
);
6142 cifs_buf_release(pSMB
);
6148 #ifdef CONFIG_CIFS_XATTR
6150 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6151 * function used by listxattr and getxattr type calls. When ea_name is set,
6152 * it looks for that attribute name and stuffs that value into the EAData
6153 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6154 * buffer. In both cases, the return value is either the length of the
6155 * resulting data or a negative error code. If EAData is a NULL pointer then
6156 * the data isn't copied to it, but the length is returned.
6159 CIFSSMBQAllEAs(const unsigned int xid
, struct cifs_tcon
*tcon
,
6160 const unsigned char *searchName
, const unsigned char *ea_name
,
6161 char *EAData
, size_t buf_size
,
6162 struct cifs_sb_info
*cifs_sb
)
6164 /* BB assumes one setup word */
6165 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
6166 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
6167 int remap
= cifs_remap(cifs_sb
);
6168 struct nls_table
*nls_codepage
= cifs_sb
->local_nls
;
6172 struct fealist
*ea_response_data
;
6173 struct fea
*temp_fea
;
6176 __u16 params
, byte_count
, data_offset
;
6177 unsigned int ea_name_len
= ea_name
? strlen(ea_name
) : 0;
6179 cifs_dbg(FYI
, "In Query All EAs path %s\n", searchName
);
6181 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6186 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6188 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
6189 PATH_MAX
, nls_codepage
, remap
);
6190 list_len
++; /* trailing null */
6192 } else { /* BB improve the check for buffer overruns BB */
6193 list_len
= strnlen(searchName
, PATH_MAX
);
6194 list_len
++; /* trailing null */
6195 strncpy(pSMB
->FileName
, searchName
, list_len
);
6198 params
= 2 /* level */ + 4 /* reserved */ + list_len
/* includes NUL */;
6199 pSMB
->TotalDataCount
= 0;
6200 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6201 /* BB find exact max SMB PDU from sess structure BB */
6202 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
6203 pSMB
->MaxSetupCount
= 0;
6207 pSMB
->Reserved2
= 0;
6208 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
6209 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
6210 pSMB
->DataCount
= 0;
6211 pSMB
->DataOffset
= 0;
6212 pSMB
->SetupCount
= 1;
6213 pSMB
->Reserved3
= 0;
6214 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
6215 byte_count
= params
+ 1 /* pad */ ;
6216 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
6217 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6218 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
6219 pSMB
->Reserved4
= 0;
6220 inc_rfc1001_len(pSMB
, byte_count
);
6221 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6223 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6224 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6226 cifs_dbg(FYI
, "Send error in QueryAllEAs = %d\n", rc
);
6231 /* BB also check enough total bytes returned */
6232 /* BB we need to improve the validity checking
6233 of these trans2 responses */
6235 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
6236 if (rc
|| get_bcc(&pSMBr
->hdr
) < 4) {
6237 rc
= -EIO
; /* bad smb */
6241 /* check that length of list is not more than bcc */
6242 /* check that each entry does not go beyond length
6244 /* check that each element of each entry does not
6245 go beyond end of list */
6246 /* validate_trans2_offsets() */
6247 /* BB check if start of smb + data_offset > &bcc+ bcc */
6249 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
6250 ea_response_data
= (struct fealist
*)
6251 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
6253 list_len
= le32_to_cpu(ea_response_data
->list_len
);
6254 cifs_dbg(FYI
, "ea length %d\n", list_len
);
6255 if (list_len
<= 8) {
6256 cifs_dbg(FYI
, "empty EA list returned from server\n");
6257 /* didn't find the named attribute */
6263 /* make sure list_len doesn't go past end of SMB */
6264 end_of_smb
= (char *)pByteArea(&pSMBr
->hdr
) + get_bcc(&pSMBr
->hdr
);
6265 if ((char *)ea_response_data
+ list_len
> end_of_smb
) {
6266 cifs_dbg(FYI
, "EA list appears to go beyond SMB\n");
6271 /* account for ea list len */
6273 temp_fea
= ea_response_data
->list
;
6274 temp_ptr
= (char *)temp_fea
;
6275 while (list_len
> 0) {
6276 unsigned int name_len
;
6281 /* make sure we can read name_len and value_len */
6283 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6288 name_len
= temp_fea
->name_len
;
6289 value_len
= le16_to_cpu(temp_fea
->value_len
);
6290 list_len
-= name_len
+ 1 + value_len
;
6292 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6298 if (ea_name_len
== name_len
&&
6299 memcmp(ea_name
, temp_ptr
, name_len
) == 0) {
6300 temp_ptr
+= name_len
+ 1;
6304 if ((size_t)value_len
> buf_size
) {
6308 memcpy(EAData
, temp_ptr
, value_len
);
6312 /* account for prefix user. and trailing null */
6313 rc
+= (5 + 1 + name_len
);
6314 if (rc
< (int) buf_size
) {
6315 memcpy(EAData
, "user.", 5);
6317 memcpy(EAData
, temp_ptr
, name_len
);
6319 /* null terminate name */
6322 } else if (buf_size
== 0) {
6323 /* skip copy - calc size only */
6325 /* stop before overrun buffer */
6330 temp_ptr
+= name_len
+ 1 + value_len
;
6331 temp_fea
= (struct fea
*)temp_ptr
;
6334 /* didn't find the named attribute */
6339 cifs_buf_release(pSMB
);
6347 CIFSSMBSetEA(const unsigned int xid
, struct cifs_tcon
*tcon
,
6348 const char *fileName
, const char *ea_name
, const void *ea_value
,
6349 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
,
6350 struct cifs_sb_info
*cifs_sb
)
6352 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
6353 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
6354 struct fealist
*parm_data
;
6357 int bytes_returned
= 0;
6358 __u16 params
, param_offset
, byte_count
, offset
, count
;
6359 int remap
= cifs_remap(cifs_sb
);
6361 cifs_dbg(FYI
, "In SetEA\n");
6363 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6368 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6370 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
6371 PATH_MAX
, nls_codepage
, remap
);
6372 name_len
++; /* trailing null */
6374 } else { /* BB improve the check for buffer overruns BB */
6375 name_len
= strnlen(fileName
, PATH_MAX
);
6376 name_len
++; /* trailing null */
6377 strncpy(pSMB
->FileName
, fileName
, name_len
);
6380 params
= 6 + name_len
;
6382 /* done calculating parms using name_len of file name,
6383 now use name_len to calculate length of ea name
6384 we are going to create in the inode xattrs */
6385 if (ea_name
== NULL
)
6388 name_len
= strnlen(ea_name
, 255);
6390 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
;
6391 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6392 /* BB find max SMB PDU from sess */
6393 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6394 pSMB
->MaxSetupCount
= 0;
6398 pSMB
->Reserved2
= 0;
6399 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6400 InformationLevel
) - 4;
6401 offset
= param_offset
+ params
;
6402 pSMB
->InformationLevel
=
6403 cpu_to_le16(SMB_SET_FILE_EA
);
6405 parm_data
= (void *)pSMB
+ offsetof(struct smb_hdr
, Protocol
) + offset
;
6406 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6407 pSMB
->DataOffset
= cpu_to_le16(offset
);
6408 pSMB
->SetupCount
= 1;
6409 pSMB
->Reserved3
= 0;
6410 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6411 byte_count
= 3 /* pad */ + params
+ count
;
6412 pSMB
->DataCount
= cpu_to_le16(count
);
6413 parm_data
->list_len
= cpu_to_le32(count
);
6414 parm_data
->list
[0].EA_flags
= 0;
6415 /* we checked above that name len is less than 255 */
6416 parm_data
->list
[0].name_len
= (__u8
)name_len
;
6417 /* EA names are always ASCII */
6419 strncpy(parm_data
->list
[0].name
, ea_name
, name_len
);
6420 parm_data
->list
[0].name
[name_len
] = 0;
6421 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
6422 /* caller ensures that ea_value_len is less than 64K but
6423 we need to ensure that it fits within the smb */
6425 /*BB add length check to see if it would fit in
6426 negotiated SMB buffer size BB */
6427 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6429 memcpy(parm_data
->list
[0].name
+name_len
+1,
6430 ea_value
, ea_value_len
);
6432 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6433 pSMB
->ParameterCount
= cpu_to_le16(params
);
6434 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6435 pSMB
->Reserved4
= 0;
6436 inc_rfc1001_len(pSMB
, byte_count
);
6437 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6438 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6439 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6441 cifs_dbg(FYI
, "SetPathInfo (EA) returned %d\n", rc
);
6443 cifs_buf_release(pSMB
);
6452 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6454 * Years ago the kernel added a "dnotify" function for Samba server,
6455 * to allow network clients (such as Windows) to display updated
6456 * lists of files in directory listings automatically when
6457 * files are added by one user when another user has the
6458 * same directory open on their desktop. The Linux cifs kernel
6459 * client hooked into the kernel side of this interface for
6460 * the same reason, but ironically when the VFS moved from
6461 * "dnotify" to "inotify" it became harder to plug in Linux
6462 * network file system clients (the most obvious use case
6463 * for notify interfaces is when multiple users can update
6464 * the contents of the same directory - exactly what network
6465 * file systems can do) although the server (Samba) could
6466 * still use it. For the short term we leave the worker
6467 * function ifdeffed out (below) until inotify is fixed
6468 * in the VFS to make it easier to plug in network file
6469 * system clients. If inotify turns out to be permanently
6470 * incompatible for network fs clients, we could instead simply
6471 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6473 int CIFSSMBNotify(const unsigned int xid
, struct cifs_tcon
*tcon
,
6474 const int notify_subdirs
, const __u16 netfid
,
6475 __u32 filter
, struct file
*pfile
, int multishot
,
6476 const struct nls_table
*nls_codepage
)
6479 struct smb_com_transaction_change_notify_req
*pSMB
= NULL
;
6480 struct smb_com_ntransaction_change_notify_rsp
*pSMBr
= NULL
;
6481 struct dir_notify_req
*dnotify_req
;
6484 cifs_dbg(FYI
, "In CIFSSMBNotify for file handle %d\n", (int)netfid
);
6485 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
6490 pSMB
->TotalParameterCount
= 0 ;
6491 pSMB
->TotalDataCount
= 0;
6492 pSMB
->MaxParameterCount
= cpu_to_le32(2);
6493 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
6494 pSMB
->MaxSetupCount
= 4;
6496 pSMB
->ParameterOffset
= 0;
6497 pSMB
->DataCount
= 0;
6498 pSMB
->DataOffset
= 0;
6499 pSMB
->SetupCount
= 4; /* single byte does not need le conversion */
6500 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE
);
6501 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6503 pSMB
->WatchTree
= 1; /* one byte - no le conversion needed */
6504 pSMB
->Reserved2
= 0;
6505 pSMB
->CompletionFilter
= cpu_to_le32(filter
);
6506 pSMB
->Fid
= netfid
; /* file handle always le */
6507 pSMB
->ByteCount
= 0;
6509 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6510 (struct smb_hdr
*)pSMBr
, &bytes_returned
,
6513 cifs_dbg(FYI
, "Error in Notify = %d\n", rc
);
6515 /* Add file to outstanding requests */
6516 /* BB change to kmem cache alloc */
6517 dnotify_req
= kmalloc(
6518 sizeof(struct dir_notify_req
),
6521 dnotify_req
->Pid
= pSMB
->hdr
.Pid
;
6522 dnotify_req
->PidHigh
= pSMB
->hdr
.PidHigh
;
6523 dnotify_req
->Mid
= pSMB
->hdr
.Mid
;
6524 dnotify_req
->Tid
= pSMB
->hdr
.Tid
;
6525 dnotify_req
->Uid
= pSMB
->hdr
.Uid
;
6526 dnotify_req
->netfid
= netfid
;
6527 dnotify_req
->pfile
= pfile
;
6528 dnotify_req
->filter
= filter
;
6529 dnotify_req
->multishot
= multishot
;
6530 spin_lock(&GlobalMid_Lock
);
6531 list_add_tail(&dnotify_req
->lhead
,
6532 &GlobalDnotifyReqList
);
6533 spin_unlock(&GlobalMid_Lock
);
6537 cifs_buf_release(pSMB
);
6540 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */