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
,
1466 length
= cifs_discard_remaining_data(server
);
1467 dequeue_mid(mid
, malformed
);
1468 mid
->resp_buf
= server
->smallbuf
;
1469 server
->smallbuf
= NULL
;
1474 cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1476 struct cifs_readdata
*rdata
= mid
->callback_data
;
1478 return __cifs_readv_discard(server
, mid
, rdata
->result
);
1482 cifs_readv_receive(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1485 unsigned int data_offset
, data_len
;
1486 struct cifs_readdata
*rdata
= mid
->callback_data
;
1487 char *buf
= server
->smallbuf
;
1488 unsigned int buflen
= server
->pdu_size
+
1489 server
->vals
->header_preamble_size
;
1490 bool use_rdma_mr
= false;
1492 cifs_dbg(FYI
, "%s: mid=%llu offset=%llu bytes=%u\n",
1493 __func__
, mid
->mid
, rdata
->offset
, rdata
->bytes
);
1496 * read the rest of READ_RSP header (sans Data array), or whatever we
1497 * can if there's not enough data. At this point, we've read down to
1500 len
= min_t(unsigned int, buflen
, server
->vals
->read_rsp_size
) -
1501 HEADER_SIZE(server
) + 1;
1503 length
= cifs_read_from_socket(server
,
1504 buf
+ HEADER_SIZE(server
) - 1, len
);
1507 server
->total_read
+= length
;
1509 if (server
->ops
->is_session_expired
&&
1510 server
->ops
->is_session_expired(buf
)) {
1511 cifs_reconnect(server
);
1512 wake_up(&server
->response_q
);
1516 if (server
->ops
->is_status_pending
&&
1517 server
->ops
->is_status_pending(buf
, server
, 0)) {
1518 cifs_discard_remaining_data(server
);
1522 /* set up first two iov for signature check and to get credits */
1523 rdata
->iov
[0].iov_base
= buf
;
1524 rdata
->iov
[0].iov_len
= server
->vals
->header_preamble_size
;
1525 rdata
->iov
[1].iov_base
= buf
+ server
->vals
->header_preamble_size
;
1526 rdata
->iov
[1].iov_len
=
1527 server
->total_read
- server
->vals
->header_preamble_size
;
1528 cifs_dbg(FYI
, "0: iov_base=%p iov_len=%zu\n",
1529 rdata
->iov
[0].iov_base
, rdata
->iov
[0].iov_len
);
1530 cifs_dbg(FYI
, "1: iov_base=%p iov_len=%zu\n",
1531 rdata
->iov
[1].iov_base
, rdata
->iov
[1].iov_len
);
1533 /* Was the SMB read successful? */
1534 rdata
->result
= server
->ops
->map_error(buf
, false);
1535 if (rdata
->result
!= 0) {
1536 cifs_dbg(FYI
, "%s: server returned error %d\n",
1537 __func__
, rdata
->result
);
1538 /* normal error on read response */
1539 return __cifs_readv_discard(server
, mid
, false);
1542 /* Is there enough to get to the rest of the READ_RSP header? */
1543 if (server
->total_read
< server
->vals
->read_rsp_size
) {
1544 cifs_dbg(FYI
, "%s: server returned short header. got=%u expected=%zu\n",
1545 __func__
, server
->total_read
,
1546 server
->vals
->read_rsp_size
);
1547 rdata
->result
= -EIO
;
1548 return cifs_readv_discard(server
, mid
);
1551 data_offset
= server
->ops
->read_data_offset(buf
) +
1552 server
->vals
->header_preamble_size
;
1553 if (data_offset
< server
->total_read
) {
1555 * win2k8 sometimes sends an offset of 0 when the read
1556 * is beyond the EOF. Treat it as if the data starts just after
1559 cifs_dbg(FYI
, "%s: data offset (%u) inside read response header\n",
1560 __func__
, data_offset
);
1561 data_offset
= server
->total_read
;
1562 } else if (data_offset
> MAX_CIFS_SMALL_BUFFER_SIZE
) {
1563 /* data_offset is beyond the end of smallbuf */
1564 cifs_dbg(FYI
, "%s: data offset (%u) beyond end of smallbuf\n",
1565 __func__
, data_offset
);
1566 rdata
->result
= -EIO
;
1567 return cifs_readv_discard(server
, mid
);
1570 cifs_dbg(FYI
, "%s: total_read=%u data_offset=%u\n",
1571 __func__
, server
->total_read
, data_offset
);
1573 len
= data_offset
- server
->total_read
;
1575 /* read any junk before data into the rest of smallbuf */
1576 length
= cifs_read_from_socket(server
,
1577 buf
+ server
->total_read
, len
);
1580 server
->total_read
+= length
;
1583 /* how much data is in the response? */
1584 #ifdef CONFIG_CIFS_SMB_DIRECT
1585 use_rdma_mr
= rdata
->mr
;
1587 data_len
= server
->ops
->read_data_length(buf
, use_rdma_mr
);
1588 if (!use_rdma_mr
&& (data_offset
+ data_len
> buflen
)) {
1589 /* data_len is corrupt -- discard frame */
1590 rdata
->result
= -EIO
;
1591 return cifs_readv_discard(server
, mid
);
1594 length
= rdata
->read_into_pages(server
, rdata
, data_len
);
1598 server
->total_read
+= length
;
1600 cifs_dbg(FYI
, "total_read=%u buflen=%u remaining=%u\n",
1601 server
->total_read
, buflen
, data_len
);
1603 /* discard anything left over */
1604 if (server
->total_read
< buflen
)
1605 return cifs_readv_discard(server
, mid
);
1607 dequeue_mid(mid
, false);
1608 mid
->resp_buf
= server
->smallbuf
;
1609 server
->smallbuf
= NULL
;
1614 cifs_readv_callback(struct mid_q_entry
*mid
)
1616 struct cifs_readdata
*rdata
= mid
->callback_data
;
1617 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1618 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
1619 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1621 .rq_pages
= rdata
->pages
,
1622 .rq_npages
= rdata
->nr_pages
,
1623 .rq_pagesz
= rdata
->pagesz
,
1624 .rq_tailsz
= rdata
->tailsz
};
1626 cifs_dbg(FYI
, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1627 __func__
, mid
->mid
, mid
->mid_state
, rdata
->result
,
1630 switch (mid
->mid_state
) {
1631 case MID_RESPONSE_RECEIVED
:
1632 /* result already set, check signature */
1636 rc
= cifs_verify_signature(&rqst
, server
,
1637 mid
->sequence_number
);
1639 cifs_dbg(VFS
, "SMB signature verification returned error = %d\n",
1642 /* FIXME: should this be counted toward the initiating task? */
1643 task_io_account_read(rdata
->got_bytes
);
1644 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1646 case MID_REQUEST_SUBMITTED
:
1647 case MID_RETRY_NEEDED
:
1648 rdata
->result
= -EAGAIN
;
1649 if (server
->sign
&& rdata
->got_bytes
)
1650 /* reset bytes number since we can not check a sign */
1651 rdata
->got_bytes
= 0;
1652 /* FIXME: should this be counted toward the initiating task? */
1653 task_io_account_read(rdata
->got_bytes
);
1654 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1657 rdata
->result
= -EIO
;
1660 queue_work(cifsiod_wq
, &rdata
->work
);
1661 DeleteMidQEntry(mid
);
1662 add_credits(server
, 1, 0);
1665 /* cifs_async_readv - send an async write, and set up mid to handle result */
1667 cifs_async_readv(struct cifs_readdata
*rdata
)
1670 READ_REQ
*smb
= NULL
;
1672 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1673 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1676 cifs_dbg(FYI
, "%s: offset=%llu bytes=%u\n",
1677 __func__
, rdata
->offset
, rdata
->bytes
);
1679 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1682 wct
= 10; /* old style read */
1683 if ((rdata
->offset
>> 32) > 0) {
1684 /* can not handle this big offset for old */
1689 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **)&smb
);
1693 smb
->hdr
.Pid
= cpu_to_le16((__u16
)rdata
->pid
);
1694 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(rdata
->pid
>> 16));
1696 smb
->AndXCommand
= 0xFF; /* none */
1697 smb
->Fid
= rdata
->cfile
->fid
.netfid
;
1698 smb
->OffsetLow
= cpu_to_le32(rdata
->offset
& 0xFFFFFFFF);
1700 smb
->OffsetHigh
= cpu_to_le32(rdata
->offset
>> 32);
1702 smb
->MaxCount
= cpu_to_le16(rdata
->bytes
& 0xFFFF);
1703 smb
->MaxCountHigh
= cpu_to_le32(rdata
->bytes
>> 16);
1707 /* old style read */
1708 struct smb_com_readx_req
*smbr
=
1709 (struct smb_com_readx_req
*)smb
;
1710 smbr
->ByteCount
= 0;
1713 /* 4 for RFC1001 length + 1 for BCC */
1714 rdata
->iov
[0].iov_base
= smb
;
1715 rdata
->iov
[0].iov_len
= 4;
1716 rdata
->iov
[1].iov_base
= (char *)smb
+ 4;
1717 rdata
->iov
[1].iov_len
= get_rfc1002_length(smb
);
1719 kref_get(&rdata
->refcount
);
1720 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, cifs_readv_receive
,
1721 cifs_readv_callback
, NULL
, rdata
, 0);
1724 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1726 kref_put(&rdata
->refcount
, cifs_readdata_release
);
1728 cifs_small_buf_release(smb
);
1733 CIFSSMBRead(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1734 unsigned int *nbytes
, char **buf
, int *pbuf_type
)
1737 READ_REQ
*pSMB
= NULL
;
1738 READ_RSP
*pSMBr
= NULL
;
1739 char *pReadData
= NULL
;
1741 int resp_buf_type
= 0;
1743 struct kvec rsp_iov
;
1744 __u32 pid
= io_parms
->pid
;
1745 __u16 netfid
= io_parms
->netfid
;
1746 __u64 offset
= io_parms
->offset
;
1747 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1748 unsigned int count
= io_parms
->length
;
1750 cifs_dbg(FYI
, "Reading %d bytes on fid %d\n", count
, netfid
);
1751 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1754 wct
= 10; /* old style read */
1755 if ((offset
>> 32) > 0) {
1756 /* can not handle this big offset for old */
1762 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **) &pSMB
);
1766 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1767 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1769 /* tcon and ses pointer are checked in smb_init */
1770 if (tcon
->ses
->server
== NULL
)
1771 return -ECONNABORTED
;
1773 pSMB
->AndXCommand
= 0xFF; /* none */
1775 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1777 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1779 pSMB
->Remaining
= 0;
1780 pSMB
->MaxCount
= cpu_to_le16(count
& 0xFFFF);
1781 pSMB
->MaxCountHigh
= cpu_to_le32(count
>> 16);
1783 pSMB
->ByteCount
= 0; /* no need to do le conversion since 0 */
1785 /* old style read */
1786 struct smb_com_readx_req
*pSMBW
=
1787 (struct smb_com_readx_req
*)pSMB
;
1788 pSMBW
->ByteCount
= 0;
1791 iov
[0].iov_base
= (char *)pSMB
;
1792 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
1793 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1, &resp_buf_type
,
1794 CIFS_LOG_ERROR
, &rsp_iov
);
1795 cifs_small_buf_release(pSMB
);
1796 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1797 pSMBr
= (READ_RSP
*)rsp_iov
.iov_base
;
1799 cifs_dbg(VFS
, "Send error in read = %d\n", rc
);
1801 int data_length
= le16_to_cpu(pSMBr
->DataLengthHigh
);
1802 data_length
= data_length
<< 16;
1803 data_length
+= le16_to_cpu(pSMBr
->DataLength
);
1804 *nbytes
= data_length
;
1806 /*check that DataLength would not go beyond end of SMB */
1807 if ((data_length
> CIFSMaxBufSize
)
1808 || (data_length
> count
)) {
1809 cifs_dbg(FYI
, "bad length %d for count %d\n",
1810 data_length
, count
);
1814 pReadData
= (char *) (&pSMBr
->hdr
.Protocol
) +
1815 le16_to_cpu(pSMBr
->DataOffset
);
1816 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1817 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1819 }*/ /* can not use copy_to_user when using page cache*/
1821 memcpy(*buf
, pReadData
, data_length
);
1826 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
1827 } else if (resp_buf_type
!= CIFS_NO_BUFFER
) {
1828 /* return buffer to caller to free */
1829 *buf
= rsp_iov
.iov_base
;
1830 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1831 *pbuf_type
= CIFS_SMALL_BUFFER
;
1832 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1833 *pbuf_type
= CIFS_LARGE_BUFFER
;
1834 } /* else no valid buffer on return - leave as null */
1836 /* Note: On -EAGAIN error only caller can retry on handle based calls
1837 since file handle passed in no longer valid */
1843 CIFSSMBWrite(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1844 unsigned int *nbytes
, const char *buf
)
1847 WRITE_REQ
*pSMB
= NULL
;
1848 WRITE_RSP
*pSMBr
= NULL
;
1849 int bytes_returned
, wct
;
1852 __u32 pid
= io_parms
->pid
;
1853 __u16 netfid
= io_parms
->netfid
;
1854 __u64 offset
= io_parms
->offset
;
1855 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1856 unsigned int count
= io_parms
->length
;
1860 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1861 if (tcon
->ses
== NULL
)
1862 return -ECONNABORTED
;
1864 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1868 if ((offset
>> 32) > 0) {
1869 /* can not handle big offset for old srv */
1874 rc
= smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
,
1879 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1880 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1882 /* tcon and ses pointer are checked in smb_init */
1883 if (tcon
->ses
->server
== NULL
)
1884 return -ECONNABORTED
;
1886 pSMB
->AndXCommand
= 0xFF; /* none */
1888 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1890 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1892 pSMB
->Reserved
= 0xFFFFFFFF;
1893 pSMB
->WriteMode
= 0;
1894 pSMB
->Remaining
= 0;
1896 /* Can increase buffer size if buffer is big enough in some cases ie we
1897 can send more if LARGE_WRITE_X capability returned by the server and if
1898 our buffer is big enough or if we convert to iovecs on socket writes
1899 and eliminate the copy to the CIFS buffer */
1900 if (tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
) {
1901 bytes_sent
= min_t(const unsigned int, CIFSMaxBufSize
, count
);
1903 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
)
1907 if (bytes_sent
> count
)
1910 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1912 memcpy(pSMB
->Data
, buf
, bytes_sent
);
1913 else if (count
!= 0) {
1915 cifs_buf_release(pSMB
);
1917 } /* else setting file size with write of zero bytes */
1919 byte_count
= bytes_sent
+ 1; /* pad */
1920 else /* wct == 12 */
1921 byte_count
= bytes_sent
+ 5; /* bigger pad, smaller smb hdr */
1923 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
& 0xFFFF);
1924 pSMB
->DataLengthHigh
= cpu_to_le16(bytes_sent
>> 16);
1925 inc_rfc1001_len(pSMB
, byte_count
);
1928 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1929 else { /* old style write has byte count 4 bytes earlier
1931 struct smb_com_writex_req
*pSMBW
=
1932 (struct smb_com_writex_req
*)pSMB
;
1933 pSMBW
->ByteCount
= cpu_to_le16(byte_count
);
1936 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1937 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1938 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
1940 cifs_dbg(FYI
, "Send error in write = %d\n", rc
);
1942 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
1943 *nbytes
= (*nbytes
) << 16;
1944 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
1947 * Mask off high 16 bits when bytes written as returned by the
1948 * server is greater than bytes requested by the client. Some
1949 * OS/2 servers are known to set incorrect CountHigh values.
1951 if (*nbytes
> count
)
1955 cifs_buf_release(pSMB
);
1957 /* Note: On -EAGAIN error only caller can retry on handle based calls
1958 since file handle passed in no longer valid */
1964 cifs_writedata_release(struct kref
*refcount
)
1966 struct cifs_writedata
*wdata
= container_of(refcount
,
1967 struct cifs_writedata
, refcount
);
1968 #ifdef CONFIG_CIFS_SMB_DIRECT
1970 smbd_deregister_mr(wdata
->mr
);
1976 cifsFileInfo_put(wdata
->cfile
);
1978 kvfree(wdata
->pages
);
1983 * Write failed with a retryable error. Resend the write request. It's also
1984 * possible that the page was redirtied so re-clean the page.
1987 cifs_writev_requeue(struct cifs_writedata
*wdata
)
1990 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
1991 struct TCP_Server_Info
*server
;
1992 unsigned int rest_len
;
1994 server
= tlink_tcon(wdata
->cfile
->tlink
)->ses
->server
;
1996 rest_len
= wdata
->bytes
;
1998 struct cifs_writedata
*wdata2
;
1999 unsigned int j
, nr_pages
, wsize
, tailsz
, cur_len
;
2001 wsize
= server
->ops
->wp_retry_size(inode
);
2002 if (wsize
< rest_len
) {
2003 nr_pages
= wsize
/ PAGE_SIZE
;
2008 cur_len
= nr_pages
* PAGE_SIZE
;
2011 nr_pages
= DIV_ROUND_UP(rest_len
, PAGE_SIZE
);
2013 tailsz
= rest_len
- (nr_pages
- 1) * PAGE_SIZE
;
2016 wdata2
= cifs_writedata_alloc(nr_pages
, cifs_writev_complete
);
2022 for (j
= 0; j
< nr_pages
; j
++) {
2023 wdata2
->pages
[j
] = wdata
->pages
[i
+ j
];
2024 lock_page(wdata2
->pages
[j
]);
2025 clear_page_dirty_for_io(wdata2
->pages
[j
]);
2028 wdata2
->sync_mode
= wdata
->sync_mode
;
2029 wdata2
->nr_pages
= nr_pages
;
2030 wdata2
->offset
= page_offset(wdata2
->pages
[0]);
2031 wdata2
->pagesz
= PAGE_SIZE
;
2032 wdata2
->tailsz
= tailsz
;
2033 wdata2
->bytes
= cur_len
;
2035 wdata2
->cfile
= find_writable_file(CIFS_I(inode
), false);
2036 if (!wdata2
->cfile
) {
2037 cifs_dbg(VFS
, "No writable handle to retry writepages\n");
2040 wdata2
->pid
= wdata2
->cfile
->pid
;
2041 rc
= server
->ops
->async_writev(wdata2
,
2042 cifs_writedata_release
);
2045 for (j
= 0; j
< nr_pages
; j
++) {
2046 unlock_page(wdata2
->pages
[j
]);
2047 if (rc
!= 0 && !is_retryable_error(rc
)) {
2048 SetPageError(wdata2
->pages
[j
]);
2049 end_page_writeback(wdata2
->pages
[j
]);
2050 put_page(wdata2
->pages
[j
]);
2054 kref_put(&wdata2
->refcount
, cifs_writedata_release
);
2056 if (is_retryable_error(rc
))
2062 rest_len
-= cur_len
;
2064 } while (i
< wdata
->nr_pages
);
2066 /* cleanup remaining pages from the original wdata */
2067 for (; i
< wdata
->nr_pages
; i
++) {
2068 SetPageError(wdata
->pages
[i
]);
2069 end_page_writeback(wdata
->pages
[i
]);
2070 put_page(wdata
->pages
[i
]);
2073 if (rc
!= 0 && !is_retryable_error(rc
))
2074 mapping_set_error(inode
->i_mapping
, rc
);
2075 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2079 cifs_writev_complete(struct work_struct
*work
)
2081 struct cifs_writedata
*wdata
= container_of(work
,
2082 struct cifs_writedata
, work
);
2083 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
2086 if (wdata
->result
== 0) {
2087 spin_lock(&inode
->i_lock
);
2088 cifs_update_eof(CIFS_I(inode
), wdata
->offset
, wdata
->bytes
);
2089 spin_unlock(&inode
->i_lock
);
2090 cifs_stats_bytes_written(tlink_tcon(wdata
->cfile
->tlink
),
2092 } else if (wdata
->sync_mode
== WB_SYNC_ALL
&& wdata
->result
== -EAGAIN
)
2093 return cifs_writev_requeue(wdata
);
2095 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
2096 struct page
*page
= wdata
->pages
[i
];
2097 if (wdata
->result
== -EAGAIN
)
2098 __set_page_dirty_nobuffers(page
);
2099 else if (wdata
->result
< 0)
2101 end_page_writeback(page
);
2104 if (wdata
->result
!= -EAGAIN
)
2105 mapping_set_error(inode
->i_mapping
, wdata
->result
);
2106 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2109 struct cifs_writedata
*
2110 cifs_writedata_alloc(unsigned int nr_pages
, work_func_t complete
)
2112 struct page
**pages
=
2113 kcalloc(nr_pages
, sizeof(struct page
*), GFP_NOFS
);
2115 return cifs_writedata_direct_alloc(pages
, complete
);
2120 struct cifs_writedata
*
2121 cifs_writedata_direct_alloc(struct page
**pages
, work_func_t complete
)
2123 struct cifs_writedata
*wdata
;
2125 wdata
= kzalloc(sizeof(*wdata
), GFP_NOFS
);
2126 if (wdata
!= NULL
) {
2127 wdata
->pages
= pages
;
2128 kref_init(&wdata
->refcount
);
2129 INIT_LIST_HEAD(&wdata
->list
);
2130 init_completion(&wdata
->done
);
2131 INIT_WORK(&wdata
->work
, complete
);
2137 * Check the mid_state and signature on received buffer (if any), and queue the
2138 * workqueue completion task.
2141 cifs_writev_callback(struct mid_q_entry
*mid
)
2143 struct cifs_writedata
*wdata
= mid
->callback_data
;
2144 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2145 unsigned int written
;
2146 WRITE_RSP
*smb
= (WRITE_RSP
*)mid
->resp_buf
;
2148 switch (mid
->mid_state
) {
2149 case MID_RESPONSE_RECEIVED
:
2150 wdata
->result
= cifs_check_receive(mid
, tcon
->ses
->server
, 0);
2151 if (wdata
->result
!= 0)
2154 written
= le16_to_cpu(smb
->CountHigh
);
2156 written
+= le16_to_cpu(smb
->Count
);
2158 * Mask off high 16 bits when bytes written as returned
2159 * by the server is greater than bytes requested by the
2160 * client. OS/2 servers are known to set incorrect
2163 if (written
> wdata
->bytes
)
2166 if (written
< wdata
->bytes
)
2167 wdata
->result
= -ENOSPC
;
2169 wdata
->bytes
= written
;
2171 case MID_REQUEST_SUBMITTED
:
2172 case MID_RETRY_NEEDED
:
2173 wdata
->result
= -EAGAIN
;
2176 wdata
->result
= -EIO
;
2180 queue_work(cifsiod_wq
, &wdata
->work
);
2181 DeleteMidQEntry(mid
);
2182 add_credits(tcon
->ses
->server
, 1, 0);
2185 /* cifs_async_writev - send an async write, and set up mid to handle result */
2187 cifs_async_writev(struct cifs_writedata
*wdata
,
2188 void (*release
)(struct kref
*kref
))
2191 WRITE_REQ
*smb
= NULL
;
2193 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2195 struct smb_rqst rqst
= { };
2197 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2201 if (wdata
->offset
>> 32 > 0) {
2202 /* can not handle big offset for old srv */
2207 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **)&smb
);
2209 goto async_writev_out
;
2211 smb
->hdr
.Pid
= cpu_to_le16((__u16
)wdata
->pid
);
2212 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(wdata
->pid
>> 16));
2214 smb
->AndXCommand
= 0xFF; /* none */
2215 smb
->Fid
= wdata
->cfile
->fid
.netfid
;
2216 smb
->OffsetLow
= cpu_to_le32(wdata
->offset
& 0xFFFFFFFF);
2218 smb
->OffsetHigh
= cpu_to_le32(wdata
->offset
>> 32);
2219 smb
->Reserved
= 0xFFFFFFFF;
2224 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2226 /* 4 for RFC1001 length + 1 for BCC */
2228 iov
[0].iov_base
= smb
;
2229 iov
[1].iov_len
= get_rfc1002_length(smb
) + 1;
2230 iov
[1].iov_base
= (char *)smb
+ 4;
2234 rqst
.rq_pages
= wdata
->pages
;
2235 rqst
.rq_npages
= wdata
->nr_pages
;
2236 rqst
.rq_pagesz
= wdata
->pagesz
;
2237 rqst
.rq_tailsz
= wdata
->tailsz
;
2239 cifs_dbg(FYI
, "async write at %llu %u bytes\n",
2240 wdata
->offset
, wdata
->bytes
);
2242 smb
->DataLengthLow
= cpu_to_le16(wdata
->bytes
& 0xFFFF);
2243 smb
->DataLengthHigh
= cpu_to_le16(wdata
->bytes
>> 16);
2246 inc_rfc1001_len(&smb
->hdr
, wdata
->bytes
+ 1);
2247 put_bcc(wdata
->bytes
+ 1, &smb
->hdr
);
2250 struct smb_com_writex_req
*smbw
=
2251 (struct smb_com_writex_req
*)smb
;
2252 inc_rfc1001_len(&smbw
->hdr
, wdata
->bytes
+ 5);
2253 put_bcc(wdata
->bytes
+ 5, &smbw
->hdr
);
2254 iov
[1].iov_len
+= 4; /* pad bigger by four bytes */
2257 kref_get(&wdata
->refcount
);
2258 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, NULL
,
2259 cifs_writev_callback
, NULL
, wdata
, 0);
2262 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2264 kref_put(&wdata
->refcount
, release
);
2267 cifs_small_buf_release(smb
);
2272 CIFSSMBWrite2(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
2273 unsigned int *nbytes
, struct kvec
*iov
, int n_vec
)
2276 WRITE_REQ
*pSMB
= NULL
;
2279 int resp_buf_type
= 0;
2280 __u32 pid
= io_parms
->pid
;
2281 __u16 netfid
= io_parms
->netfid
;
2282 __u64 offset
= io_parms
->offset
;
2283 struct cifs_tcon
*tcon
= io_parms
->tcon
;
2284 unsigned int count
= io_parms
->length
;
2285 struct kvec rsp_iov
;
2289 cifs_dbg(FYI
, "write2 at %lld %d bytes\n", (long long)offset
, count
);
2291 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2295 if ((offset
>> 32) > 0) {
2296 /* can not handle big offset for old srv */
2300 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
);
2304 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
2305 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
2307 /* tcon and ses pointer are checked in smb_init */
2308 if (tcon
->ses
->server
== NULL
)
2309 return -ECONNABORTED
;
2311 pSMB
->AndXCommand
= 0xFF; /* none */
2313 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
2315 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
2316 pSMB
->Reserved
= 0xFFFFFFFF;
2317 pSMB
->WriteMode
= 0;
2318 pSMB
->Remaining
= 0;
2321 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2323 pSMB
->DataLengthLow
= cpu_to_le16(count
& 0xFFFF);
2324 pSMB
->DataLengthHigh
= cpu_to_le16(count
>> 16);
2325 /* header + 1 byte pad */
2326 smb_hdr_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 1;
2328 inc_rfc1001_len(pSMB
, count
+ 1);
2329 else /* wct == 12 */
2330 inc_rfc1001_len(pSMB
, count
+ 5); /* smb data starts later */
2332 pSMB
->ByteCount
= cpu_to_le16(count
+ 1);
2333 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2334 struct smb_com_writex_req
*pSMBW
=
2335 (struct smb_com_writex_req
*)pSMB
;
2336 pSMBW
->ByteCount
= cpu_to_le16(count
+ 5);
2338 iov
[0].iov_base
= pSMB
;
2340 iov
[0].iov_len
= smb_hdr_len
+ 4;
2341 else /* wct == 12 pad bigger by four bytes */
2342 iov
[0].iov_len
= smb_hdr_len
+ 8;
2344 rc
= SendReceive2(xid
, tcon
->ses
, iov
, n_vec
+ 1, &resp_buf_type
, 0,
2346 cifs_small_buf_release(pSMB
);
2347 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2349 cifs_dbg(FYI
, "Send error Write2 = %d\n", rc
);
2350 } else if (resp_buf_type
== 0) {
2351 /* presumably this can not happen, but best to be safe */
2354 WRITE_RSP
*pSMBr
= (WRITE_RSP
*)rsp_iov
.iov_base
;
2355 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2356 *nbytes
= (*nbytes
) << 16;
2357 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2360 * Mask off high 16 bits when bytes written as returned by the
2361 * server is greater than bytes requested by the client. OS/2
2362 * servers are known to set incorrect CountHigh values.
2364 if (*nbytes
> count
)
2368 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2370 /* Note: On -EAGAIN error only caller can retry on handle based calls
2371 since file handle passed in no longer valid */
2376 int cifs_lockv(const unsigned int xid
, struct cifs_tcon
*tcon
,
2377 const __u16 netfid
, const __u8 lock_type
, const __u32 num_unlock
,
2378 const __u32 num_lock
, LOCKING_ANDX_RANGE
*buf
)
2381 LOCK_REQ
*pSMB
= NULL
;
2383 struct kvec rsp_iov
;
2387 cifs_dbg(FYI
, "cifs_lockv num lock %d num unlock %d\n",
2388 num_lock
, num_unlock
);
2390 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2395 pSMB
->NumberOfLocks
= cpu_to_le16(num_lock
);
2396 pSMB
->NumberOfUnlocks
= cpu_to_le16(num_unlock
);
2397 pSMB
->LockType
= lock_type
;
2398 pSMB
->AndXCommand
= 0xFF; /* none */
2399 pSMB
->Fid
= netfid
; /* netfid stays le */
2401 count
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2402 inc_rfc1001_len(pSMB
, count
);
2403 pSMB
->ByteCount
= cpu_to_le16(count
);
2405 iov
[0].iov_base
= (char *)pSMB
;
2406 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4 -
2407 (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2408 iov
[1].iov_base
= (char *)buf
;
2409 iov
[1].iov_len
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2411 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2412 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 2, &resp_buf_type
, CIFS_NO_RESP
,
2414 cifs_small_buf_release(pSMB
);
2416 cifs_dbg(FYI
, "Send error in cifs_lockv = %d\n", rc
);
2422 CIFSSMBLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2423 const __u16 smb_file_id
, const __u32 netpid
, const __u64 len
,
2424 const __u64 offset
, const __u32 numUnlock
,
2425 const __u32 numLock
, const __u8 lockType
,
2426 const bool waitFlag
, const __u8 oplock_level
)
2429 LOCK_REQ
*pSMB
= NULL
;
2430 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2435 cifs_dbg(FYI
, "CIFSSMBLock timeout %d numLock %d\n",
2436 (int)waitFlag
, numLock
);
2437 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2442 if (lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
2443 /* no response expected */
2444 flags
= CIFS_ASYNC_OP
| CIFS_OBREAK_OP
;
2446 } else if (waitFlag
) {
2447 flags
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2448 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
2453 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
2454 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
2455 pSMB
->LockType
= lockType
;
2456 pSMB
->OplockLevel
= oplock_level
;
2457 pSMB
->AndXCommand
= 0xFF; /* none */
2458 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
2460 if ((numLock
!= 0) || (numUnlock
!= 0)) {
2461 pSMB
->Locks
[0].Pid
= cpu_to_le16(netpid
);
2462 /* BB where to store pid high? */
2463 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
2464 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
2465 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
2466 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
2467 count
= sizeof(LOCKING_ANDX_RANGE
);
2472 inc_rfc1001_len(pSMB
, count
);
2473 pSMB
->ByteCount
= cpu_to_le16(count
);
2476 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2477 (struct smb_hdr
*) pSMB
, &bytes_returned
);
2479 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)pSMB
, flags
);
2480 cifs_small_buf_release(pSMB
);
2481 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2483 cifs_dbg(FYI
, "Send error in Lock = %d\n", rc
);
2485 /* Note: On -EAGAIN error only caller can retry on handle based calls
2486 since file handle passed in no longer valid */
2491 CIFSSMBPosixLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2492 const __u16 smb_file_id
, const __u32 netpid
,
2493 const loff_t start_offset
, const __u64 len
,
2494 struct file_lock
*pLockData
, const __u16 lock_type
,
2495 const bool waitFlag
)
2497 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2498 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2499 struct cifs_posix_lock
*parm_data
;
2502 int bytes_returned
= 0;
2503 int resp_buf_type
= 0;
2504 __u16 params
, param_offset
, offset
, byte_count
, count
;
2506 struct kvec rsp_iov
;
2508 cifs_dbg(FYI
, "Posix Lock\n");
2510 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
2515 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)pSMB
;
2518 pSMB
->MaxSetupCount
= 0;
2521 pSMB
->Reserved2
= 0;
2522 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2523 offset
= param_offset
+ params
;
2525 count
= sizeof(struct cifs_posix_lock
);
2526 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2527 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2528 pSMB
->SetupCount
= 1;
2529 pSMB
->Reserved3
= 0;
2531 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
2533 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2534 byte_count
= 3 /* pad */ + params
+ count
;
2535 pSMB
->DataCount
= cpu_to_le16(count
);
2536 pSMB
->ParameterCount
= cpu_to_le16(params
);
2537 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2538 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2539 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2540 parm_data
= (struct cifs_posix_lock
*)
2541 (((char *) &pSMB
->hdr
.Protocol
) + offset
);
2543 parm_data
->lock_type
= cpu_to_le16(lock_type
);
2545 timeout
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2546 parm_data
->lock_flags
= cpu_to_le16(1);
2547 pSMB
->Timeout
= cpu_to_le32(-1);
2551 parm_data
->pid
= cpu_to_le32(netpid
);
2552 parm_data
->start
= cpu_to_le64(start_offset
);
2553 parm_data
->length
= cpu_to_le64(len
); /* normalize negative numbers */
2555 pSMB
->DataOffset
= cpu_to_le16(offset
);
2556 pSMB
->Fid
= smb_file_id
;
2557 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_LOCK
);
2558 pSMB
->Reserved4
= 0;
2559 inc_rfc1001_len(pSMB
, byte_count
);
2560 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2562 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2563 (struct smb_hdr
*) pSMBr
, &bytes_returned
);
2565 iov
[0].iov_base
= (char *)pSMB
;
2566 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
2567 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
2568 &resp_buf_type
, timeout
, &rsp_iov
);
2569 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)rsp_iov
.iov_base
;
2571 cifs_small_buf_release(pSMB
);
2574 cifs_dbg(FYI
, "Send error in Posix Lock = %d\n", rc
);
2575 } else if (pLockData
) {
2576 /* lock structure can be returned on get */
2579 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2581 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(*parm_data
)) {
2582 rc
= -EIO
; /* bad smb */
2585 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
2586 data_count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2587 if (data_count
< sizeof(struct cifs_posix_lock
)) {
2591 parm_data
= (struct cifs_posix_lock
*)
2592 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2593 if (parm_data
->lock_type
== cpu_to_le16(CIFS_UNLCK
))
2594 pLockData
->fl_type
= F_UNLCK
;
2596 if (parm_data
->lock_type
==
2597 cpu_to_le16(CIFS_RDLCK
))
2598 pLockData
->fl_type
= F_RDLCK
;
2599 else if (parm_data
->lock_type
==
2600 cpu_to_le16(CIFS_WRLCK
))
2601 pLockData
->fl_type
= F_WRLCK
;
2603 pLockData
->fl_start
= le64_to_cpu(parm_data
->start
);
2604 pLockData
->fl_end
= pLockData
->fl_start
+
2605 le64_to_cpu(parm_data
->length
) - 1;
2606 pLockData
->fl_pid
= -le32_to_cpu(parm_data
->pid
);
2611 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2613 /* Note: On -EAGAIN error only caller can retry on handle based calls
2614 since file handle passed in no longer valid */
2621 CIFSSMBClose(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2624 CLOSE_REQ
*pSMB
= NULL
;
2625 cifs_dbg(FYI
, "In CIFSSMBClose\n");
2627 /* do not retry on dead session on close */
2628 rc
= small_smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
);
2634 pSMB
->FileID
= (__u16
) smb_file_id
;
2635 pSMB
->LastWriteTime
= 0xFFFFFFFF;
2636 pSMB
->ByteCount
= 0;
2637 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2638 cifs_small_buf_release(pSMB
);
2639 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_closes
);
2642 /* EINTR is expected when user ctl-c to kill app */
2643 cifs_dbg(VFS
, "Send error in Close = %d\n", rc
);
2647 /* Since session is dead, file will be closed on server already */
2655 CIFSSMBFlush(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2658 FLUSH_REQ
*pSMB
= NULL
;
2659 cifs_dbg(FYI
, "In CIFSSMBFlush\n");
2661 rc
= small_smb_init(SMB_COM_FLUSH
, 1, tcon
, (void **) &pSMB
);
2665 pSMB
->FileID
= (__u16
) smb_file_id
;
2666 pSMB
->ByteCount
= 0;
2667 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2668 cifs_small_buf_release(pSMB
);
2669 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_flushes
);
2671 cifs_dbg(VFS
, "Send error in Flush = %d\n", rc
);
2677 CIFSSMBRename(const unsigned int xid
, struct cifs_tcon
*tcon
,
2678 const char *from_name
, const char *to_name
,
2679 struct cifs_sb_info
*cifs_sb
)
2682 RENAME_REQ
*pSMB
= NULL
;
2683 RENAME_RSP
*pSMBr
= NULL
;
2685 int name_len
, name_len2
;
2687 int remap
= cifs_remap(cifs_sb
);
2689 cifs_dbg(FYI
, "In CIFSSMBRename\n");
2691 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
2696 pSMB
->BufferFormat
= 0x04;
2697 pSMB
->SearchAttributes
=
2698 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2701 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2702 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2703 from_name
, PATH_MAX
,
2704 cifs_sb
->local_nls
, remap
);
2705 name_len
++; /* trailing null */
2707 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2708 /* protocol requires ASCII signature byte on Unicode string */
2709 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2711 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2712 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2714 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2715 name_len2
*= 2; /* convert to bytes */
2716 } else { /* BB improve the check for buffer overruns BB */
2717 name_len
= strnlen(from_name
, PATH_MAX
);
2718 name_len
++; /* trailing null */
2719 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
2720 name_len2
= strnlen(to_name
, PATH_MAX
);
2721 name_len2
++; /* trailing null */
2722 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2723 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
2724 name_len2
++; /* trailing null */
2725 name_len2
++; /* signature byte */
2728 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2729 inc_rfc1001_len(pSMB
, count
);
2730 pSMB
->ByteCount
= cpu_to_le16(count
);
2732 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2733 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2734 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_renames
);
2736 cifs_dbg(FYI
, "Send error in rename = %d\n", rc
);
2738 cifs_buf_release(pSMB
);
2746 int CIFSSMBRenameOpenFile(const unsigned int xid
, struct cifs_tcon
*pTcon
,
2747 int netfid
, const char *target_name
,
2748 const struct nls_table
*nls_codepage
, int remap
)
2750 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2751 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2752 struct set_file_rename
*rename_info
;
2754 char dummy_string
[30];
2756 int bytes_returned
= 0;
2758 __u16 params
, param_offset
, offset
, count
, byte_count
;
2760 cifs_dbg(FYI
, "Rename to File by handle\n");
2761 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
2767 pSMB
->MaxSetupCount
= 0;
2771 pSMB
->Reserved2
= 0;
2772 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2773 offset
= param_offset
+ params
;
2775 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2776 rename_info
= (struct set_file_rename
*) data_offset
;
2777 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2778 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2779 pSMB
->SetupCount
= 1;
2780 pSMB
->Reserved3
= 0;
2781 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2782 byte_count
= 3 /* pad */ + params
;
2783 pSMB
->ParameterCount
= cpu_to_le16(params
);
2784 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2785 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2786 pSMB
->DataOffset
= cpu_to_le16(offset
);
2787 /* construct random name ".cifs_tmp<inodenum><mid>" */
2788 rename_info
->overwrite
= cpu_to_le32(1);
2789 rename_info
->root_fid
= 0;
2790 /* unicode only call */
2791 if (target_name
== NULL
) {
2792 sprintf(dummy_string
, "cifs%x", pSMB
->hdr
.Mid
);
2794 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2795 dummy_string
, 24, nls_codepage
, remap
);
2798 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2799 target_name
, PATH_MAX
, nls_codepage
,
2802 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
2803 count
= 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str
);
2804 byte_count
+= count
;
2805 pSMB
->DataCount
= cpu_to_le16(count
);
2806 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2808 pSMB
->InformationLevel
=
2809 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
2810 pSMB
->Reserved4
= 0;
2811 inc_rfc1001_len(pSMB
, byte_count
);
2812 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2813 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
2814 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2815 cifs_stats_inc(&pTcon
->stats
.cifs_stats
.num_t2renames
);
2817 cifs_dbg(FYI
, "Send error in Rename (by file handle) = %d\n",
2820 cifs_buf_release(pSMB
);
2822 /* Note: On -EAGAIN error only caller can retry on handle based calls
2823 since file handle passed in no longer valid */
2829 CIFSSMBCopy(const unsigned int xid
, struct cifs_tcon
*tcon
,
2830 const char *fromName
, const __u16 target_tid
, const char *toName
,
2831 const int flags
, const struct nls_table
*nls_codepage
, int remap
)
2834 COPY_REQ
*pSMB
= NULL
;
2835 COPY_RSP
*pSMBr
= NULL
;
2837 int name_len
, name_len2
;
2840 cifs_dbg(FYI
, "In CIFSSMBCopy\n");
2842 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
2847 pSMB
->BufferFormat
= 0x04;
2848 pSMB
->Tid2
= target_tid
;
2850 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
2852 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2853 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2854 fromName
, PATH_MAX
, nls_codepage
,
2856 name_len
++; /* trailing null */
2858 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2859 /* protocol requires ASCII signature byte on Unicode string */
2860 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2862 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2863 toName
, PATH_MAX
, nls_codepage
, remap
);
2864 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2865 name_len2
*= 2; /* convert to bytes */
2866 } else { /* BB improve the check for buffer overruns BB */
2867 name_len
= strnlen(fromName
, PATH_MAX
);
2868 name_len
++; /* trailing null */
2869 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
2870 name_len2
= strnlen(toName
, PATH_MAX
);
2871 name_len2
++; /* trailing null */
2872 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2873 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
2874 name_len2
++; /* trailing null */
2875 name_len2
++; /* signature byte */
2878 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2879 inc_rfc1001_len(pSMB
, count
);
2880 pSMB
->ByteCount
= cpu_to_le16(count
);
2882 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2883 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2885 cifs_dbg(FYI
, "Send error in copy = %d with %d files copied\n",
2886 rc
, le16_to_cpu(pSMBr
->CopyCount
));
2888 cifs_buf_release(pSMB
);
2897 CIFSUnixCreateSymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2898 const char *fromName
, const char *toName
,
2899 const struct nls_table
*nls_codepage
, int remap
)
2901 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2902 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2905 int name_len_target
;
2907 int bytes_returned
= 0;
2908 __u16 params
, param_offset
, offset
, byte_count
;
2910 cifs_dbg(FYI
, "In Symlink Unix style\n");
2912 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2917 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2919 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fromName
,
2920 /* find define for this maxpathcomponent */
2921 PATH_MAX
, nls_codepage
, remap
);
2922 name_len
++; /* trailing null */
2925 } else { /* BB improve the check for buffer overruns BB */
2926 name_len
= strnlen(fromName
, PATH_MAX
);
2927 name_len
++; /* trailing null */
2928 strncpy(pSMB
->FileName
, fromName
, name_len
);
2930 params
= 6 + name_len
;
2931 pSMB
->MaxSetupCount
= 0;
2935 pSMB
->Reserved2
= 0;
2936 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2937 InformationLevel
) - 4;
2938 offset
= param_offset
+ params
;
2940 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2941 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2943 cifsConvertToUTF16((__le16
*) data_offset
, toName
,
2944 /* find define for this maxpathcomponent */
2945 PATH_MAX
, nls_codepage
, remap
);
2946 name_len_target
++; /* trailing null */
2947 name_len_target
*= 2;
2948 } else { /* BB improve the check for buffer overruns BB */
2949 name_len_target
= strnlen(toName
, PATH_MAX
);
2950 name_len_target
++; /* trailing null */
2951 strncpy(data_offset
, toName
, name_len_target
);
2954 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2955 /* BB find exact max on data count below from sess */
2956 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2957 pSMB
->SetupCount
= 1;
2958 pSMB
->Reserved3
= 0;
2959 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2960 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2961 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2962 pSMB
->ParameterCount
= cpu_to_le16(params
);
2963 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2964 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2965 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2966 pSMB
->DataOffset
= cpu_to_le16(offset
);
2967 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
2968 pSMB
->Reserved4
= 0;
2969 inc_rfc1001_len(pSMB
, byte_count
);
2970 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2971 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2972 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2973 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_symlinks
);
2975 cifs_dbg(FYI
, "Send error in SetPathInfo create symlink = %d\n",
2978 cifs_buf_release(pSMB
);
2981 goto createSymLinkRetry
;
2987 CIFSUnixCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2988 const char *fromName
, const char *toName
,
2989 const struct nls_table
*nls_codepage
, int remap
)
2991 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2992 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2995 int name_len_target
;
2997 int bytes_returned
= 0;
2998 __u16 params
, param_offset
, offset
, byte_count
;
3000 cifs_dbg(FYI
, "In Create Hard link Unix style\n");
3001 createHardLinkRetry
:
3002 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3007 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3008 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->FileName
, toName
,
3009 PATH_MAX
, nls_codepage
, remap
);
3010 name_len
++; /* trailing null */
3013 } else { /* BB improve the check for buffer overruns BB */
3014 name_len
= strnlen(toName
, PATH_MAX
);
3015 name_len
++; /* trailing null */
3016 strncpy(pSMB
->FileName
, toName
, name_len
);
3018 params
= 6 + name_len
;
3019 pSMB
->MaxSetupCount
= 0;
3023 pSMB
->Reserved2
= 0;
3024 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3025 InformationLevel
) - 4;
3026 offset
= param_offset
+ params
;
3028 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
3029 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3031 cifsConvertToUTF16((__le16
*) data_offset
, fromName
,
3032 PATH_MAX
, nls_codepage
, remap
);
3033 name_len_target
++; /* trailing null */
3034 name_len_target
*= 2;
3035 } else { /* BB improve the check for buffer overruns BB */
3036 name_len_target
= strnlen(fromName
, PATH_MAX
);
3037 name_len_target
++; /* trailing null */
3038 strncpy(data_offset
, fromName
, name_len_target
);
3041 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3042 /* BB find exact max on data count below from sess*/
3043 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3044 pSMB
->SetupCount
= 1;
3045 pSMB
->Reserved3
= 0;
3046 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3047 byte_count
= 3 /* pad */ + params
+ name_len_target
;
3048 pSMB
->ParameterCount
= cpu_to_le16(params
);
3049 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3050 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
3051 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3052 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3053 pSMB
->DataOffset
= cpu_to_le16(offset
);
3054 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
3055 pSMB
->Reserved4
= 0;
3056 inc_rfc1001_len(pSMB
, byte_count
);
3057 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3058 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3059 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3060 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3062 cifs_dbg(FYI
, "Send error in SetPathInfo (hard link) = %d\n",
3065 cifs_buf_release(pSMB
);
3067 goto createHardLinkRetry
;
3073 CIFSCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3074 const char *from_name
, const char *to_name
,
3075 struct cifs_sb_info
*cifs_sb
)
3078 NT_RENAME_REQ
*pSMB
= NULL
;
3079 RENAME_RSP
*pSMBr
= NULL
;
3081 int name_len
, name_len2
;
3083 int remap
= cifs_remap(cifs_sb
);
3085 cifs_dbg(FYI
, "In CIFSCreateHardLink\n");
3086 winCreateHardLinkRetry
:
3088 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
3093 pSMB
->SearchAttributes
=
3094 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
3096 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
3097 pSMB
->ClusterCount
= 0;
3099 pSMB
->BufferFormat
= 0x04;
3101 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3103 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, from_name
,
3104 PATH_MAX
, cifs_sb
->local_nls
, remap
);
3105 name_len
++; /* trailing null */
3108 /* protocol specifies ASCII buffer format (0x04) for unicode */
3109 pSMB
->OldFileName
[name_len
] = 0x04;
3110 pSMB
->OldFileName
[name_len
+ 1] = 0x00; /* pad */
3112 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
3113 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
3115 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
3116 name_len2
*= 2; /* convert to bytes */
3117 } else { /* BB improve the check for buffer overruns BB */
3118 name_len
= strnlen(from_name
, PATH_MAX
);
3119 name_len
++; /* trailing null */
3120 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
3121 name_len2
= strnlen(to_name
, PATH_MAX
);
3122 name_len2
++; /* trailing null */
3123 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
3124 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
3125 name_len2
++; /* trailing null */
3126 name_len2
++; /* signature byte */
3129 count
= 1 /* string type byte */ + name_len
+ name_len2
;
3130 inc_rfc1001_len(pSMB
, count
);
3131 pSMB
->ByteCount
= cpu_to_le16(count
);
3133 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3134 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3135 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3137 cifs_dbg(FYI
, "Send error in hard link (NT rename) = %d\n", rc
);
3139 cifs_buf_release(pSMB
);
3141 goto winCreateHardLinkRetry
;
3147 CIFSSMBUnixQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3148 const unsigned char *searchName
, char **symlinkinfo
,
3149 const struct nls_table
*nls_codepage
, int remap
)
3151 /* SMB_QUERY_FILE_UNIX_LINK */
3152 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3153 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3157 __u16 params
, byte_count
;
3160 cifs_dbg(FYI
, "In QPathSymLinkInfo (Unix) for path %s\n", searchName
);
3163 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3168 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3170 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3171 searchName
, PATH_MAX
, nls_codepage
,
3173 name_len
++; /* trailing null */
3175 } else { /* BB improve the check for buffer overruns BB */
3176 name_len
= strnlen(searchName
, PATH_MAX
);
3177 name_len
++; /* trailing null */
3178 strncpy(pSMB
->FileName
, searchName
, name_len
);
3181 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3182 pSMB
->TotalDataCount
= 0;
3183 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3184 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3185 pSMB
->MaxSetupCount
= 0;
3189 pSMB
->Reserved2
= 0;
3190 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3191 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3192 pSMB
->DataCount
= 0;
3193 pSMB
->DataOffset
= 0;
3194 pSMB
->SetupCount
= 1;
3195 pSMB
->Reserved3
= 0;
3196 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3197 byte_count
= params
+ 1 /* pad */ ;
3198 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3199 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3200 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
3201 pSMB
->Reserved4
= 0;
3202 inc_rfc1001_len(pSMB
, byte_count
);
3203 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3205 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3206 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3208 cifs_dbg(FYI
, "Send error in QuerySymLinkInfo = %d\n", rc
);
3210 /* decode response */
3212 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3213 /* BB also check enough total bytes returned */
3214 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3218 u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3220 data_start
= ((char *) &pSMBr
->hdr
.Protocol
) +
3221 le16_to_cpu(pSMBr
->t2
.DataOffset
);
3223 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3228 /* BB FIXME investigate remapping reserved chars here */
3229 *symlinkinfo
= cifs_strndup_from_utf16(data_start
,
3230 count
, is_unicode
, nls_codepage
);
3235 cifs_buf_release(pSMB
);
3237 goto querySymLinkRetry
;
3242 * Recent Windows versions now create symlinks more frequently
3243 * and they use the "reparse point" mechanism below. We can of course
3244 * do symlinks nicely to Samba and other servers which support the
3245 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3246 * "MF" symlinks optionally, but for recent Windows we really need to
3247 * reenable the code below and fix the cifs_symlink callers to handle this.
3248 * In the interim this code has been moved to its own config option so
3249 * it is not compiled in by default until callers fixed up and more tested.
3252 CIFSSMBQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3253 __u16 fid
, char **symlinkinfo
,
3254 const struct nls_table
*nls_codepage
)
3258 struct smb_com_transaction_ioctl_req
*pSMB
;
3259 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3261 unsigned int sub_len
;
3263 struct reparse_symlink_data
*reparse_buf
;
3264 struct reparse_posix_data
*posix_buf
;
3265 __u32 data_offset
, data_count
;
3268 cifs_dbg(FYI
, "In Windows reparse style QueryLink for fid %u\n", fid
);
3269 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3274 pSMB
->TotalParameterCount
= 0 ;
3275 pSMB
->TotalDataCount
= 0;
3276 pSMB
->MaxParameterCount
= cpu_to_le32(2);
3277 /* BB find exact data count max from sess structure BB */
3278 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3279 pSMB
->MaxSetupCount
= 4;
3281 pSMB
->ParameterOffset
= 0;
3282 pSMB
->DataCount
= 0;
3283 pSMB
->DataOffset
= 0;
3284 pSMB
->SetupCount
= 4;
3285 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3286 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3287 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
3288 pSMB
->IsFsctl
= 1; /* FSCTL */
3289 pSMB
->IsRootFlag
= 0;
3290 pSMB
->Fid
= fid
; /* file handle always le */
3291 pSMB
->ByteCount
= 0;
3293 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3294 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3296 cifs_dbg(FYI
, "Send error in QueryReparseLinkInfo = %d\n", rc
);
3300 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3301 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3302 if (get_bcc(&pSMBr
->hdr
) < 2 || data_offset
> 512) {
3303 /* BB also check enough total bytes returned */
3304 rc
= -EIO
; /* bad smb */
3307 if (!data_count
|| (data_count
> 2048)) {
3309 cifs_dbg(FYI
, "Invalid return data count on get reparse info ioctl\n");
3312 end_of_smb
= 2 + get_bcc(&pSMBr
->hdr
) + (char *)&pSMBr
->ByteCount
;
3313 reparse_buf
= (struct reparse_symlink_data
*)
3314 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
3315 if ((char *)reparse_buf
>= end_of_smb
) {
3319 if (reparse_buf
->ReparseTag
== cpu_to_le32(IO_REPARSE_TAG_NFS
)) {
3320 cifs_dbg(FYI
, "NFS style reparse tag\n");
3321 posix_buf
= (struct reparse_posix_data
*)reparse_buf
;
3323 if (posix_buf
->InodeType
!= cpu_to_le64(NFS_SPECFILE_LNK
)) {
3324 cifs_dbg(FYI
, "unsupported file type 0x%llx\n",
3325 le64_to_cpu(posix_buf
->InodeType
));
3330 sub_len
= le16_to_cpu(reparse_buf
->ReparseDataLength
);
3331 if (posix_buf
->PathBuffer
+ sub_len
> end_of_smb
) {
3332 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3336 *symlinkinfo
= cifs_strndup_from_utf16(posix_buf
->PathBuffer
,
3337 sub_len
, is_unicode
, nls_codepage
);
3339 } else if (reparse_buf
->ReparseTag
!=
3340 cpu_to_le32(IO_REPARSE_TAG_SYMLINK
)) {
3345 /* Reparse tag is NTFS symlink */
3346 sub_start
= le16_to_cpu(reparse_buf
->SubstituteNameOffset
) +
3347 reparse_buf
->PathBuffer
;
3348 sub_len
= le16_to_cpu(reparse_buf
->SubstituteNameLength
);
3349 if (sub_start
+ sub_len
> end_of_smb
) {
3350 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3354 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3359 /* BB FIXME investigate remapping reserved chars here */
3360 *symlinkinfo
= cifs_strndup_from_utf16(sub_start
, sub_len
, is_unicode
,
3365 cifs_buf_release(pSMB
);
3368 * Note: On -EAGAIN error only caller can retry on handle based calls
3369 * since file handle passed in no longer valid.
3375 CIFSSMB_set_compression(const unsigned int xid
, struct cifs_tcon
*tcon
,
3380 struct smb_com_transaction_compr_ioctl_req
*pSMB
;
3381 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3383 cifs_dbg(FYI
, "Set compression for %u\n", fid
);
3384 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3389 pSMB
->compression_state
= cpu_to_le16(COMPRESSION_FORMAT_DEFAULT
);
3391 pSMB
->TotalParameterCount
= 0;
3392 pSMB
->TotalDataCount
= cpu_to_le32(2);
3393 pSMB
->MaxParameterCount
= 0;
3394 pSMB
->MaxDataCount
= 0;
3395 pSMB
->MaxSetupCount
= 4;
3397 pSMB
->ParameterOffset
= 0;
3398 pSMB
->DataCount
= cpu_to_le32(2);
3400 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req
,
3401 compression_state
) - 4); /* 84 */
3402 pSMB
->SetupCount
= 4;
3403 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3404 pSMB
->ParameterCount
= 0;
3405 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_SET_COMPRESSION
);
3406 pSMB
->IsFsctl
= 1; /* FSCTL */
3407 pSMB
->IsRootFlag
= 0;
3408 pSMB
->Fid
= fid
; /* file handle always le */
3409 /* 3 byte pad, followed by 2 byte compress state */
3410 pSMB
->ByteCount
= cpu_to_le16(5);
3411 inc_rfc1001_len(pSMB
, 5);
3413 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3414 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3416 cifs_dbg(FYI
, "Send error in SetCompression = %d\n", rc
);
3418 cifs_buf_release(pSMB
);
3421 * Note: On -EAGAIN error only caller can retry on handle based calls
3422 * since file handle passed in no longer valid.
3428 #ifdef CONFIG_CIFS_POSIX
3430 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3431 static void cifs_convert_ace(struct posix_acl_xattr_entry
*ace
,
3432 struct cifs_posix_ace
*cifs_ace
)
3434 /* u8 cifs fields do not need le conversion */
3435 ace
->e_perm
= cpu_to_le16(cifs_ace
->cifs_e_perm
);
3436 ace
->e_tag
= cpu_to_le16(cifs_ace
->cifs_e_tag
);
3437 ace
->e_id
= cpu_to_le32(le64_to_cpu(cifs_ace
->cifs_uid
));
3439 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3440 ace->e_perm, ace->e_tag, ace->e_id);
3446 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3447 static int cifs_copy_posix_acl(char *trgt
, char *src
, const int buflen
,
3448 const int acl_type
, const int size_of_data_area
)
3453 struct cifs_posix_ace
*pACE
;
3454 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)src
;
3455 struct posix_acl_xattr_header
*local_acl
= (void *)trgt
;
3457 if (le16_to_cpu(cifs_acl
->version
) != CIFS_ACL_VERSION
)
3460 if (acl_type
== ACL_TYPE_ACCESS
) {
3461 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3462 pACE
= &cifs_acl
->ace_array
[0];
3463 size
= sizeof(struct cifs_posix_acl
);
3464 size
+= sizeof(struct cifs_posix_ace
) * count
;
3465 /* check if we would go beyond end of SMB */
3466 if (size_of_data_area
< size
) {
3467 cifs_dbg(FYI
, "bad CIFS POSIX ACL size %d vs. %d\n",
3468 size_of_data_area
, size
);
3471 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3472 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3473 size
= sizeof(struct cifs_posix_acl
);
3474 size
+= sizeof(struct cifs_posix_ace
) * count
;
3475 /* skip past access ACEs to get to default ACEs */
3476 pACE
= &cifs_acl
->ace_array
[count
];
3477 count
= le16_to_cpu(cifs_acl
->default_entry_count
);
3478 size
+= sizeof(struct cifs_posix_ace
) * count
;
3479 /* check if we would go beyond end of SMB */
3480 if (size_of_data_area
< size
)
3487 size
= posix_acl_xattr_size(count
);
3488 if ((buflen
== 0) || (local_acl
== NULL
)) {
3489 /* used to query ACL EA size */
3490 } else if (size
> buflen
) {
3492 } else /* buffer big enough */ {
3493 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3495 local_acl
->a_version
= cpu_to_le32(POSIX_ACL_XATTR_VERSION
);
3496 for (i
= 0; i
< count
; i
++) {
3497 cifs_convert_ace(&ace
[i
], pACE
);
3504 static __u16
convert_ace_to_cifs_ace(struct cifs_posix_ace
*cifs_ace
,
3505 const struct posix_acl_xattr_entry
*local_ace
)
3507 __u16 rc
= 0; /* 0 = ACL converted ok */
3509 cifs_ace
->cifs_e_perm
= le16_to_cpu(local_ace
->e_perm
);
3510 cifs_ace
->cifs_e_tag
= le16_to_cpu(local_ace
->e_tag
);
3511 /* BB is there a better way to handle the large uid? */
3512 if (local_ace
->e_id
== cpu_to_le32(-1)) {
3513 /* Probably no need to le convert -1 on any arch but can not hurt */
3514 cifs_ace
->cifs_uid
= cpu_to_le64(-1);
3516 cifs_ace
->cifs_uid
= cpu_to_le64(le32_to_cpu(local_ace
->e_id
));
3518 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3519 ace->e_perm, ace->e_tag, ace->e_id);
3524 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3525 static __u16
ACL_to_cifs_posix(char *parm_data
, const char *pACL
,
3526 const int buflen
, const int acl_type
)
3529 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)parm_data
;
3530 struct posix_acl_xattr_header
*local_acl
= (void *)pACL
;
3531 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3535 if ((buflen
== 0) || (pACL
== NULL
) || (cifs_acl
== NULL
))
3538 count
= posix_acl_xattr_count((size_t)buflen
);
3539 cifs_dbg(FYI
, "setting acl with %d entries from buf of length %d and version of %d\n",
3540 count
, buflen
, le32_to_cpu(local_acl
->a_version
));
3541 if (le32_to_cpu(local_acl
->a_version
) != 2) {
3542 cifs_dbg(FYI
, "unknown POSIX ACL version %d\n",
3543 le32_to_cpu(local_acl
->a_version
));
3546 cifs_acl
->version
= cpu_to_le16(1);
3547 if (acl_type
== ACL_TYPE_ACCESS
) {
3548 cifs_acl
->access_entry_count
= cpu_to_le16(count
);
3549 cifs_acl
->default_entry_count
= cpu_to_le16(0xFFFF);
3550 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3551 cifs_acl
->default_entry_count
= cpu_to_le16(count
);
3552 cifs_acl
->access_entry_count
= cpu_to_le16(0xFFFF);
3554 cifs_dbg(FYI
, "unknown ACL type %d\n", acl_type
);
3557 for (i
= 0; i
< count
; i
++) {
3558 rc
= convert_ace_to_cifs_ace(&cifs_acl
->ace_array
[i
], &ace
[i
]);
3560 /* ACE not converted */
3565 rc
= (__u16
)(count
* sizeof(struct cifs_posix_ace
));
3566 rc
+= sizeof(struct cifs_posix_acl
);
3567 /* BB add check to make sure ACL does not overflow SMB */
3573 CIFSSMBGetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3574 const unsigned char *searchName
,
3575 char *acl_inf
, const int buflen
, const int acl_type
,
3576 const struct nls_table
*nls_codepage
, int remap
)
3578 /* SMB_QUERY_POSIX_ACL */
3579 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3580 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3584 __u16 params
, byte_count
;
3586 cifs_dbg(FYI
, "In GetPosixACL (Unix) for path %s\n", searchName
);
3589 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3594 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3596 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3597 searchName
, PATH_MAX
, nls_codepage
,
3599 name_len
++; /* trailing null */
3601 pSMB
->FileName
[name_len
] = 0;
3602 pSMB
->FileName
[name_len
+1] = 0;
3603 } else { /* BB improve the check for buffer overruns BB */
3604 name_len
= strnlen(searchName
, PATH_MAX
);
3605 name_len
++; /* trailing null */
3606 strncpy(pSMB
->FileName
, searchName
, name_len
);
3609 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3610 pSMB
->TotalDataCount
= 0;
3611 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3612 /* BB find exact max data count below from sess structure BB */
3613 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3614 pSMB
->MaxSetupCount
= 0;
3618 pSMB
->Reserved2
= 0;
3619 pSMB
->ParameterOffset
= cpu_to_le16(
3620 offsetof(struct smb_com_transaction2_qpi_req
,
3621 InformationLevel
) - 4);
3622 pSMB
->DataCount
= 0;
3623 pSMB
->DataOffset
= 0;
3624 pSMB
->SetupCount
= 1;
3625 pSMB
->Reserved3
= 0;
3626 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3627 byte_count
= params
+ 1 /* pad */ ;
3628 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3629 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3630 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_ACL
);
3631 pSMB
->Reserved4
= 0;
3632 inc_rfc1001_len(pSMB
, byte_count
);
3633 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3635 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3636 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3637 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3639 cifs_dbg(FYI
, "Send error in Query POSIX ACL = %d\n", rc
);
3641 /* decode response */
3643 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3644 /* BB also check enough total bytes returned */
3645 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3646 rc
= -EIO
; /* bad smb */
3648 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3649 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3650 rc
= cifs_copy_posix_acl(acl_inf
,
3651 (char *)&pSMBr
->hdr
.Protocol
+data_offset
,
3652 buflen
, acl_type
, count
);
3655 cifs_buf_release(pSMB
);
3662 CIFSSMBSetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3663 const unsigned char *fileName
,
3664 const char *local_acl
, const int buflen
,
3666 const struct nls_table
*nls_codepage
, int remap
)
3668 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3669 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3673 int bytes_returned
= 0;
3674 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
3676 cifs_dbg(FYI
, "In SetPosixACL (Unix) for path %s\n", fileName
);
3678 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3682 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3684 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
3685 PATH_MAX
, nls_codepage
, remap
);
3686 name_len
++; /* trailing null */
3688 } else { /* BB improve the check for buffer overruns BB */
3689 name_len
= strnlen(fileName
, PATH_MAX
);
3690 name_len
++; /* trailing null */
3691 strncpy(pSMB
->FileName
, fileName
, name_len
);
3693 params
= 6 + name_len
;
3694 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3695 /* BB find max SMB size from sess */
3696 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3697 pSMB
->MaxSetupCount
= 0;
3701 pSMB
->Reserved2
= 0;
3702 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3703 InformationLevel
) - 4;
3704 offset
= param_offset
+ params
;
3705 parm_data
= ((char *) &pSMB
->hdr
.Protocol
) + offset
;
3706 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3708 /* convert to on the wire format for POSIX ACL */
3709 data_count
= ACL_to_cifs_posix(parm_data
, local_acl
, buflen
, acl_type
);
3711 if (data_count
== 0) {
3713 goto setACLerrorExit
;
3715 pSMB
->DataOffset
= cpu_to_le16(offset
);
3716 pSMB
->SetupCount
= 1;
3717 pSMB
->Reserved3
= 0;
3718 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3719 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_ACL
);
3720 byte_count
= 3 /* pad */ + params
+ data_count
;
3721 pSMB
->DataCount
= cpu_to_le16(data_count
);
3722 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3723 pSMB
->ParameterCount
= cpu_to_le16(params
);
3724 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3725 pSMB
->Reserved4
= 0;
3726 inc_rfc1001_len(pSMB
, byte_count
);
3727 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3728 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3729 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3731 cifs_dbg(FYI
, "Set POSIX ACL returned %d\n", rc
);
3734 cifs_buf_release(pSMB
);
3740 /* BB fix tabs in this function FIXME BB */
3742 CIFSGetExtAttr(const unsigned int xid
, struct cifs_tcon
*tcon
,
3743 const int netfid
, __u64
*pExtAttrBits
, __u64
*pMask
)
3746 struct smb_t2_qfi_req
*pSMB
= NULL
;
3747 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3749 __u16 params
, byte_count
;
3751 cifs_dbg(FYI
, "In GetExtAttr\n");
3756 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3761 params
= 2 /* level */ + 2 /* fid */;
3762 pSMB
->t2
.TotalDataCount
= 0;
3763 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3764 /* BB find exact max data count below from sess structure BB */
3765 pSMB
->t2
.MaxDataCount
= cpu_to_le16(4000);
3766 pSMB
->t2
.MaxSetupCount
= 0;
3767 pSMB
->t2
.Reserved
= 0;
3769 pSMB
->t2
.Timeout
= 0;
3770 pSMB
->t2
.Reserved2
= 0;
3771 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3773 pSMB
->t2
.DataCount
= 0;
3774 pSMB
->t2
.DataOffset
= 0;
3775 pSMB
->t2
.SetupCount
= 1;
3776 pSMB
->t2
.Reserved3
= 0;
3777 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3778 byte_count
= params
+ 1 /* pad */ ;
3779 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3780 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3781 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_ATTR_FLAGS
);
3784 inc_rfc1001_len(pSMB
, byte_count
);
3785 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3787 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3788 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3790 cifs_dbg(FYI
, "error %d in GetExtAttr\n", rc
);
3792 /* decode response */
3793 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3794 /* BB also check enough total bytes returned */
3795 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3796 /* If rc should we check for EOPNOSUPP and
3797 disable the srvino flag? or in caller? */
3798 rc
= -EIO
; /* bad smb */
3800 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3801 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3802 struct file_chattr_info
*pfinfo
;
3803 /* BB Do we need a cast or hash here ? */
3805 cifs_dbg(FYI
, "Illegal size ret in GetExtAttr\n");
3809 pfinfo
= (struct file_chattr_info
*)
3810 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
3811 *pExtAttrBits
= le64_to_cpu(pfinfo
->mode
);
3812 *pMask
= le64_to_cpu(pfinfo
->mask
);
3816 cifs_buf_release(pSMB
);
3818 goto GetExtAttrRetry
;
3822 #endif /* CONFIG_POSIX */
3824 #ifdef CONFIG_CIFS_ACL
3826 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3827 * all NT TRANSACTS that we init here have total parm and data under about 400
3828 * bytes (to fit in small cifs buffer size), which is the case so far, it
3829 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3830 * returned setup area) and MaxParameterCount (returned parms size) must be set
3834 smb_init_nttransact(const __u16 sub_command
, const int setup_count
,
3835 const int parm_len
, struct cifs_tcon
*tcon
,
3840 struct smb_com_ntransact_req
*pSMB
;
3842 rc
= small_smb_init(SMB_COM_NT_TRANSACT
, 19 + setup_count
, tcon
,
3846 *ret_buf
= (void *)pSMB
;
3848 pSMB
->TotalParameterCount
= cpu_to_le32(parm_len
);
3849 pSMB
->TotalDataCount
= 0;
3850 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3851 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3852 pSMB
->DataCount
= pSMB
->TotalDataCount
;
3853 temp_offset
= offsetof(struct smb_com_ntransact_req
, Parms
) +
3854 (setup_count
* 2) - 4 /* for rfc1001 length itself */;
3855 pSMB
->ParameterOffset
= cpu_to_le32(temp_offset
);
3856 pSMB
->DataOffset
= cpu_to_le32(temp_offset
+ parm_len
);
3857 pSMB
->SetupCount
= setup_count
; /* no need to le convert byte fields */
3858 pSMB
->SubCommand
= cpu_to_le16(sub_command
);
3863 validate_ntransact(char *buf
, char **ppparm
, char **ppdata
,
3864 __u32
*pparmlen
, __u32
*pdatalen
)
3867 __u32 data_count
, data_offset
, parm_count
, parm_offset
;
3868 struct smb_com_ntransact_rsp
*pSMBr
;
3877 pSMBr
= (struct smb_com_ntransact_rsp
*)buf
;
3879 bcc
= get_bcc(&pSMBr
->hdr
);
3880 end_of_smb
= 2 /* sizeof byte count */ + bcc
+
3881 (char *)&pSMBr
->ByteCount
;
3883 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3884 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3885 parm_offset
= le32_to_cpu(pSMBr
->ParameterOffset
);
3886 parm_count
= le32_to_cpu(pSMBr
->ParameterCount
);
3888 *ppparm
= (char *)&pSMBr
->hdr
.Protocol
+ parm_offset
;
3889 *ppdata
= (char *)&pSMBr
->hdr
.Protocol
+ data_offset
;
3891 /* should we also check that parm and data areas do not overlap? */
3892 if (*ppparm
> end_of_smb
) {
3893 cifs_dbg(FYI
, "parms start after end of smb\n");
3895 } else if (parm_count
+ *ppparm
> end_of_smb
) {
3896 cifs_dbg(FYI
, "parm end after end of smb\n");
3898 } else if (*ppdata
> end_of_smb
) {
3899 cifs_dbg(FYI
, "data starts after end of smb\n");
3901 } else if (data_count
+ *ppdata
> end_of_smb
) {
3902 cifs_dbg(FYI
, "data %p + count %d (%p) past smb end %p start %p\n",
3903 *ppdata
, data_count
, (data_count
+ *ppdata
),
3906 } else if (parm_count
+ data_count
> bcc
) {
3907 cifs_dbg(FYI
, "parm count and data count larger than SMB\n");
3910 *pdatalen
= data_count
;
3911 *pparmlen
= parm_count
;
3915 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3917 CIFSSMBGetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3918 struct cifs_ntsd
**acl_inf
, __u32
*pbuflen
)
3922 QUERY_SEC_DESC_REQ
*pSMB
;
3924 struct kvec rsp_iov
;
3926 cifs_dbg(FYI
, "GetCifsACL\n");
3931 rc
= smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC
, 0,
3932 8 /* parm len */, tcon
, (void **) &pSMB
);
3936 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3937 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3938 pSMB
->MaxSetupCount
= 0;
3939 pSMB
->Fid
= fid
; /* file handle always le */
3940 pSMB
->AclFlags
= cpu_to_le32(CIFS_ACL_OWNER
| CIFS_ACL_GROUP
|
3942 pSMB
->ByteCount
= cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3943 inc_rfc1001_len(pSMB
, 11);
3944 iov
[0].iov_base
= (char *)pSMB
;
3945 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
3947 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovec */, &buf_type
,
3949 cifs_small_buf_release(pSMB
);
3950 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3952 cifs_dbg(FYI
, "Send error in QuerySecDesc = %d\n", rc
);
3953 } else { /* decode response */
3957 struct smb_com_ntransact_rsp
*pSMBr
;
3960 /* validate_nttransact */
3961 rc
= validate_ntransact(rsp_iov
.iov_base
, (char **)&parm
,
3962 &pdata
, &parm_len
, pbuflen
);
3965 pSMBr
= (struct smb_com_ntransact_rsp
*)rsp_iov
.iov_base
;
3967 cifs_dbg(FYI
, "smb %p parm %p data %p\n",
3968 pSMBr
, parm
, *acl_inf
);
3970 if (le32_to_cpu(pSMBr
->ParameterCount
) != 4) {
3971 rc
= -EIO
; /* bad smb */
3976 /* BB check that data area is minimum length and as big as acl_len */
3978 acl_len
= le32_to_cpu(*parm
);
3979 if (acl_len
!= *pbuflen
) {
3980 cifs_dbg(VFS
, "acl length %d does not match %d\n",
3982 if (*pbuflen
> acl_len
)
3986 /* check if buffer is big enough for the acl
3987 header followed by the smallest SID */
3988 if ((*pbuflen
< sizeof(struct cifs_ntsd
) + 8) ||
3989 (*pbuflen
>= 64 * 1024)) {
3990 cifs_dbg(VFS
, "bad acl length %d\n", *pbuflen
);
3994 *acl_inf
= kmemdup(pdata
, *pbuflen
, GFP_KERNEL
);
3995 if (*acl_inf
== NULL
) {
4002 free_rsp_buf(buf_type
, rsp_iov
.iov_base
);
4007 CIFSSMBSetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
4008 struct cifs_ntsd
*pntsd
, __u32 acllen
, int aclflag
)
4010 __u16 byte_count
, param_count
, data_count
, param_offset
, data_offset
;
4012 int bytes_returned
= 0;
4013 SET_SEC_DESC_REQ
*pSMB
= NULL
;
4017 rc
= smb_init(SMB_COM_NT_TRANSACT
, 19, tcon
, (void **) &pSMB
, &pSMBr
);
4021 pSMB
->MaxSetupCount
= 0;
4025 param_offset
= offsetof(struct smb_com_transaction_ssec_req
, Fid
) - 4;
4026 data_count
= acllen
;
4027 data_offset
= param_offset
+ param_count
;
4028 byte_count
= 3 /* pad */ + param_count
;
4030 pSMB
->DataCount
= cpu_to_le32(data_count
);
4031 pSMB
->TotalDataCount
= pSMB
->DataCount
;
4032 pSMB
->MaxParameterCount
= cpu_to_le32(4);
4033 pSMB
->MaxDataCount
= cpu_to_le32(16384);
4034 pSMB
->ParameterCount
= cpu_to_le32(param_count
);
4035 pSMB
->ParameterOffset
= cpu_to_le32(param_offset
);
4036 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4037 pSMB
->DataOffset
= cpu_to_le32(data_offset
);
4038 pSMB
->SetupCount
= 0;
4039 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC
);
4040 pSMB
->ByteCount
= cpu_to_le16(byte_count
+data_count
);
4042 pSMB
->Fid
= fid
; /* file handle always le */
4043 pSMB
->Reserved2
= 0;
4044 pSMB
->AclFlags
= cpu_to_le32(aclflag
);
4046 if (pntsd
&& acllen
) {
4047 memcpy((char *)pSMBr
+ offsetof(struct smb_hdr
, Protocol
) +
4048 data_offset
, pntsd
, acllen
);
4049 inc_rfc1001_len(pSMB
, byte_count
+ data_count
);
4051 inc_rfc1001_len(pSMB
, byte_count
);
4053 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4054 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4056 cifs_dbg(FYI
, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4057 bytes_returned
, rc
);
4059 cifs_dbg(FYI
, "Set CIFS ACL returned %d\n", rc
);
4060 cifs_buf_release(pSMB
);
4063 goto setCifsAclRetry
;
4068 #endif /* CONFIG_CIFS_ACL */
4070 /* Legacy Query Path Information call for lookup to old servers such
4073 SMBQueryInformation(const unsigned int xid
, struct cifs_tcon
*tcon
,
4074 const char *search_name
, FILE_ALL_INFO
*data
,
4075 const struct nls_table
*nls_codepage
, int remap
)
4077 QUERY_INFORMATION_REQ
*pSMB
;
4078 QUERY_INFORMATION_RSP
*pSMBr
;
4083 cifs_dbg(FYI
, "In SMBQPath path %s\n", search_name
);
4085 rc
= smb_init(SMB_COM_QUERY_INFORMATION
, 0, tcon
, (void **) &pSMB
,
4090 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4092 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4093 search_name
, PATH_MAX
, nls_codepage
,
4095 name_len
++; /* trailing null */
4098 name_len
= strnlen(search_name
, PATH_MAX
);
4099 name_len
++; /* trailing null */
4100 strncpy(pSMB
->FileName
, search_name
, name_len
);
4102 pSMB
->BufferFormat
= 0x04;
4103 name_len
++; /* account for buffer type byte */
4104 inc_rfc1001_len(pSMB
, (__u16
)name_len
);
4105 pSMB
->ByteCount
= cpu_to_le16(name_len
);
4107 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4108 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4110 cifs_dbg(FYI
, "Send error in QueryInfo = %d\n", rc
);
4112 struct timespec64 ts
;
4113 __u32 time
= le32_to_cpu(pSMBr
->last_write_time
);
4115 /* decode response */
4116 /* BB FIXME - add time zone adjustment BB */
4117 memset(data
, 0, sizeof(FILE_ALL_INFO
));
4120 /* decode time fields */
4121 data
->ChangeTime
= cpu_to_le64(cifs_UnixTimeToNT(ts
));
4122 data
->LastWriteTime
= data
->ChangeTime
;
4123 data
->LastAccessTime
= 0;
4124 data
->AllocationSize
=
4125 cpu_to_le64(le32_to_cpu(pSMBr
->size
));
4126 data
->EndOfFile
= data
->AllocationSize
;
4128 cpu_to_le32(le16_to_cpu(pSMBr
->attr
));
4130 rc
= -EIO
; /* bad buffer passed in */
4132 cifs_buf_release(pSMB
);
4141 CIFSSMBQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4142 u16 netfid
, FILE_ALL_INFO
*pFindData
)
4144 struct smb_t2_qfi_req
*pSMB
= NULL
;
4145 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4148 __u16 params
, byte_count
;
4151 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4156 params
= 2 /* level */ + 2 /* fid */;
4157 pSMB
->t2
.TotalDataCount
= 0;
4158 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4159 /* BB find exact max data count below from sess structure BB */
4160 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4161 pSMB
->t2
.MaxSetupCount
= 0;
4162 pSMB
->t2
.Reserved
= 0;
4164 pSMB
->t2
.Timeout
= 0;
4165 pSMB
->t2
.Reserved2
= 0;
4166 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4168 pSMB
->t2
.DataCount
= 0;
4169 pSMB
->t2
.DataOffset
= 0;
4170 pSMB
->t2
.SetupCount
= 1;
4171 pSMB
->t2
.Reserved3
= 0;
4172 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4173 byte_count
= params
+ 1 /* pad */ ;
4174 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4175 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4176 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4179 inc_rfc1001_len(pSMB
, byte_count
);
4180 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4182 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4183 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4185 cifs_dbg(FYI
, "Send error in QFileInfo = %d", rc
);
4186 } else { /* decode response */
4187 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4189 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4191 else if (get_bcc(&pSMBr
->hdr
) < 40)
4192 rc
= -EIO
; /* bad smb */
4193 else if (pFindData
) {
4194 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4195 memcpy((char *) pFindData
,
4196 (char *) &pSMBr
->hdr
.Protocol
+
4197 data_offset
, sizeof(FILE_ALL_INFO
));
4201 cifs_buf_release(pSMB
);
4203 goto QFileInfoRetry
;
4209 CIFSSMBQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4210 const char *search_name
, FILE_ALL_INFO
*data
,
4211 int legacy
/* old style infolevel */,
4212 const struct nls_table
*nls_codepage
, int remap
)
4214 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4215 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4216 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4220 __u16 params
, byte_count
;
4222 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4224 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4229 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4231 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, search_name
,
4232 PATH_MAX
, nls_codepage
, remap
);
4233 name_len
++; /* trailing null */
4235 } else { /* BB improve the check for buffer overruns BB */
4236 name_len
= strnlen(search_name
, PATH_MAX
);
4237 name_len
++; /* trailing null */
4238 strncpy(pSMB
->FileName
, search_name
, name_len
);
4241 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4242 pSMB
->TotalDataCount
= 0;
4243 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4244 /* BB find exact max SMB PDU from sess structure BB */
4245 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4246 pSMB
->MaxSetupCount
= 0;
4250 pSMB
->Reserved2
= 0;
4251 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4252 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4253 pSMB
->DataCount
= 0;
4254 pSMB
->DataOffset
= 0;
4255 pSMB
->SetupCount
= 1;
4256 pSMB
->Reserved3
= 0;
4257 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4258 byte_count
= params
+ 1 /* pad */ ;
4259 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4260 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4262 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
4264 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4265 pSMB
->Reserved4
= 0;
4266 inc_rfc1001_len(pSMB
, byte_count
);
4267 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4269 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4270 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4272 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4273 } else { /* decode response */
4274 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4276 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4278 else if (!legacy
&& get_bcc(&pSMBr
->hdr
) < 40)
4279 rc
= -EIO
; /* bad smb */
4280 else if (legacy
&& get_bcc(&pSMBr
->hdr
) < 24)
4281 rc
= -EIO
; /* 24 or 26 expected but we do not read
4285 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4288 * On legacy responses we do not read the last field,
4289 * EAsize, fortunately since it varies by subdialect and
4290 * also note it differs on Set vs Get, ie two bytes or 4
4291 * bytes depending but we don't care here.
4294 size
= sizeof(FILE_INFO_STANDARD
);
4296 size
= sizeof(FILE_ALL_INFO
);
4297 memcpy((char *) data
, (char *) &pSMBr
->hdr
.Protocol
+
4302 cifs_buf_release(pSMB
);
4304 goto QPathInfoRetry
;
4310 CIFSSMBUnixQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4311 u16 netfid
, FILE_UNIX_BASIC_INFO
*pFindData
)
4313 struct smb_t2_qfi_req
*pSMB
= NULL
;
4314 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4317 __u16 params
, byte_count
;
4320 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4325 params
= 2 /* level */ + 2 /* fid */;
4326 pSMB
->t2
.TotalDataCount
= 0;
4327 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4328 /* BB find exact max data count below from sess structure BB */
4329 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4330 pSMB
->t2
.MaxSetupCount
= 0;
4331 pSMB
->t2
.Reserved
= 0;
4333 pSMB
->t2
.Timeout
= 0;
4334 pSMB
->t2
.Reserved2
= 0;
4335 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4337 pSMB
->t2
.DataCount
= 0;
4338 pSMB
->t2
.DataOffset
= 0;
4339 pSMB
->t2
.SetupCount
= 1;
4340 pSMB
->t2
.Reserved3
= 0;
4341 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4342 byte_count
= params
+ 1 /* pad */ ;
4343 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4344 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4345 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4348 inc_rfc1001_len(pSMB
, byte_count
);
4349 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4351 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4352 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4354 cifs_dbg(FYI
, "Send error in UnixQFileInfo = %d", rc
);
4355 } else { /* decode response */
4356 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4358 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4359 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4360 rc
= -EIO
; /* bad smb */
4362 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4363 memcpy((char *) pFindData
,
4364 (char *) &pSMBr
->hdr
.Protocol
+
4366 sizeof(FILE_UNIX_BASIC_INFO
));
4370 cifs_buf_release(pSMB
);
4372 goto UnixQFileInfoRetry
;
4378 CIFSSMBUnixQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4379 const unsigned char *searchName
,
4380 FILE_UNIX_BASIC_INFO
*pFindData
,
4381 const struct nls_table
*nls_codepage
, int remap
)
4383 /* SMB_QUERY_FILE_UNIX_BASIC */
4384 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4385 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4387 int bytes_returned
= 0;
4389 __u16 params
, byte_count
;
4391 cifs_dbg(FYI
, "In QPathInfo (Unix) the path %s\n", searchName
);
4393 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4398 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4400 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4401 PATH_MAX
, nls_codepage
, remap
);
4402 name_len
++; /* trailing null */
4404 } else { /* BB improve the check for buffer overruns BB */
4405 name_len
= strnlen(searchName
, PATH_MAX
);
4406 name_len
++; /* trailing null */
4407 strncpy(pSMB
->FileName
, searchName
, name_len
);
4410 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4411 pSMB
->TotalDataCount
= 0;
4412 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4413 /* BB find exact max SMB PDU from sess structure BB */
4414 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4415 pSMB
->MaxSetupCount
= 0;
4419 pSMB
->Reserved2
= 0;
4420 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4421 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4422 pSMB
->DataCount
= 0;
4423 pSMB
->DataOffset
= 0;
4424 pSMB
->SetupCount
= 1;
4425 pSMB
->Reserved3
= 0;
4426 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4427 byte_count
= params
+ 1 /* pad */ ;
4428 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4429 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4430 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4431 pSMB
->Reserved4
= 0;
4432 inc_rfc1001_len(pSMB
, byte_count
);
4433 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4435 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4436 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4438 cifs_dbg(FYI
, "Send error in UnixQPathInfo = %d", rc
);
4439 } else { /* decode response */
4440 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4442 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4443 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4444 rc
= -EIO
; /* bad smb */
4446 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4447 memcpy((char *) pFindData
,
4448 (char *) &pSMBr
->hdr
.Protocol
+
4450 sizeof(FILE_UNIX_BASIC_INFO
));
4453 cifs_buf_release(pSMB
);
4455 goto UnixQPathInfoRetry
;
4460 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4462 CIFSFindFirst(const unsigned int xid
, struct cifs_tcon
*tcon
,
4463 const char *searchName
, struct cifs_sb_info
*cifs_sb
,
4464 __u16
*pnetfid
, __u16 search_flags
,
4465 struct cifs_search_info
*psrch_inf
, bool msearch
)
4467 /* level 257 SMB_ */
4468 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
4469 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
4470 T2_FFIRST_RSP_PARMS
*parms
;
4472 int bytes_returned
= 0;
4473 int name_len
, remap
;
4474 __u16 params
, byte_count
;
4475 struct nls_table
*nls_codepage
;
4477 cifs_dbg(FYI
, "In FindFirst for %s\n", searchName
);
4480 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4485 nls_codepage
= cifs_sb
->local_nls
;
4486 remap
= cifs_remap(cifs_sb
);
4488 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4490 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4491 PATH_MAX
, nls_codepage
, remap
);
4492 /* We can not add the asterik earlier in case
4493 it got remapped to 0xF03A as if it were part of the
4494 directory name instead of a wildcard */
4497 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4498 pSMB
->FileName
[name_len
+1] = 0;
4499 pSMB
->FileName
[name_len
+2] = '*';
4500 pSMB
->FileName
[name_len
+3] = 0;
4501 name_len
+= 4; /* now the trailing null */
4502 /* null terminate just in case */
4503 pSMB
->FileName
[name_len
] = 0;
4504 pSMB
->FileName
[name_len
+1] = 0;
4507 } else { /* BB add check for overrun of SMB buf BB */
4508 name_len
= strnlen(searchName
, PATH_MAX
);
4509 /* BB fix here and in unicode clause above ie
4510 if (name_len > buffersize-header)
4511 free buffer exit; BB */
4512 strncpy(pSMB
->FileName
, searchName
, name_len
);
4514 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4515 pSMB
->FileName
[name_len
+1] = '*';
4516 pSMB
->FileName
[name_len
+2] = 0;
4521 params
= 12 + name_len
/* includes null */ ;
4522 pSMB
->TotalDataCount
= 0; /* no EAs */
4523 pSMB
->MaxParameterCount
= cpu_to_le16(10);
4524 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4525 pSMB
->MaxSetupCount
= 0;
4529 pSMB
->Reserved2
= 0;
4530 byte_count
= params
+ 1 /* pad */ ;
4531 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4532 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4533 pSMB
->ParameterOffset
= cpu_to_le16(
4534 offsetof(struct smb_com_transaction2_ffirst_req
, SearchAttributes
)
4536 pSMB
->DataCount
= 0;
4537 pSMB
->DataOffset
= 0;
4538 pSMB
->SetupCount
= 1; /* one byte, no need to make endian neutral */
4539 pSMB
->Reserved3
= 0;
4540 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
4541 pSMB
->SearchAttributes
=
4542 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
4544 pSMB
->SearchCount
= cpu_to_le16(CIFSMaxBufSize
/sizeof(FILE_UNIX_INFO
));
4545 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4546 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4548 /* BB what should we set StorageType to? Does it matter? BB */
4549 pSMB
->SearchStorageType
= 0;
4550 inc_rfc1001_len(pSMB
, byte_count
);
4551 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4553 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4554 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4555 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_ffirst
);
4557 if (rc
) {/* BB add logic to retry regular search if Unix search
4558 rejected unexpectedly by server */
4559 /* BB Add code to handle unsupported level rc */
4560 cifs_dbg(FYI
, "Error in FindFirst = %d\n", rc
);
4562 cifs_buf_release(pSMB
);
4564 /* BB eventually could optimize out free and realloc of buf */
4567 goto findFirstRetry
;
4568 } else { /* decode response */
4569 /* BB remember to free buffer if error BB */
4570 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4574 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4575 psrch_inf
->unicode
= true;
4577 psrch_inf
->unicode
= false;
4579 psrch_inf
->ntwrk_buf_start
= (char *)pSMBr
;
4580 psrch_inf
->smallBuf
= 0;
4581 psrch_inf
->srch_entries_start
=
4582 (char *) &pSMBr
->hdr
.Protocol
+
4583 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4584 parms
= (T2_FFIRST_RSP_PARMS
*)((char *) &pSMBr
->hdr
.Protocol
+
4585 le16_to_cpu(pSMBr
->t2
.ParameterOffset
));
4587 if (parms
->EndofSearch
)
4588 psrch_inf
->endOfSearch
= true;
4590 psrch_inf
->endOfSearch
= false;
4592 psrch_inf
->entries_in_buffer
=
4593 le16_to_cpu(parms
->SearchCount
);
4594 psrch_inf
->index_of_last_entry
= 2 /* skip . and .. */ +
4595 psrch_inf
->entries_in_buffer
;
4596 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4597 if (CIFSMaxBufSize
< lnoff
) {
4598 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4599 psrch_inf
->last_entry
= NULL
;
4603 psrch_inf
->last_entry
= psrch_inf
->srch_entries_start
+
4607 *pnetfid
= parms
->SearchHandle
;
4609 cifs_buf_release(pSMB
);
4616 int CIFSFindNext(const unsigned int xid
, struct cifs_tcon
*tcon
,
4617 __u16 searchHandle
, __u16 search_flags
,
4618 struct cifs_search_info
*psrch_inf
)
4620 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
4621 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
4622 T2_FNEXT_RSP_PARMS
*parms
;
4623 char *response_data
;
4626 unsigned int name_len
;
4627 __u16 params
, byte_count
;
4629 cifs_dbg(FYI
, "In FindNext\n");
4631 if (psrch_inf
->endOfSearch
)
4634 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4639 params
= 14; /* includes 2 bytes of null string, converted to LE below*/
4641 pSMB
->TotalDataCount
= 0; /* no EAs */
4642 pSMB
->MaxParameterCount
= cpu_to_le16(8);
4643 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4644 pSMB
->MaxSetupCount
= 0;
4648 pSMB
->Reserved2
= 0;
4649 pSMB
->ParameterOffset
= cpu_to_le16(
4650 offsetof(struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
4651 pSMB
->DataCount
= 0;
4652 pSMB
->DataOffset
= 0;
4653 pSMB
->SetupCount
= 1;
4654 pSMB
->Reserved3
= 0;
4655 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
4656 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
4658 cpu_to_le16(CIFSMaxBufSize
/ sizeof(FILE_UNIX_INFO
));
4659 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4660 pSMB
->ResumeKey
= psrch_inf
->resume_key
;
4661 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4663 name_len
= psrch_inf
->resume_name_len
;
4665 if (name_len
< PATH_MAX
) {
4666 memcpy(pSMB
->ResumeFileName
, psrch_inf
->presume_name
, name_len
);
4667 byte_count
+= name_len
;
4668 /* 14 byte parm len above enough for 2 byte null terminator */
4669 pSMB
->ResumeFileName
[name_len
] = 0;
4670 pSMB
->ResumeFileName
[name_len
+1] = 0;
4673 goto FNext2_err_exit
;
4675 byte_count
= params
+ 1 /* pad */ ;
4676 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4677 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4678 inc_rfc1001_len(pSMB
, byte_count
);
4679 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4681 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4682 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4683 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fnext
);
4686 psrch_inf
->endOfSearch
= true;
4687 cifs_buf_release(pSMB
);
4688 rc
= 0; /* search probably was closed at end of search*/
4690 cifs_dbg(FYI
, "FindNext returned = %d\n", rc
);
4691 } else { /* decode response */
4692 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4697 /* BB fixme add lock for file (srch_info) struct here */
4698 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4699 psrch_inf
->unicode
= true;
4701 psrch_inf
->unicode
= false;
4702 response_data
= (char *) &pSMBr
->hdr
.Protocol
+
4703 le16_to_cpu(pSMBr
->t2
.ParameterOffset
);
4704 parms
= (T2_FNEXT_RSP_PARMS
*)response_data
;
4705 response_data
= (char *)&pSMBr
->hdr
.Protocol
+
4706 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4707 if (psrch_inf
->smallBuf
)
4708 cifs_small_buf_release(
4709 psrch_inf
->ntwrk_buf_start
);
4711 cifs_buf_release(psrch_inf
->ntwrk_buf_start
);
4712 psrch_inf
->srch_entries_start
= response_data
;
4713 psrch_inf
->ntwrk_buf_start
= (char *)pSMB
;
4714 psrch_inf
->smallBuf
= 0;
4715 if (parms
->EndofSearch
)
4716 psrch_inf
->endOfSearch
= true;
4718 psrch_inf
->endOfSearch
= false;
4719 psrch_inf
->entries_in_buffer
=
4720 le16_to_cpu(parms
->SearchCount
);
4721 psrch_inf
->index_of_last_entry
+=
4722 psrch_inf
->entries_in_buffer
;
4723 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4724 if (CIFSMaxBufSize
< lnoff
) {
4725 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4726 psrch_inf
->last_entry
= NULL
;
4729 psrch_inf
->last_entry
=
4730 psrch_inf
->srch_entries_start
+ lnoff
;
4732 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4733 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4735 /* BB fixme add unlock here */
4740 /* BB On error, should we leave previous search buf (and count and
4741 last entry fields) intact or free the previous one? */
4743 /* Note: On -EAGAIN error only caller can retry on handle based calls
4744 since file handle passed in no longer valid */
4747 cifs_buf_release(pSMB
);
4752 CIFSFindClose(const unsigned int xid
, struct cifs_tcon
*tcon
,
4753 const __u16 searchHandle
)
4756 FINDCLOSE_REQ
*pSMB
= NULL
;
4758 cifs_dbg(FYI
, "In CIFSSMBFindClose\n");
4759 rc
= small_smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **)&pSMB
);
4761 /* no sense returning error if session restarted
4762 as file handle has been closed */
4768 pSMB
->FileID
= searchHandle
;
4769 pSMB
->ByteCount
= 0;
4770 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
4771 cifs_small_buf_release(pSMB
);
4773 cifs_dbg(VFS
, "Send error in FindClose = %d\n", rc
);
4775 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fclose
);
4777 /* Since session is dead, search handle closed on server already */
4785 CIFSGetSrvInodeNumber(const unsigned int xid
, struct cifs_tcon
*tcon
,
4786 const char *search_name
, __u64
*inode_number
,
4787 const struct nls_table
*nls_codepage
, int remap
)
4790 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4791 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4792 int name_len
, bytes_returned
;
4793 __u16 params
, byte_count
;
4795 cifs_dbg(FYI
, "In GetSrvInodeNum for %s\n", search_name
);
4799 GetInodeNumberRetry
:
4800 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4805 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4807 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4808 search_name
, PATH_MAX
, nls_codepage
,
4810 name_len
++; /* trailing null */
4812 } else { /* BB improve the check for buffer overruns BB */
4813 name_len
= strnlen(search_name
, PATH_MAX
);
4814 name_len
++; /* trailing null */
4815 strncpy(pSMB
->FileName
, search_name
, name_len
);
4818 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
4819 pSMB
->TotalDataCount
= 0;
4820 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4821 /* BB find exact max data count below from sess structure BB */
4822 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4823 pSMB
->MaxSetupCount
= 0;
4827 pSMB
->Reserved2
= 0;
4828 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4829 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4830 pSMB
->DataCount
= 0;
4831 pSMB
->DataOffset
= 0;
4832 pSMB
->SetupCount
= 1;
4833 pSMB
->Reserved3
= 0;
4834 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4835 byte_count
= params
+ 1 /* pad */ ;
4836 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4837 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4838 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO
);
4839 pSMB
->Reserved4
= 0;
4840 inc_rfc1001_len(pSMB
, byte_count
);
4841 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4843 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4844 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4846 cifs_dbg(FYI
, "error %d in QueryInternalInfo\n", rc
);
4848 /* decode response */
4849 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4850 /* BB also check enough total bytes returned */
4851 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
4852 /* If rc should we check for EOPNOSUPP and
4853 disable the srvino flag? or in caller? */
4854 rc
= -EIO
; /* bad smb */
4856 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4857 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
4858 struct file_internal_info
*pfinfo
;
4859 /* BB Do we need a cast or hash here ? */
4861 cifs_dbg(FYI
, "Illegal size ret in QryIntrnlInf\n");
4863 goto GetInodeNumOut
;
4865 pfinfo
= (struct file_internal_info
*)
4866 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
4867 *inode_number
= le64_to_cpu(pfinfo
->UniqueId
);
4871 cifs_buf_release(pSMB
);
4873 goto GetInodeNumberRetry
;
4878 CIFSGetDFSRefer(const unsigned int xid
, struct cifs_ses
*ses
,
4879 const char *search_name
, struct dfs_info3_param
**target_nodes
,
4880 unsigned int *num_of_nodes
,
4881 const struct nls_table
*nls_codepage
, int remap
)
4883 /* TRANS2_GET_DFS_REFERRAL */
4884 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
4885 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
4889 __u16 params
, byte_count
;
4891 *target_nodes
= NULL
;
4893 cifs_dbg(FYI
, "In GetDFSRefer the path %s\n", search_name
);
4894 if (ses
== NULL
|| ses
->tcon_ipc
== NULL
)
4898 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, ses
->tcon_ipc
, (void **) &pSMB
,
4903 /* server pointer checked in called function,
4904 but should never be null here anyway */
4905 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
4906 pSMB
->hdr
.Tid
= ses
->tcon_ipc
->tid
;
4907 pSMB
->hdr
.Uid
= ses
->Suid
;
4908 if (ses
->capabilities
& CAP_STATUS32
)
4909 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
4910 if (ses
->capabilities
& CAP_DFS
)
4911 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
4913 if (ses
->capabilities
& CAP_UNICODE
) {
4914 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
4916 cifsConvertToUTF16((__le16
*) pSMB
->RequestFileName
,
4917 search_name
, PATH_MAX
, nls_codepage
,
4919 name_len
++; /* trailing null */
4921 } else { /* BB improve the check for buffer overruns BB */
4922 name_len
= strnlen(search_name
, PATH_MAX
);
4923 name_len
++; /* trailing null */
4924 strncpy(pSMB
->RequestFileName
, search_name
, name_len
);
4927 if (ses
->server
->sign
)
4928 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
4930 pSMB
->hdr
.Uid
= ses
->Suid
;
4932 params
= 2 /* level */ + name_len
/*includes null */ ;
4933 pSMB
->TotalDataCount
= 0;
4934 pSMB
->DataCount
= 0;
4935 pSMB
->DataOffset
= 0;
4936 pSMB
->MaxParameterCount
= 0;
4937 /* BB find exact max SMB PDU from sess structure BB */
4938 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4939 pSMB
->MaxSetupCount
= 0;
4943 pSMB
->Reserved2
= 0;
4944 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4945 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
4946 pSMB
->SetupCount
= 1;
4947 pSMB
->Reserved3
= 0;
4948 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
4949 byte_count
= params
+ 3 /* pad */ ;
4950 pSMB
->ParameterCount
= cpu_to_le16(params
);
4951 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4952 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
4953 inc_rfc1001_len(pSMB
, byte_count
);
4954 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4956 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
4957 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4959 cifs_dbg(FYI
, "Send error in GetDFSRefer = %d\n", rc
);
4962 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4964 /* BB Also check if enough total bytes returned? */
4965 if (rc
|| get_bcc(&pSMBr
->hdr
) < 17) {
4966 rc
= -EIO
; /* bad smb */
4970 cifs_dbg(FYI
, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4971 get_bcc(&pSMBr
->hdr
), le16_to_cpu(pSMBr
->t2
.DataOffset
));
4973 /* parse returned result into more usable form */
4974 rc
= parse_dfs_referrals(&pSMBr
->dfs_data
,
4975 le16_to_cpu(pSMBr
->t2
.DataCount
),
4976 num_of_nodes
, target_nodes
, nls_codepage
,
4978 (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) != 0);
4981 cifs_buf_release(pSMB
);
4989 /* Query File System Info such as free space to old servers such as Win 9x */
4991 SMBOldQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4992 struct kstatfs
*FSData
)
4994 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4995 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4996 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4997 FILE_SYSTEM_ALLOC_INFO
*response_data
;
4999 int bytes_returned
= 0;
5000 __u16 params
, byte_count
;
5002 cifs_dbg(FYI
, "OldQFSInfo\n");
5004 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5009 params
= 2; /* level */
5010 pSMB
->TotalDataCount
= 0;
5011 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5012 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5013 pSMB
->MaxSetupCount
= 0;
5017 pSMB
->Reserved2
= 0;
5018 byte_count
= params
+ 1 /* pad */ ;
5019 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5020 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5021 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5022 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5023 pSMB
->DataCount
= 0;
5024 pSMB
->DataOffset
= 0;
5025 pSMB
->SetupCount
= 1;
5026 pSMB
->Reserved3
= 0;
5027 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5028 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_ALLOCATION
);
5029 inc_rfc1001_len(pSMB
, byte_count
);
5030 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5032 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5033 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5035 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5036 } else { /* decode response */
5037 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5039 if (rc
|| get_bcc(&pSMBr
->hdr
) < 18)
5040 rc
= -EIO
; /* bad smb */
5042 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5043 cifs_dbg(FYI
, "qfsinf resp BCC: %d Offset %d\n",
5044 get_bcc(&pSMBr
->hdr
), data_offset
);
5046 response_data
= (FILE_SYSTEM_ALLOC_INFO
*)
5047 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
5049 le16_to_cpu(response_data
->BytesPerSector
) *
5050 le32_to_cpu(response_data
->
5051 SectorsPerAllocationUnit
);
5053 le32_to_cpu(response_data
->TotalAllocationUnits
);
5054 FSData
->f_bfree
= FSData
->f_bavail
=
5055 le32_to_cpu(response_data
->FreeAllocationUnits
);
5056 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5057 (unsigned long long)FSData
->f_blocks
,
5058 (unsigned long long)FSData
->f_bfree
,
5062 cifs_buf_release(pSMB
);
5065 goto oldQFSInfoRetry
;
5071 CIFSSMBQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5072 struct kstatfs
*FSData
)
5074 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5075 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5076 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5077 FILE_SYSTEM_INFO
*response_data
;
5079 int bytes_returned
= 0;
5080 __u16 params
, byte_count
;
5082 cifs_dbg(FYI
, "In QFSInfo\n");
5084 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5089 params
= 2; /* level */
5090 pSMB
->TotalDataCount
= 0;
5091 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5092 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5093 pSMB
->MaxSetupCount
= 0;
5097 pSMB
->Reserved2
= 0;
5098 byte_count
= params
+ 1 /* pad */ ;
5099 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5100 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5101 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5102 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5103 pSMB
->DataCount
= 0;
5104 pSMB
->DataOffset
= 0;
5105 pSMB
->SetupCount
= 1;
5106 pSMB
->Reserved3
= 0;
5107 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5108 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
5109 inc_rfc1001_len(pSMB
, byte_count
);
5110 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5112 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5113 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5115 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5116 } else { /* decode response */
5117 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5119 if (rc
|| get_bcc(&pSMBr
->hdr
) < 24)
5120 rc
= -EIO
; /* bad smb */
5122 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5126 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5129 le32_to_cpu(response_data
->BytesPerSector
) *
5130 le32_to_cpu(response_data
->
5131 SectorsPerAllocationUnit
);
5133 le64_to_cpu(response_data
->TotalAllocationUnits
);
5134 FSData
->f_bfree
= FSData
->f_bavail
=
5135 le64_to_cpu(response_data
->FreeAllocationUnits
);
5136 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5137 (unsigned long long)FSData
->f_blocks
,
5138 (unsigned long long)FSData
->f_bfree
,
5142 cifs_buf_release(pSMB
);
5151 CIFSSMBQFSAttributeInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5153 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5154 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5155 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5156 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
5158 int bytes_returned
= 0;
5159 __u16 params
, byte_count
;
5161 cifs_dbg(FYI
, "In QFSAttributeInfo\n");
5163 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5168 params
= 2; /* level */
5169 pSMB
->TotalDataCount
= 0;
5170 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5171 /* BB find exact max SMB PDU from sess structure BB */
5172 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5173 pSMB
->MaxSetupCount
= 0;
5177 pSMB
->Reserved2
= 0;
5178 byte_count
= params
+ 1 /* pad */ ;
5179 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5180 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5181 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5182 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5183 pSMB
->DataCount
= 0;
5184 pSMB
->DataOffset
= 0;
5185 pSMB
->SetupCount
= 1;
5186 pSMB
->Reserved3
= 0;
5187 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5188 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
5189 inc_rfc1001_len(pSMB
, byte_count
);
5190 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5192 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5193 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5195 cifs_dbg(VFS
, "Send error in QFSAttributeInfo = %d\n", rc
);
5196 } else { /* decode response */
5197 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5199 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5200 /* BB also check if enough bytes returned */
5201 rc
= -EIO
; /* bad smb */
5203 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5205 (FILE_SYSTEM_ATTRIBUTE_INFO
5206 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5208 memcpy(&tcon
->fsAttrInfo
, response_data
,
5209 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO
));
5212 cifs_buf_release(pSMB
);
5215 goto QFSAttributeRetry
;
5221 CIFSSMBQFSDeviceInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5223 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5224 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5225 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5226 FILE_SYSTEM_DEVICE_INFO
*response_data
;
5228 int bytes_returned
= 0;
5229 __u16 params
, byte_count
;
5231 cifs_dbg(FYI
, "In QFSDeviceInfo\n");
5233 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5238 params
= 2; /* level */
5239 pSMB
->TotalDataCount
= 0;
5240 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5241 /* BB find exact max SMB PDU from sess structure BB */
5242 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5243 pSMB
->MaxSetupCount
= 0;
5247 pSMB
->Reserved2
= 0;
5248 byte_count
= params
+ 1 /* pad */ ;
5249 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5250 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5251 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5252 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5254 pSMB
->DataCount
= 0;
5255 pSMB
->DataOffset
= 0;
5256 pSMB
->SetupCount
= 1;
5257 pSMB
->Reserved3
= 0;
5258 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5259 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
5260 inc_rfc1001_len(pSMB
, byte_count
);
5261 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5263 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5264 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5266 cifs_dbg(FYI
, "Send error in QFSDeviceInfo = %d\n", rc
);
5267 } else { /* decode response */
5268 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5270 if (rc
|| get_bcc(&pSMBr
->hdr
) <
5271 sizeof(FILE_SYSTEM_DEVICE_INFO
))
5272 rc
= -EIO
; /* bad smb */
5274 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5276 (FILE_SYSTEM_DEVICE_INFO
*)
5277 (((char *) &pSMBr
->hdr
.Protocol
) +
5279 memcpy(&tcon
->fsDevInfo
, response_data
,
5280 sizeof(FILE_SYSTEM_DEVICE_INFO
));
5283 cifs_buf_release(pSMB
);
5286 goto QFSDeviceRetry
;
5292 CIFSSMBQFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5294 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5295 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5296 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5297 FILE_SYSTEM_UNIX_INFO
*response_data
;
5299 int bytes_returned
= 0;
5300 __u16 params
, byte_count
;
5302 cifs_dbg(FYI
, "In QFSUnixInfo\n");
5304 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5305 (void **) &pSMB
, (void **) &pSMBr
);
5309 params
= 2; /* level */
5310 pSMB
->TotalDataCount
= 0;
5311 pSMB
->DataCount
= 0;
5312 pSMB
->DataOffset
= 0;
5313 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5314 /* BB find exact max SMB PDU from sess structure BB */
5315 pSMB
->MaxDataCount
= cpu_to_le16(100);
5316 pSMB
->MaxSetupCount
= 0;
5320 pSMB
->Reserved2
= 0;
5321 byte_count
= params
+ 1 /* pad */ ;
5322 pSMB
->ParameterCount
= cpu_to_le16(params
);
5323 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5324 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5325 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5326 pSMB
->SetupCount
= 1;
5327 pSMB
->Reserved3
= 0;
5328 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5329 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
5330 inc_rfc1001_len(pSMB
, byte_count
);
5331 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5333 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5334 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5336 cifs_dbg(VFS
, "Send error in QFSUnixInfo = %d\n", rc
);
5337 } else { /* decode response */
5338 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5340 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5341 rc
= -EIO
; /* bad smb */
5343 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5345 (FILE_SYSTEM_UNIX_INFO
5346 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5348 memcpy(&tcon
->fsUnixInfo
, response_data
,
5349 sizeof(FILE_SYSTEM_UNIX_INFO
));
5352 cifs_buf_release(pSMB
);
5362 CIFSSMBSetFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
, __u64 cap
)
5364 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5365 TRANSACTION2_SETFSI_REQ
*pSMB
= NULL
;
5366 TRANSACTION2_SETFSI_RSP
*pSMBr
= NULL
;
5368 int bytes_returned
= 0;
5369 __u16 params
, param_offset
, offset
, byte_count
;
5371 cifs_dbg(FYI
, "In SETFSUnixInfo\n");
5373 /* BB switch to small buf init to save memory */
5374 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5375 (void **) &pSMB
, (void **) &pSMBr
);
5379 params
= 4; /* 2 bytes zero followed by info level. */
5380 pSMB
->MaxSetupCount
= 0;
5384 pSMB
->Reserved2
= 0;
5385 param_offset
= offsetof(struct smb_com_transaction2_setfsi_req
, FileNum
)
5387 offset
= param_offset
+ params
;
5389 pSMB
->MaxParameterCount
= cpu_to_le16(4);
5390 /* BB find exact max SMB PDU from sess structure BB */
5391 pSMB
->MaxDataCount
= cpu_to_le16(100);
5392 pSMB
->SetupCount
= 1;
5393 pSMB
->Reserved3
= 0;
5394 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FS_INFORMATION
);
5395 byte_count
= 1 /* pad */ + params
+ 12;
5397 pSMB
->DataCount
= cpu_to_le16(12);
5398 pSMB
->ParameterCount
= cpu_to_le16(params
);
5399 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5400 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5401 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5402 pSMB
->DataOffset
= cpu_to_le16(offset
);
5406 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_CIFS_UNIX_INFO
);
5409 pSMB
->ClientUnixMajor
= cpu_to_le16(CIFS_UNIX_MAJOR_VERSION
);
5410 pSMB
->ClientUnixMinor
= cpu_to_le16(CIFS_UNIX_MINOR_VERSION
);
5411 pSMB
->ClientUnixCap
= cpu_to_le64(cap
);
5413 inc_rfc1001_len(pSMB
, byte_count
);
5414 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5416 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5417 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5419 cifs_dbg(VFS
, "Send error in SETFSUnixInfo = %d\n", rc
);
5420 } else { /* decode response */
5421 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5423 rc
= -EIO
; /* bad smb */
5425 cifs_buf_release(pSMB
);
5428 goto SETFSUnixRetry
;
5436 CIFSSMBQFSPosixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5437 struct kstatfs
*FSData
)
5439 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5440 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5441 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5442 FILE_SYSTEM_POSIX_INFO
*response_data
;
5444 int bytes_returned
= 0;
5445 __u16 params
, byte_count
;
5447 cifs_dbg(FYI
, "In QFSPosixInfo\n");
5449 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5454 params
= 2; /* level */
5455 pSMB
->TotalDataCount
= 0;
5456 pSMB
->DataCount
= 0;
5457 pSMB
->DataOffset
= 0;
5458 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5459 /* BB find exact max SMB PDU from sess structure BB */
5460 pSMB
->MaxDataCount
= cpu_to_le16(100);
5461 pSMB
->MaxSetupCount
= 0;
5465 pSMB
->Reserved2
= 0;
5466 byte_count
= params
+ 1 /* pad */ ;
5467 pSMB
->ParameterCount
= cpu_to_le16(params
);
5468 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5469 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5470 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5471 pSMB
->SetupCount
= 1;
5472 pSMB
->Reserved3
= 0;
5473 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5474 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_FS_INFO
);
5475 inc_rfc1001_len(pSMB
, byte_count
);
5476 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5478 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5479 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5481 cifs_dbg(FYI
, "Send error in QFSUnixInfo = %d\n", rc
);
5482 } else { /* decode response */
5483 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5485 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5486 rc
= -EIO
; /* bad smb */
5488 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5490 (FILE_SYSTEM_POSIX_INFO
5491 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5494 le32_to_cpu(response_data
->BlockSize
);
5496 le64_to_cpu(response_data
->TotalBlocks
);
5498 le64_to_cpu(response_data
->BlocksAvail
);
5499 if (response_data
->UserBlocksAvail
== cpu_to_le64(-1)) {
5500 FSData
->f_bavail
= FSData
->f_bfree
;
5503 le64_to_cpu(response_data
->UserBlocksAvail
);
5505 if (response_data
->TotalFileNodes
!= cpu_to_le64(-1))
5507 le64_to_cpu(response_data
->TotalFileNodes
);
5508 if (response_data
->FreeFileNodes
!= cpu_to_le64(-1))
5510 le64_to_cpu(response_data
->FreeFileNodes
);
5513 cifs_buf_release(pSMB
);
5523 * We can not use write of zero bytes trick to set file size due to need for
5524 * large file support. Also note that this SetPathInfo is preferred to
5525 * SetFileInfo based method in next routine which is only needed to work around
5526 * a sharing violation bugin Samba which this routine can run into.
5529 CIFSSMBSetEOF(const unsigned int xid
, struct cifs_tcon
*tcon
,
5530 const char *file_name
, __u64 size
, struct cifs_sb_info
*cifs_sb
,
5531 bool set_allocation
)
5533 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5534 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5535 struct file_end_of_file_info
*parm_data
;
5538 int bytes_returned
= 0;
5539 int remap
= cifs_remap(cifs_sb
);
5541 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
5543 cifs_dbg(FYI
, "In SetEOF\n");
5545 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5550 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5552 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5553 PATH_MAX
, cifs_sb
->local_nls
, remap
);
5554 name_len
++; /* trailing null */
5556 } else { /* BB improve the check for buffer overruns BB */
5557 name_len
= strnlen(file_name
, PATH_MAX
);
5558 name_len
++; /* trailing null */
5559 strncpy(pSMB
->FileName
, file_name
, name_len
);
5561 params
= 6 + name_len
;
5562 data_count
= sizeof(struct file_end_of_file_info
);
5563 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5564 pSMB
->MaxDataCount
= cpu_to_le16(4100);
5565 pSMB
->MaxSetupCount
= 0;
5569 pSMB
->Reserved2
= 0;
5570 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5571 InformationLevel
) - 4;
5572 offset
= param_offset
+ params
;
5573 if (set_allocation
) {
5574 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5575 pSMB
->InformationLevel
=
5576 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5578 pSMB
->InformationLevel
=
5579 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5580 } else /* Set File Size */ {
5581 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5582 pSMB
->InformationLevel
=
5583 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5585 pSMB
->InformationLevel
=
5586 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5590 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
5592 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5593 pSMB
->DataOffset
= cpu_to_le16(offset
);
5594 pSMB
->SetupCount
= 1;
5595 pSMB
->Reserved3
= 0;
5596 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5597 byte_count
= 3 /* pad */ + params
+ data_count
;
5598 pSMB
->DataCount
= cpu_to_le16(data_count
);
5599 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5600 pSMB
->ParameterCount
= cpu_to_le16(params
);
5601 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5602 pSMB
->Reserved4
= 0;
5603 inc_rfc1001_len(pSMB
, byte_count
);
5604 parm_data
->FileSize
= cpu_to_le64(size
);
5605 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5606 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5607 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5609 cifs_dbg(FYI
, "SetPathInfo (file size) returned %d\n", rc
);
5611 cifs_buf_release(pSMB
);
5620 CIFSSMBSetFileSize(const unsigned int xid
, struct cifs_tcon
*tcon
,
5621 struct cifsFileInfo
*cfile
, __u64 size
, bool set_allocation
)
5623 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5624 struct file_end_of_file_info
*parm_data
;
5626 __u16 params
, param_offset
, offset
, byte_count
, count
;
5628 cifs_dbg(FYI
, "SetFileSize (via SetFileInfo) %lld\n",
5630 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5635 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)cfile
->pid
);
5636 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(cfile
->pid
>> 16));
5639 pSMB
->MaxSetupCount
= 0;
5643 pSMB
->Reserved2
= 0;
5644 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5645 offset
= param_offset
+ params
;
5647 count
= sizeof(struct file_end_of_file_info
);
5648 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5649 /* BB find exact max SMB PDU from sess structure BB */
5650 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5651 pSMB
->SetupCount
= 1;
5652 pSMB
->Reserved3
= 0;
5653 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5654 byte_count
= 3 /* pad */ + params
+ count
;
5655 pSMB
->DataCount
= cpu_to_le16(count
);
5656 pSMB
->ParameterCount
= cpu_to_le16(params
);
5657 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5658 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5659 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5661 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
)
5663 pSMB
->DataOffset
= cpu_to_le16(offset
);
5664 parm_data
->FileSize
= cpu_to_le64(size
);
5665 pSMB
->Fid
= cfile
->fid
.netfid
;
5666 if (set_allocation
) {
5667 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5668 pSMB
->InformationLevel
=
5669 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5671 pSMB
->InformationLevel
=
5672 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5673 } else /* Set File Size */ {
5674 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5675 pSMB
->InformationLevel
=
5676 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5678 pSMB
->InformationLevel
=
5679 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5681 pSMB
->Reserved4
= 0;
5682 inc_rfc1001_len(pSMB
, byte_count
);
5683 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5684 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5685 cifs_small_buf_release(pSMB
);
5687 cifs_dbg(FYI
, "Send error in SetFileInfo (SetFileSize) = %d\n",
5691 /* Note: On -EAGAIN error only caller can retry on handle based calls
5692 since file handle passed in no longer valid */
5697 /* Some legacy servers such as NT4 require that the file times be set on
5698 an open handle, rather than by pathname - this is awkward due to
5699 potential access conflicts on the open, but it is unavoidable for these
5700 old servers since the only other choice is to go from 100 nanosecond DCE
5701 time and resort to the original setpathinfo level which takes the ancient
5702 DOS time format with 2 second granularity */
5704 CIFSSMBSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5705 const FILE_BASIC_INFO
*data
, __u16 fid
, __u32 pid_of_opener
)
5707 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5710 __u16 params
, param_offset
, offset
, byte_count
, count
;
5712 cifs_dbg(FYI
, "Set Times (via SetFileInfo)\n");
5713 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5718 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5719 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5722 pSMB
->MaxSetupCount
= 0;
5726 pSMB
->Reserved2
= 0;
5727 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5728 offset
= param_offset
+ params
;
5730 data_offset
= (char *)pSMB
+
5731 offsetof(struct smb_hdr
, Protocol
) + offset
;
5733 count
= sizeof(FILE_BASIC_INFO
);
5734 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5735 /* BB find max SMB PDU from sess */
5736 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5737 pSMB
->SetupCount
= 1;
5738 pSMB
->Reserved3
= 0;
5739 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5740 byte_count
= 3 /* pad */ + params
+ count
;
5741 pSMB
->DataCount
= cpu_to_le16(count
);
5742 pSMB
->ParameterCount
= cpu_to_le16(params
);
5743 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5744 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5745 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5746 pSMB
->DataOffset
= cpu_to_le16(offset
);
5748 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5749 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5751 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5752 pSMB
->Reserved4
= 0;
5753 inc_rfc1001_len(pSMB
, byte_count
);
5754 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5755 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5756 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5757 cifs_small_buf_release(pSMB
);
5759 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5762 /* Note: On -EAGAIN error only caller can retry on handle based calls
5763 since file handle passed in no longer valid */
5769 CIFSSMBSetFileDisposition(const unsigned int xid
, struct cifs_tcon
*tcon
,
5770 bool delete_file
, __u16 fid
, __u32 pid_of_opener
)
5772 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5775 __u16 params
, param_offset
, offset
, byte_count
, count
;
5777 cifs_dbg(FYI
, "Set File Disposition (via SetFileInfo)\n");
5778 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5783 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5784 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5787 pSMB
->MaxSetupCount
= 0;
5791 pSMB
->Reserved2
= 0;
5792 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5793 offset
= param_offset
+ params
;
5795 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5798 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5799 /* BB find max SMB PDU from sess */
5800 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5801 pSMB
->SetupCount
= 1;
5802 pSMB
->Reserved3
= 0;
5803 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5804 byte_count
= 3 /* pad */ + params
+ count
;
5805 pSMB
->DataCount
= cpu_to_le16(count
);
5806 pSMB
->ParameterCount
= cpu_to_le16(params
);
5807 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5808 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5809 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5810 pSMB
->DataOffset
= cpu_to_le16(offset
);
5812 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO
);
5813 pSMB
->Reserved4
= 0;
5814 inc_rfc1001_len(pSMB
, byte_count
);
5815 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5816 *data_offset
= delete_file
? 1 : 0;
5817 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5818 cifs_small_buf_release(pSMB
);
5820 cifs_dbg(FYI
, "Send error in SetFileDisposition = %d\n", rc
);
5826 CIFSSMBSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5827 const char *fileName
, const FILE_BASIC_INFO
*data
,
5828 const struct nls_table
*nls_codepage
, int remap
)
5830 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5831 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5834 int bytes_returned
= 0;
5836 __u16 params
, param_offset
, offset
, byte_count
, count
;
5838 cifs_dbg(FYI
, "In SetTimes\n");
5841 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5846 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5848 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5849 PATH_MAX
, nls_codepage
, remap
);
5850 name_len
++; /* trailing null */
5852 } else { /* BB improve the check for buffer overruns BB */
5853 name_len
= strnlen(fileName
, PATH_MAX
);
5854 name_len
++; /* trailing null */
5855 strncpy(pSMB
->FileName
, fileName
, name_len
);
5858 params
= 6 + name_len
;
5859 count
= sizeof(FILE_BASIC_INFO
);
5860 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5861 /* BB find max SMB PDU from sess structure BB */
5862 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5863 pSMB
->MaxSetupCount
= 0;
5867 pSMB
->Reserved2
= 0;
5868 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5869 InformationLevel
) - 4;
5870 offset
= param_offset
+ params
;
5871 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5872 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5873 pSMB
->DataOffset
= cpu_to_le16(offset
);
5874 pSMB
->SetupCount
= 1;
5875 pSMB
->Reserved3
= 0;
5876 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5877 byte_count
= 3 /* pad */ + params
+ count
;
5879 pSMB
->DataCount
= cpu_to_le16(count
);
5880 pSMB
->ParameterCount
= cpu_to_le16(params
);
5881 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5882 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5883 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5884 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5886 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5887 pSMB
->Reserved4
= 0;
5888 inc_rfc1001_len(pSMB
, byte_count
);
5889 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5890 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5891 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5892 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5894 cifs_dbg(FYI
, "SetPathInfo (times) returned %d\n", rc
);
5896 cifs_buf_release(pSMB
);
5904 /* Can not be used to set time stamps yet (due to old DOS time format) */
5905 /* Can be used to set attributes */
5906 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5907 handling it anyway and NT4 was what we thought it would be needed for
5908 Do not delete it until we prove whether needed for Win9x though */
5910 CIFSSMBSetAttrLegacy(unsigned int xid
, struct cifs_tcon
*tcon
, char *fileName
,
5911 __u16 dos_attrs
, const struct nls_table
*nls_codepage
)
5913 SETATTR_REQ
*pSMB
= NULL
;
5914 SETATTR_RSP
*pSMBr
= NULL
;
5919 cifs_dbg(FYI
, "In SetAttrLegacy\n");
5922 rc
= smb_init(SMB_COM_SETATTR
, 8, tcon
, (void **) &pSMB
,
5927 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5929 ConvertToUTF16((__le16
*) pSMB
->fileName
, fileName
,
5930 PATH_MAX
, nls_codepage
);
5931 name_len
++; /* trailing null */
5933 } else { /* BB improve the check for buffer overruns BB */
5934 name_len
= strnlen(fileName
, PATH_MAX
);
5935 name_len
++; /* trailing null */
5936 strncpy(pSMB
->fileName
, fileName
, name_len
);
5938 pSMB
->attr
= cpu_to_le16(dos_attrs
);
5939 pSMB
->BufferFormat
= 0x04;
5940 inc_rfc1001_len(pSMB
, name_len
+ 1);
5941 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
5942 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5943 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5945 cifs_dbg(FYI
, "Error in LegacySetAttr = %d\n", rc
);
5947 cifs_buf_release(pSMB
);
5950 goto SetAttrLgcyRetry
;
5954 #endif /* temporarily unneeded SetAttr legacy function */
5957 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO
*data_offset
,
5958 const struct cifs_unix_set_info_args
*args
)
5960 u64 uid
= NO_CHANGE_64
, gid
= NO_CHANGE_64
;
5961 u64 mode
= args
->mode
;
5963 if (uid_valid(args
->uid
))
5964 uid
= from_kuid(&init_user_ns
, args
->uid
);
5965 if (gid_valid(args
->gid
))
5966 gid
= from_kgid(&init_user_ns
, args
->gid
);
5969 * Samba server ignores set of file size to zero due to bugs in some
5970 * older clients, but we should be precise - we use SetFileSize to
5971 * set file size and do not want to truncate file size to zero
5972 * accidentally as happened on one Samba server beta by putting
5973 * zero instead of -1 here
5975 data_offset
->EndOfFile
= cpu_to_le64(NO_CHANGE_64
);
5976 data_offset
->NumOfBytes
= cpu_to_le64(NO_CHANGE_64
);
5977 data_offset
->LastStatusChange
= cpu_to_le64(args
->ctime
);
5978 data_offset
->LastAccessTime
= cpu_to_le64(args
->atime
);
5979 data_offset
->LastModificationTime
= cpu_to_le64(args
->mtime
);
5980 data_offset
->Uid
= cpu_to_le64(uid
);
5981 data_offset
->Gid
= cpu_to_le64(gid
);
5982 /* better to leave device as zero when it is */
5983 data_offset
->DevMajor
= cpu_to_le64(MAJOR(args
->device
));
5984 data_offset
->DevMinor
= cpu_to_le64(MINOR(args
->device
));
5985 data_offset
->Permissions
= cpu_to_le64(mode
);
5988 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
5989 else if (S_ISDIR(mode
))
5990 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
5991 else if (S_ISLNK(mode
))
5992 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
5993 else if (S_ISCHR(mode
))
5994 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
5995 else if (S_ISBLK(mode
))
5996 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
5997 else if (S_ISFIFO(mode
))
5998 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
5999 else if (S_ISSOCK(mode
))
6000 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
6004 CIFSSMBUnixSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6005 const struct cifs_unix_set_info_args
*args
,
6006 u16 fid
, u32 pid_of_opener
)
6008 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
6011 u16 params
, param_offset
, offset
, byte_count
, count
;
6013 cifs_dbg(FYI
, "Set Unix Info (via SetFileInfo)\n");
6014 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
6019 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
6020 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
6023 pSMB
->MaxSetupCount
= 0;
6027 pSMB
->Reserved2
= 0;
6028 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
6029 offset
= param_offset
+ params
;
6031 data_offset
= (char *)pSMB
+
6032 offsetof(struct smb_hdr
, Protocol
) + offset
;
6034 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6036 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6037 /* BB find max SMB PDU from sess */
6038 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6039 pSMB
->SetupCount
= 1;
6040 pSMB
->Reserved3
= 0;
6041 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
6042 byte_count
= 3 /* pad */ + params
+ count
;
6043 pSMB
->DataCount
= cpu_to_le16(count
);
6044 pSMB
->ParameterCount
= cpu_to_le16(params
);
6045 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6046 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6047 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6048 pSMB
->DataOffset
= cpu_to_le16(offset
);
6050 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6051 pSMB
->Reserved4
= 0;
6052 inc_rfc1001_len(pSMB
, byte_count
);
6053 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6055 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO
*)data_offset
, args
);
6057 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
6058 cifs_small_buf_release(pSMB
);
6060 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
6063 /* Note: On -EAGAIN error only caller can retry on handle based calls
6064 since file handle passed in no longer valid */
6070 CIFSSMBUnixSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6071 const char *file_name
,
6072 const struct cifs_unix_set_info_args
*args
,
6073 const struct nls_table
*nls_codepage
, int remap
)
6075 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
6076 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
6079 int bytes_returned
= 0;
6080 FILE_UNIX_BASIC_INFO
*data_offset
;
6081 __u16 params
, param_offset
, offset
, count
, byte_count
;
6083 cifs_dbg(FYI
, "In SetUID/GID/Mode\n");
6085 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6090 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6092 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
6093 PATH_MAX
, nls_codepage
, remap
);
6094 name_len
++; /* trailing null */
6096 } else { /* BB improve the check for buffer overruns BB */
6097 name_len
= strnlen(file_name
, PATH_MAX
);
6098 name_len
++; /* trailing null */
6099 strncpy(pSMB
->FileName
, file_name
, name_len
);
6102 params
= 6 + name_len
;
6103 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6104 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6105 /* BB find max SMB PDU from sess structure BB */
6106 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6107 pSMB
->MaxSetupCount
= 0;
6111 pSMB
->Reserved2
= 0;
6112 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6113 InformationLevel
) - 4;
6114 offset
= param_offset
+ params
;
6116 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
6118 memset(data_offset
, 0, count
);
6119 pSMB
->DataOffset
= cpu_to_le16(offset
);
6120 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6121 pSMB
->SetupCount
= 1;
6122 pSMB
->Reserved3
= 0;
6123 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6124 byte_count
= 3 /* pad */ + params
+ count
;
6125 pSMB
->ParameterCount
= cpu_to_le16(params
);
6126 pSMB
->DataCount
= cpu_to_le16(count
);
6127 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6128 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6129 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6130 pSMB
->Reserved4
= 0;
6131 inc_rfc1001_len(pSMB
, byte_count
);
6133 cifs_fill_unix_set_info(data_offset
, args
);
6135 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6136 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6137 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6139 cifs_dbg(FYI
, "SetPathInfo (perms) returned %d\n", rc
);
6141 cifs_buf_release(pSMB
);
6147 #ifdef CONFIG_CIFS_XATTR
6149 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6150 * function used by listxattr and getxattr type calls. When ea_name is set,
6151 * it looks for that attribute name and stuffs that value into the EAData
6152 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6153 * buffer. In both cases, the return value is either the length of the
6154 * resulting data or a negative error code. If EAData is a NULL pointer then
6155 * the data isn't copied to it, but the length is returned.
6158 CIFSSMBQAllEAs(const unsigned int xid
, struct cifs_tcon
*tcon
,
6159 const unsigned char *searchName
, const unsigned char *ea_name
,
6160 char *EAData
, size_t buf_size
,
6161 struct cifs_sb_info
*cifs_sb
)
6163 /* BB assumes one setup word */
6164 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
6165 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
6166 int remap
= cifs_remap(cifs_sb
);
6167 struct nls_table
*nls_codepage
= cifs_sb
->local_nls
;
6171 struct fealist
*ea_response_data
;
6172 struct fea
*temp_fea
;
6175 __u16 params
, byte_count
, data_offset
;
6176 unsigned int ea_name_len
= ea_name
? strlen(ea_name
) : 0;
6178 cifs_dbg(FYI
, "In Query All EAs path %s\n", searchName
);
6180 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6185 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6187 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
6188 PATH_MAX
, nls_codepage
, remap
);
6189 list_len
++; /* trailing null */
6191 } else { /* BB improve the check for buffer overruns BB */
6192 list_len
= strnlen(searchName
, PATH_MAX
);
6193 list_len
++; /* trailing null */
6194 strncpy(pSMB
->FileName
, searchName
, list_len
);
6197 params
= 2 /* level */ + 4 /* reserved */ + list_len
/* includes NUL */;
6198 pSMB
->TotalDataCount
= 0;
6199 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6200 /* BB find exact max SMB PDU from sess structure BB */
6201 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
6202 pSMB
->MaxSetupCount
= 0;
6206 pSMB
->Reserved2
= 0;
6207 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
6208 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
6209 pSMB
->DataCount
= 0;
6210 pSMB
->DataOffset
= 0;
6211 pSMB
->SetupCount
= 1;
6212 pSMB
->Reserved3
= 0;
6213 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
6214 byte_count
= params
+ 1 /* pad */ ;
6215 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
6216 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6217 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
6218 pSMB
->Reserved4
= 0;
6219 inc_rfc1001_len(pSMB
, byte_count
);
6220 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6222 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6223 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6225 cifs_dbg(FYI
, "Send error in QueryAllEAs = %d\n", rc
);
6230 /* BB also check enough total bytes returned */
6231 /* BB we need to improve the validity checking
6232 of these trans2 responses */
6234 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
6235 if (rc
|| get_bcc(&pSMBr
->hdr
) < 4) {
6236 rc
= -EIO
; /* bad smb */
6240 /* check that length of list is not more than bcc */
6241 /* check that each entry does not go beyond length
6243 /* check that each element of each entry does not
6244 go beyond end of list */
6245 /* validate_trans2_offsets() */
6246 /* BB check if start of smb + data_offset > &bcc+ bcc */
6248 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
6249 ea_response_data
= (struct fealist
*)
6250 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
6252 list_len
= le32_to_cpu(ea_response_data
->list_len
);
6253 cifs_dbg(FYI
, "ea length %d\n", list_len
);
6254 if (list_len
<= 8) {
6255 cifs_dbg(FYI
, "empty EA list returned from server\n");
6256 /* didn't find the named attribute */
6262 /* make sure list_len doesn't go past end of SMB */
6263 end_of_smb
= (char *)pByteArea(&pSMBr
->hdr
) + get_bcc(&pSMBr
->hdr
);
6264 if ((char *)ea_response_data
+ list_len
> end_of_smb
) {
6265 cifs_dbg(FYI
, "EA list appears to go beyond SMB\n");
6270 /* account for ea list len */
6272 temp_fea
= ea_response_data
->list
;
6273 temp_ptr
= (char *)temp_fea
;
6274 while (list_len
> 0) {
6275 unsigned int name_len
;
6280 /* make sure we can read name_len and value_len */
6282 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6287 name_len
= temp_fea
->name_len
;
6288 value_len
= le16_to_cpu(temp_fea
->value_len
);
6289 list_len
-= name_len
+ 1 + value_len
;
6291 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6297 if (ea_name_len
== name_len
&&
6298 memcmp(ea_name
, temp_ptr
, name_len
) == 0) {
6299 temp_ptr
+= name_len
+ 1;
6303 if ((size_t)value_len
> buf_size
) {
6307 memcpy(EAData
, temp_ptr
, value_len
);
6311 /* account for prefix user. and trailing null */
6312 rc
+= (5 + 1 + name_len
);
6313 if (rc
< (int) buf_size
) {
6314 memcpy(EAData
, "user.", 5);
6316 memcpy(EAData
, temp_ptr
, name_len
);
6318 /* null terminate name */
6321 } else if (buf_size
== 0) {
6322 /* skip copy - calc size only */
6324 /* stop before overrun buffer */
6329 temp_ptr
+= name_len
+ 1 + value_len
;
6330 temp_fea
= (struct fea
*)temp_ptr
;
6333 /* didn't find the named attribute */
6338 cifs_buf_release(pSMB
);
6346 CIFSSMBSetEA(const unsigned int xid
, struct cifs_tcon
*tcon
,
6347 const char *fileName
, const char *ea_name
, const void *ea_value
,
6348 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
,
6349 struct cifs_sb_info
*cifs_sb
)
6351 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
6352 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
6353 struct fealist
*parm_data
;
6356 int bytes_returned
= 0;
6357 __u16 params
, param_offset
, byte_count
, offset
, count
;
6358 int remap
= cifs_remap(cifs_sb
);
6360 cifs_dbg(FYI
, "In SetEA\n");
6362 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6367 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6369 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
6370 PATH_MAX
, nls_codepage
, remap
);
6371 name_len
++; /* trailing null */
6373 } else { /* BB improve the check for buffer overruns BB */
6374 name_len
= strnlen(fileName
, PATH_MAX
);
6375 name_len
++; /* trailing null */
6376 strncpy(pSMB
->FileName
, fileName
, name_len
);
6379 params
= 6 + name_len
;
6381 /* done calculating parms using name_len of file name,
6382 now use name_len to calculate length of ea name
6383 we are going to create in the inode xattrs */
6384 if (ea_name
== NULL
)
6387 name_len
= strnlen(ea_name
, 255);
6389 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
;
6390 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6391 /* BB find max SMB PDU from sess */
6392 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6393 pSMB
->MaxSetupCount
= 0;
6397 pSMB
->Reserved2
= 0;
6398 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6399 InformationLevel
) - 4;
6400 offset
= param_offset
+ params
;
6401 pSMB
->InformationLevel
=
6402 cpu_to_le16(SMB_SET_FILE_EA
);
6404 parm_data
= (void *)pSMB
+ offsetof(struct smb_hdr
, Protocol
) + offset
;
6405 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6406 pSMB
->DataOffset
= cpu_to_le16(offset
);
6407 pSMB
->SetupCount
= 1;
6408 pSMB
->Reserved3
= 0;
6409 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6410 byte_count
= 3 /* pad */ + params
+ count
;
6411 pSMB
->DataCount
= cpu_to_le16(count
);
6412 parm_data
->list_len
= cpu_to_le32(count
);
6413 parm_data
->list
[0].EA_flags
= 0;
6414 /* we checked above that name len is less than 255 */
6415 parm_data
->list
[0].name_len
= (__u8
)name_len
;
6416 /* EA names are always ASCII */
6418 strncpy(parm_data
->list
[0].name
, ea_name
, name_len
);
6419 parm_data
->list
[0].name
[name_len
] = 0;
6420 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
6421 /* caller ensures that ea_value_len is less than 64K but
6422 we need to ensure that it fits within the smb */
6424 /*BB add length check to see if it would fit in
6425 negotiated SMB buffer size BB */
6426 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6428 memcpy(parm_data
->list
[0].name
+name_len
+1,
6429 ea_value
, ea_value_len
);
6431 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6432 pSMB
->ParameterCount
= cpu_to_le16(params
);
6433 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6434 pSMB
->Reserved4
= 0;
6435 inc_rfc1001_len(pSMB
, byte_count
);
6436 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6437 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6438 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6440 cifs_dbg(FYI
, "SetPathInfo (EA) returned %d\n", rc
);
6442 cifs_buf_release(pSMB
);
6451 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6453 * Years ago the kernel added a "dnotify" function for Samba server,
6454 * to allow network clients (such as Windows) to display updated
6455 * lists of files in directory listings automatically when
6456 * files are added by one user when another user has the
6457 * same directory open on their desktop. The Linux cifs kernel
6458 * client hooked into the kernel side of this interface for
6459 * the same reason, but ironically when the VFS moved from
6460 * "dnotify" to "inotify" it became harder to plug in Linux
6461 * network file system clients (the most obvious use case
6462 * for notify interfaces is when multiple users can update
6463 * the contents of the same directory - exactly what network
6464 * file systems can do) although the server (Samba) could
6465 * still use it. For the short term we leave the worker
6466 * function ifdeffed out (below) until inotify is fixed
6467 * in the VFS to make it easier to plug in network file
6468 * system clients. If inotify turns out to be permanently
6469 * incompatible for network fs clients, we could instead simply
6470 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6472 int CIFSSMBNotify(const unsigned int xid
, struct cifs_tcon
*tcon
,
6473 const int notify_subdirs
, const __u16 netfid
,
6474 __u32 filter
, struct file
*pfile
, int multishot
,
6475 const struct nls_table
*nls_codepage
)
6478 struct smb_com_transaction_change_notify_req
*pSMB
= NULL
;
6479 struct smb_com_ntransaction_change_notify_rsp
*pSMBr
= NULL
;
6480 struct dir_notify_req
*dnotify_req
;
6483 cifs_dbg(FYI
, "In CIFSSMBNotify for file handle %d\n", (int)netfid
);
6484 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
6489 pSMB
->TotalParameterCount
= 0 ;
6490 pSMB
->TotalDataCount
= 0;
6491 pSMB
->MaxParameterCount
= cpu_to_le32(2);
6492 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
6493 pSMB
->MaxSetupCount
= 4;
6495 pSMB
->ParameterOffset
= 0;
6496 pSMB
->DataCount
= 0;
6497 pSMB
->DataOffset
= 0;
6498 pSMB
->SetupCount
= 4; /* single byte does not need le conversion */
6499 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE
);
6500 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6502 pSMB
->WatchTree
= 1; /* one byte - no le conversion needed */
6503 pSMB
->Reserved2
= 0;
6504 pSMB
->CompletionFilter
= cpu_to_le32(filter
);
6505 pSMB
->Fid
= netfid
; /* file handle always le */
6506 pSMB
->ByteCount
= 0;
6508 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6509 (struct smb_hdr
*)pSMBr
, &bytes_returned
,
6512 cifs_dbg(FYI
, "Error in Notify = %d\n", rc
);
6514 /* Add file to outstanding requests */
6515 /* BB change to kmem cache alloc */
6516 dnotify_req
= kmalloc(
6517 sizeof(struct dir_notify_req
),
6520 dnotify_req
->Pid
= pSMB
->hdr
.Pid
;
6521 dnotify_req
->PidHigh
= pSMB
->hdr
.PidHigh
;
6522 dnotify_req
->Mid
= pSMB
->hdr
.Mid
;
6523 dnotify_req
->Tid
= pSMB
->hdr
.Tid
;
6524 dnotify_req
->Uid
= pSMB
->hdr
.Uid
;
6525 dnotify_req
->netfid
= netfid
;
6526 dnotify_req
->pfile
= pfile
;
6527 dnotify_req
->filter
= filter
;
6528 dnotify_req
->multishot
= multishot
;
6529 spin_lock(&GlobalMid_Lock
);
6530 list_add_tail(&dnotify_req
->lhead
,
6531 &GlobalDnotifyReqList
);
6532 spin_unlock(&GlobalMid_Lock
);
6536 cifs_buf_release(pSMB
);
6539 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */