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 <asm/uaccess.h>
42 #include "cifsproto.h"
43 #include "cifs_unicode.h"
44 #include "cifs_debug.h"
47 #ifdef CONFIG_CIFS_POSIX
52 #ifdef CONFIG_CIFS_WEAK_PW_HASH
53 {LANMAN_PROT
, "\2LM1.2X002"},
54 {LANMAN2_PROT
, "\2LANMAN2.1"},
55 #endif /* weak password hashing for legacy clients */
56 {CIFS_PROT
, "\2NT LM 0.12"},
57 {POSIX_PROT
, "\2POSIX 2"},
65 #ifdef CONFIG_CIFS_WEAK_PW_HASH
66 {LANMAN_PROT
, "\2LM1.2X002"},
67 {LANMAN2_PROT
, "\2LANMAN2.1"},
68 #endif /* weak password hashing for legacy clients */
69 {CIFS_PROT
, "\2NT LM 0.12"},
74 /* define the number of elements in the cifs dialect array */
75 #ifdef CONFIG_CIFS_POSIX
76 #ifdef CONFIG_CIFS_WEAK_PW_HASH
77 #define CIFS_NUM_PROT 4
79 #define CIFS_NUM_PROT 2
80 #endif /* CIFS_WEAK_PW_HASH */
82 #ifdef CONFIG_CIFS_WEAK_PW_HASH
83 #define CIFS_NUM_PROT 3
85 #define CIFS_NUM_PROT 1
86 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
87 #endif /* CIFS_POSIX */
91 * On arches that have high memory, kmap address space is limited. By
92 * serializing the kmap operations on those arches, we ensure that we don't
93 * end up with a bunch of threads in writeback with partially mapped page
94 * arrays, stuck waiting for kmap to come back. That situation prevents
95 * progress and can deadlock.
97 static DEFINE_MUTEX(cifs_kmap_mutex
);
102 mutex_lock(&cifs_kmap_mutex
);
106 cifs_kmap_unlock(void)
108 mutex_unlock(&cifs_kmap_mutex
);
110 #else /* !CONFIG_HIGHMEM */
111 #define cifs_kmap_lock() do { ; } while(0)
112 #define cifs_kmap_unlock() do { ; } while(0)
113 #endif /* CONFIG_HIGHMEM */
115 /* Mark as invalid, all open files on tree connections since they
116 were closed when session to server was lost */
117 static void mark_open_files_invalid(struct cifs_tcon
*pTcon
)
119 struct cifsFileInfo
*open_file
= NULL
;
120 struct list_head
*tmp
;
121 struct list_head
*tmp1
;
123 /* list all files open on tree connection and mark them invalid */
124 spin_lock(&cifs_file_list_lock
);
125 list_for_each_safe(tmp
, tmp1
, &pTcon
->openFileList
) {
126 open_file
= list_entry(tmp
, struct cifsFileInfo
, tlist
);
127 open_file
->invalidHandle
= true;
128 open_file
->oplock_break_cancelled
= true;
130 spin_unlock(&cifs_file_list_lock
);
131 /* BB Add call to invalidate_inodes(sb) for all superblocks mounted
135 /* reconnect the socket, tcon, and smb session if needed */
137 cifs_reconnect_tcon(struct cifs_tcon
*tcon
, int smb_command
)
140 struct cifs_ses
*ses
;
141 struct TCP_Server_Info
*server
;
142 struct nls_table
*nls_codepage
;
145 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
146 * tcp and smb session status done differently for those three - in the
153 server
= ses
->server
;
156 * only tree disconnect, open, and write, (and ulogoff which does not
157 * have tcon) are allowed as we start force umount
159 if (tcon
->tidStatus
== CifsExiting
) {
160 if (smb_command
!= SMB_COM_WRITE_ANDX
&&
161 smb_command
!= SMB_COM_OPEN_ANDX
&&
162 smb_command
!= SMB_COM_TREE_DISCONNECT
) {
163 cFYI(1, "can not send cmd %d while umounting",
170 * Give demultiplex thread up to 10 seconds to reconnect, should be
171 * greater than cifs socket timeout which is 7 seconds
173 while (server
->tcpStatus
== CifsNeedReconnect
) {
174 wait_event_interruptible_timeout(server
->response_q
,
175 (server
->tcpStatus
!= CifsNeedReconnect
), 10 * HZ
);
177 /* are we still trying to reconnect? */
178 if (server
->tcpStatus
!= CifsNeedReconnect
)
182 * on "soft" mounts we wait once. Hard mounts keep
183 * retrying until process is killed or server comes
187 cFYI(1, "gave up waiting on reconnect in smb_init");
192 if (!ses
->need_reconnect
&& !tcon
->need_reconnect
)
195 nls_codepage
= load_nls_default();
198 * need to prevent multiple threads trying to simultaneously
199 * reconnect the same SMB session
201 mutex_lock(&ses
->session_mutex
);
202 rc
= cifs_negotiate_protocol(0, ses
);
203 if (rc
== 0 && ses
->need_reconnect
)
204 rc
= cifs_setup_session(0, ses
, nls_codepage
);
206 /* do we need to reconnect tcon? */
207 if (rc
|| !tcon
->need_reconnect
) {
208 mutex_unlock(&ses
->session_mutex
);
212 mark_open_files_invalid(tcon
);
213 rc
= CIFSTCon(0, ses
, tcon
->treeName
, tcon
, nls_codepage
);
214 mutex_unlock(&ses
->session_mutex
);
215 cFYI(1, "reconnect tcon rc = %d", rc
);
221 * FIXME: check if wsize needs updated due to negotiated smb buffer
224 atomic_inc(&tconInfoReconnectCount
);
226 /* tell server Unix caps we support */
227 if (ses
->capabilities
& CAP_UNIX
)
228 reset_cifs_unix_caps(0, tcon
, NULL
, NULL
);
231 * Removed call to reopen open files here. It is safer (and faster) to
232 * reopen files one at a time as needed in read and write.
234 * FIXME: what about file locks? don't we need to reclaim them ASAP?
239 * Check if handle based operation so we know whether we can continue
240 * or not without returning to caller to reset file handle
242 switch (smb_command
) {
243 case SMB_COM_READ_ANDX
:
244 case SMB_COM_WRITE_ANDX
:
246 case SMB_COM_FIND_CLOSE2
:
247 case SMB_COM_LOCKING_ANDX
:
251 unload_nls(nls_codepage
);
255 /* Allocate and return pointer to an SMB request buffer, and set basic
256 SMB information in the SMB header. If the return code is zero, this
257 function must have filled in request_buf pointer */
259 small_smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
264 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
268 *request_buf
= cifs_small_buf_get();
269 if (*request_buf
== NULL
) {
270 /* BB should we add a retry in here if not a writepage? */
274 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
,
278 cifs_stats_inc(&tcon
->num_smbs_sent
);
284 small_smb_init_no_tc(const int smb_command
, const int wct
,
285 struct cifs_ses
*ses
, void **request_buf
)
288 struct smb_hdr
*buffer
;
290 rc
= small_smb_init(smb_command
, wct
, NULL
, request_buf
);
294 buffer
= (struct smb_hdr
*)*request_buf
;
295 buffer
->Mid
= get_next_mid(ses
->server
);
296 if (ses
->capabilities
& CAP_UNICODE
)
297 buffer
->Flags2
|= SMBFLG2_UNICODE
;
298 if (ses
->capabilities
& CAP_STATUS32
)
299 buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
301 /* uid, tid can stay at zero as set in header assemble */
303 /* BB add support for turning on the signing when
304 this function is used after 1st of session setup requests */
309 /* If the return code is zero, this function must fill in request_buf pointer */
311 __smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
312 void **request_buf
, void **response_buf
)
314 *request_buf
= cifs_buf_get();
315 if (*request_buf
== NULL
) {
316 /* BB should we add a retry in here if not a writepage? */
319 /* Although the original thought was we needed the response buf for */
320 /* potential retries of smb operations it turns out we can determine */
321 /* from the mid flags when the request buffer can be resent without */
322 /* having to use a second distinct buffer for the response */
324 *response_buf
= *request_buf
;
326 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
, tcon
,
330 cifs_stats_inc(&tcon
->num_smbs_sent
);
335 /* If the return code is zero, this function must fill in request_buf pointer */
337 smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
338 void **request_buf
, void **response_buf
)
342 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
346 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
350 smb_init_no_reconnect(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
351 void **request_buf
, void **response_buf
)
353 if (tcon
->ses
->need_reconnect
|| tcon
->need_reconnect
)
356 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
359 static int validate_t2(struct smb_t2_rsp
*pSMB
)
361 unsigned int total_size
;
363 /* check for plausible wct */
364 if (pSMB
->hdr
.WordCount
< 10)
367 /* check for parm and data offset going beyond end of smb */
368 if (get_unaligned_le16(&pSMB
->t2_rsp
.ParameterOffset
) > 1024 ||
369 get_unaligned_le16(&pSMB
->t2_rsp
.DataOffset
) > 1024)
372 total_size
= get_unaligned_le16(&pSMB
->t2_rsp
.ParameterCount
);
373 if (total_size
>= 512)
376 /* check that bcc is at least as big as parms + data, and that it is
377 * less than negotiated smb buffer
379 total_size
+= get_unaligned_le16(&pSMB
->t2_rsp
.DataCount
);
380 if (total_size
> get_bcc(&pSMB
->hdr
) ||
381 total_size
>= CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
)
386 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB
,
387 sizeof(struct smb_t2_rsp
) + 16);
391 static inline void inc_rfc1001_len(void *pSMB
, int count
)
393 struct smb_hdr
*hdr
= (struct smb_hdr
*)pSMB
;
395 be32_add_cpu(&hdr
->smb_buf_length
, count
);
399 CIFSSMBNegotiate(unsigned int xid
, struct cifs_ses
*ses
)
402 NEGOTIATE_RSP
*pSMBr
;
406 struct TCP_Server_Info
*server
;
408 unsigned int secFlags
;
411 server
= ses
->server
;
416 rc
= smb_init(SMB_COM_NEGOTIATE
, 0, NULL
/* no tcon yet */ ,
417 (void **) &pSMB
, (void **) &pSMBr
);
421 /* if any of auth flags (ie not sign or seal) are overriden use them */
422 if (ses
->overrideSecFlg
& (~(CIFSSEC_MUST_SIGN
| CIFSSEC_MUST_SEAL
)))
423 secFlags
= ses
->overrideSecFlg
; /* BB FIXME fix sign flags? */
424 else /* if override flags set only sign/seal OR them with global auth */
425 secFlags
= global_secflags
| ses
->overrideSecFlg
;
427 cFYI(1, "secFlags 0x%x", secFlags
);
429 pSMB
->hdr
.Mid
= get_next_mid(server
);
430 pSMB
->hdr
.Flags2
|= (SMBFLG2_UNICODE
| SMBFLG2_ERR_STATUS
);
432 if ((secFlags
& CIFSSEC_MUST_KRB5
) == CIFSSEC_MUST_KRB5
)
433 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
434 else if ((secFlags
& CIFSSEC_AUTH_MASK
) == CIFSSEC_MAY_KRB5
) {
435 cFYI(1, "Kerberos only mechanism, enable extended security");
436 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
437 } else if ((secFlags
& CIFSSEC_MUST_NTLMSSP
) == CIFSSEC_MUST_NTLMSSP
)
438 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
439 else if ((secFlags
& CIFSSEC_AUTH_MASK
) == CIFSSEC_MAY_NTLMSSP
) {
440 cFYI(1, "NTLMSSP only mechanism, enable extended security");
441 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
445 for (i
= 0; i
< CIFS_NUM_PROT
; i
++) {
446 strncpy(pSMB
->DialectsArray
+count
, protocols
[i
].name
, 16);
447 count
+= strlen(protocols
[i
].name
) + 1;
448 /* null at end of source and target buffers anyway */
450 inc_rfc1001_len(pSMB
, count
);
451 pSMB
->ByteCount
= cpu_to_le16(count
);
453 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
454 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
458 server
->dialect
= le16_to_cpu(pSMBr
->DialectIndex
);
459 cFYI(1, "Dialect: %d", server
->dialect
);
460 /* Check wct = 1 error case */
461 if ((pSMBr
->hdr
.WordCount
< 13) || (server
->dialect
== BAD_PROT
)) {
462 /* core returns wct = 1, but we do not ask for core - otherwise
463 small wct just comes when dialect index is -1 indicating we
464 could not negotiate a common dialect */
467 #ifdef CONFIG_CIFS_WEAK_PW_HASH
468 } else if ((pSMBr
->hdr
.WordCount
== 13)
469 && ((server
->dialect
== LANMAN_PROT
)
470 || (server
->dialect
== LANMAN2_PROT
))) {
472 struct lanman_neg_rsp
*rsp
= (struct lanman_neg_rsp
*)pSMBr
;
474 if ((secFlags
& CIFSSEC_MAY_LANMAN
) ||
475 (secFlags
& CIFSSEC_MAY_PLNTXT
))
476 server
->secType
= LANMAN
;
478 cERROR(1, "mount failed weak security disabled"
479 " in /proc/fs/cifs/SecurityFlags");
483 server
->sec_mode
= (__u8
)le16_to_cpu(rsp
->SecurityMode
);
484 server
->maxReq
= min_t(unsigned int,
485 le16_to_cpu(rsp
->MaxMpxCount
),
487 set_credits(server
, server
->maxReq
);
488 server
->maxBuf
= le16_to_cpu(rsp
->MaxBufSize
);
489 server
->max_vcs
= le16_to_cpu(rsp
->MaxNumberVcs
);
490 /* even though we do not use raw we might as well set this
491 accurately, in case we ever find a need for it */
492 if ((le16_to_cpu(rsp
->RawMode
) & RAW_ENABLE
) == RAW_ENABLE
) {
493 server
->max_rw
= 0xFF00;
494 server
->capabilities
= CAP_MPX_MODE
| CAP_RAW_MODE
;
496 server
->max_rw
= 0;/* do not need to use raw anyway */
497 server
->capabilities
= CAP_MPX_MODE
;
499 tmp
= (__s16
)le16_to_cpu(rsp
->ServerTimeZone
);
501 /* OS/2 often does not set timezone therefore
502 * we must use server time to calc time zone.
503 * Could deviate slightly from the right zone.
504 * Smallest defined timezone difference is 15 minutes
505 * (i.e. Nepal). Rounding up/down is done to match
508 int val
, seconds
, remain
, result
;
509 struct timespec ts
, utc
;
511 ts
= cnvrtDosUnixTm(rsp
->SrvTime
.Date
,
512 rsp
->SrvTime
.Time
, 0);
513 cFYI(1, "SrvTime %d sec since 1970 (utc: %d) diff: %d",
514 (int)ts
.tv_sec
, (int)utc
.tv_sec
,
515 (int)(utc
.tv_sec
- ts
.tv_sec
));
516 val
= (int)(utc
.tv_sec
- ts
.tv_sec
);
518 result
= (seconds
/ MIN_TZ_ADJ
) * MIN_TZ_ADJ
;
519 remain
= seconds
% MIN_TZ_ADJ
;
520 if (remain
>= (MIN_TZ_ADJ
/ 2))
521 result
+= MIN_TZ_ADJ
;
524 server
->timeAdj
= result
;
526 server
->timeAdj
= (int)tmp
;
527 server
->timeAdj
*= 60; /* also in seconds */
529 cFYI(1, "server->timeAdj: %d seconds", server
->timeAdj
);
532 /* BB get server time for time conversions and add
533 code to use it and timezone since this is not UTC */
535 if (rsp
->EncryptionKeyLength
==
536 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE
)) {
537 memcpy(ses
->server
->cryptkey
, rsp
->EncryptionKey
,
538 CIFS_CRYPTO_KEY_SIZE
);
539 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
540 rc
= -EIO
; /* need cryptkey unless plain text */
544 cFYI(1, "LANMAN negotiated");
545 /* we will not end up setting signing flags - as no signing
546 was in LANMAN and server did not return the flags on */
548 #else /* weak security disabled */
549 } else if (pSMBr
->hdr
.WordCount
== 13) {
550 cERROR(1, "mount failed, cifs module not built "
551 "with CIFS_WEAK_PW_HASH support");
553 #endif /* WEAK_PW_HASH */
555 } else if (pSMBr
->hdr
.WordCount
!= 17) {
560 /* else wct == 17 NTLM */
561 server
->sec_mode
= pSMBr
->SecurityMode
;
562 if ((server
->sec_mode
& SECMODE_USER
) == 0)
563 cFYI(1, "share mode security");
565 if ((server
->sec_mode
& SECMODE_PW_ENCRYPT
) == 0)
566 #ifdef CONFIG_CIFS_WEAK_PW_HASH
567 if ((secFlags
& CIFSSEC_MAY_PLNTXT
) == 0)
568 #endif /* CIFS_WEAK_PW_HASH */
569 cERROR(1, "Server requests plain text password"
570 " but client support disabled");
572 if ((secFlags
& CIFSSEC_MUST_NTLMV2
) == CIFSSEC_MUST_NTLMV2
)
573 server
->secType
= NTLMv2
;
574 else if (secFlags
& CIFSSEC_MAY_NTLM
)
575 server
->secType
= NTLM
;
576 else if (secFlags
& CIFSSEC_MAY_NTLMV2
)
577 server
->secType
= NTLMv2
;
578 else if (secFlags
& CIFSSEC_MAY_KRB5
)
579 server
->secType
= Kerberos
;
580 else if (secFlags
& CIFSSEC_MAY_NTLMSSP
)
581 server
->secType
= RawNTLMSSP
;
582 else if (secFlags
& CIFSSEC_MAY_LANMAN
)
583 server
->secType
= LANMAN
;
586 cERROR(1, "Invalid security type");
589 /* else ... any others ...? */
591 /* one byte, so no need to convert this or EncryptionKeyLen from
593 server
->maxReq
= min_t(unsigned int, le16_to_cpu(pSMBr
->MaxMpxCount
),
595 set_credits(server
, server
->maxReq
);
596 /* probably no need to store and check maxvcs */
597 server
->maxBuf
= le32_to_cpu(pSMBr
->MaxBufferSize
);
598 server
->max_rw
= le32_to_cpu(pSMBr
->MaxRawSize
);
599 cFYI(DBG2
, "Max buf = %d", ses
->server
->maxBuf
);
600 server
->capabilities
= le32_to_cpu(pSMBr
->Capabilities
);
601 server
->timeAdj
= (int)(__s16
)le16_to_cpu(pSMBr
->ServerTimeZone
);
602 server
->timeAdj
*= 60;
603 if (pSMBr
->EncryptionKeyLength
== CIFS_CRYPTO_KEY_SIZE
) {
604 memcpy(ses
->server
->cryptkey
, pSMBr
->u
.EncryptionKey
,
605 CIFS_CRYPTO_KEY_SIZE
);
606 } else if ((pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
||
607 server
->capabilities
& CAP_EXTENDED_SECURITY
) &&
608 (pSMBr
->EncryptionKeyLength
== 0)) {
609 /* decode security blob */
610 count
= get_bcc(&pSMBr
->hdr
);
615 spin_lock(&cifs_tcp_ses_lock
);
616 if (server
->srv_count
> 1) {
617 spin_unlock(&cifs_tcp_ses_lock
);
618 if (memcmp(server
->server_GUID
,
619 pSMBr
->u
.extended_response
.
621 cFYI(1, "server UID changed");
622 memcpy(server
->server_GUID
,
623 pSMBr
->u
.extended_response
.GUID
,
627 spin_unlock(&cifs_tcp_ses_lock
);
628 memcpy(server
->server_GUID
,
629 pSMBr
->u
.extended_response
.GUID
, 16);
633 server
->secType
= RawNTLMSSP
;
635 rc
= decode_negTokenInit(pSMBr
->u
.extended_response
.
636 SecurityBlob
, count
- 16,
642 if (server
->secType
== Kerberos
) {
643 if (!server
->sec_kerberos
&&
644 !server
->sec_mskerberos
)
646 } else if (server
->secType
== RawNTLMSSP
) {
647 if (!server
->sec_ntlmssp
)
652 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
653 rc
= -EIO
; /* no crypt key only if plain text pwd */
656 server
->capabilities
&= ~CAP_EXTENDED_SECURITY
;
658 #ifdef CONFIG_CIFS_WEAK_PW_HASH
661 if ((secFlags
& CIFSSEC_MAY_SIGN
) == 0) {
662 /* MUST_SIGN already includes the MAY_SIGN FLAG
663 so if this is zero it means that signing is disabled */
664 cFYI(1, "Signing disabled");
665 if (server
->sec_mode
& SECMODE_SIGN_REQUIRED
) {
666 cERROR(1, "Server requires "
667 "packet signing to be enabled in "
668 "/proc/fs/cifs/SecurityFlags.");
672 ~(SECMODE_SIGN_ENABLED
| SECMODE_SIGN_REQUIRED
);
673 } else if ((secFlags
& CIFSSEC_MUST_SIGN
) == CIFSSEC_MUST_SIGN
) {
674 /* signing required */
675 cFYI(1, "Must sign - secFlags 0x%x", secFlags
);
676 if ((server
->sec_mode
&
677 (SECMODE_SIGN_ENABLED
| SECMODE_SIGN_REQUIRED
)) == 0) {
678 cERROR(1, "signing required but server lacks support");
681 server
->sec_mode
|= SECMODE_SIGN_REQUIRED
;
683 /* signing optional ie CIFSSEC_MAY_SIGN */
684 if ((server
->sec_mode
& SECMODE_SIGN_REQUIRED
) == 0)
686 ~(SECMODE_SIGN_ENABLED
| SECMODE_SIGN_REQUIRED
);
690 cifs_buf_release(pSMB
);
692 cFYI(1, "negprot rc %d", rc
);
697 CIFSSMBTDis(const int xid
, struct cifs_tcon
*tcon
)
699 struct smb_hdr
*smb_buffer
;
702 cFYI(1, "In tree disconnect");
704 /* BB: do we need to check this? These should never be NULL. */
705 if ((tcon
->ses
== NULL
) || (tcon
->ses
->server
== NULL
))
709 * No need to return error on this operation if tid invalidated and
710 * closed on server already e.g. due to tcp session crashing. Also,
711 * the tcon is no longer on the list, so no need to take lock before
714 if ((tcon
->need_reconnect
) || (tcon
->ses
->need_reconnect
))
717 rc
= small_smb_init(SMB_COM_TREE_DISCONNECT
, 0, tcon
,
718 (void **)&smb_buffer
);
722 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)smb_buffer
, 0);
724 cFYI(1, "Tree disconnect failed %d", rc
);
726 /* No need to return error on this operation if tid invalidated and
727 closed on server already e.g. due to tcp session crashing */
735 * This is a no-op for now. We're not really interested in the reply, but
736 * rather in the fact that the server sent one and that server->lstrp
739 * FIXME: maybe we should consider checking that the reply matches request?
742 cifs_echo_callback(struct mid_q_entry
*mid
)
744 struct TCP_Server_Info
*server
= mid
->callback_data
;
746 DeleteMidQEntry(mid
);
747 add_credits(server
, 1, CIFS_ECHO_OP
);
751 CIFSSMBEcho(struct TCP_Server_Info
*server
)
757 cFYI(1, "In echo request");
759 rc
= small_smb_init(SMB_COM_ECHO
, 0, NULL
, (void **)&smb
);
763 /* set up echo request */
764 smb
->hdr
.Tid
= 0xffff;
765 smb
->hdr
.WordCount
= 1;
766 put_unaligned_le16(1, &smb
->EchoCount
);
767 put_bcc(1, &smb
->hdr
);
769 inc_rfc1001_len(smb
, 3);
771 iov
.iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4;
773 rc
= cifs_call_async(server
, &iov
, 1, NULL
, cifs_echo_callback
,
774 server
, CIFS_ASYNC_OP
| CIFS_ECHO_OP
);
776 cFYI(1, "Echo request failed: %d", rc
);
778 cifs_small_buf_release(smb
);
784 CIFSSMBLogoff(const int xid
, struct cifs_ses
*ses
)
786 LOGOFF_ANDX_REQ
*pSMB
;
789 cFYI(1, "In SMBLogoff for session disconnect");
792 * BB: do we need to check validity of ses and server? They should
793 * always be valid since we have an active reference. If not, that
794 * should probably be a BUG()
796 if (!ses
|| !ses
->server
)
799 mutex_lock(&ses
->session_mutex
);
800 if (ses
->need_reconnect
)
801 goto session_already_dead
; /* no need to send SMBlogoff if uid
802 already closed due to reconnect */
803 rc
= small_smb_init(SMB_COM_LOGOFF_ANDX
, 2, NULL
, (void **)&pSMB
);
805 mutex_unlock(&ses
->session_mutex
);
809 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
811 if (ses
->server
->sec_mode
&
812 (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
))
813 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
815 pSMB
->hdr
.Uid
= ses
->Suid
;
817 pSMB
->AndXCommand
= 0xFF;
818 rc
= SendReceiveNoRsp(xid
, ses
, (char *) pSMB
, 0);
819 session_already_dead
:
820 mutex_unlock(&ses
->session_mutex
);
822 /* if session dead then we do not need to do ulogoff,
823 since server closed smb session, no sense reporting
831 CIFSPOSIXDelFile(const int xid
, struct cifs_tcon
*tcon
, const char *fileName
,
832 __u16 type
, const struct nls_table
*nls_codepage
, int remap
)
834 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
835 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
836 struct unlink_psx_rq
*pRqD
;
839 int bytes_returned
= 0;
840 __u16 params
, param_offset
, offset
, byte_count
;
842 cFYI(1, "In POSIX delete");
844 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
849 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
851 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
852 PATH_MAX
, nls_codepage
, remap
);
853 name_len
++; /* trailing null */
855 } else { /* BB add path length overrun check */
856 name_len
= strnlen(fileName
, PATH_MAX
);
857 name_len
++; /* trailing null */
858 strncpy(pSMB
->FileName
, fileName
, name_len
);
861 params
= 6 + name_len
;
862 pSMB
->MaxParameterCount
= cpu_to_le16(2);
863 pSMB
->MaxDataCount
= 0; /* BB double check this with jra */
864 pSMB
->MaxSetupCount
= 0;
869 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
870 InformationLevel
) - 4;
871 offset
= param_offset
+ params
;
873 /* Setup pointer to Request Data (inode type) */
874 pRqD
= (struct unlink_psx_rq
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
875 pRqD
->type
= cpu_to_le16(type
);
876 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
877 pSMB
->DataOffset
= cpu_to_le16(offset
);
878 pSMB
->SetupCount
= 1;
880 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
881 byte_count
= 3 /* pad */ + params
+ sizeof(struct unlink_psx_rq
);
883 pSMB
->DataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
884 pSMB
->TotalDataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
885 pSMB
->ParameterCount
= cpu_to_le16(params
);
886 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
887 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_UNLINK
);
889 inc_rfc1001_len(pSMB
, byte_count
);
890 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
891 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
892 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
894 cFYI(1, "Posix delete returned %d", rc
);
895 cifs_buf_release(pSMB
);
897 cifs_stats_inc(&tcon
->num_deletes
);
906 CIFSSMBDelFile(const int xid
, struct cifs_tcon
*tcon
, const char *fileName
,
907 const struct nls_table
*nls_codepage
, int remap
)
909 DELETE_FILE_REQ
*pSMB
= NULL
;
910 DELETE_FILE_RSP
*pSMBr
= NULL
;
916 rc
= smb_init(SMB_COM_DELETE
, 1, tcon
, (void **) &pSMB
,
921 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
923 cifsConvertToUTF16((__le16
*) pSMB
->fileName
, fileName
,
924 PATH_MAX
, nls_codepage
, remap
);
925 name_len
++; /* trailing null */
927 } else { /* BB improve check for buffer overruns BB */
928 name_len
= strnlen(fileName
, PATH_MAX
);
929 name_len
++; /* trailing null */
930 strncpy(pSMB
->fileName
, fileName
, name_len
);
932 pSMB
->SearchAttributes
=
933 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
);
934 pSMB
->BufferFormat
= 0x04;
935 inc_rfc1001_len(pSMB
, name_len
+ 1);
936 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
937 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
938 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
939 cifs_stats_inc(&tcon
->num_deletes
);
941 cFYI(1, "Error in RMFile = %d", rc
);
943 cifs_buf_release(pSMB
);
951 CIFSSMBRmDir(const int xid
, struct cifs_tcon
*tcon
, const char *dirName
,
952 const struct nls_table
*nls_codepage
, int remap
)
954 DELETE_DIRECTORY_REQ
*pSMB
= NULL
;
955 DELETE_DIRECTORY_RSP
*pSMBr
= NULL
;
960 cFYI(1, "In CIFSSMBRmDir");
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
, dirName
,
969 PATH_MAX
, nls_codepage
, remap
);
970 name_len
++; /* trailing null */
972 } else { /* BB improve check for buffer overruns BB */
973 name_len
= strnlen(dirName
, PATH_MAX
);
974 name_len
++; /* trailing null */
975 strncpy(pSMB
->DirName
, dirName
, name_len
);
978 pSMB
->BufferFormat
= 0x04;
979 inc_rfc1001_len(pSMB
, name_len
+ 1);
980 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
981 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
982 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
983 cifs_stats_inc(&tcon
->num_rmdirs
);
985 cFYI(1, "Error in RMDir = %d", rc
);
987 cifs_buf_release(pSMB
);
994 CIFSSMBMkDir(const int xid
, struct cifs_tcon
*tcon
,
995 const char *name
, const struct nls_table
*nls_codepage
, int remap
)
998 CREATE_DIRECTORY_REQ
*pSMB
= NULL
;
999 CREATE_DIRECTORY_RSP
*pSMBr
= NULL
;
1003 cFYI(1, "In CIFSSMBMkDir");
1005 rc
= smb_init(SMB_COM_CREATE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
1010 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1011 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
1012 PATH_MAX
, nls_codepage
, remap
);
1013 name_len
++; /* trailing null */
1015 } else { /* BB improve check for buffer overruns BB */
1016 name_len
= strnlen(name
, PATH_MAX
);
1017 name_len
++; /* trailing null */
1018 strncpy(pSMB
->DirName
, name
, name_len
);
1021 pSMB
->BufferFormat
= 0x04;
1022 inc_rfc1001_len(pSMB
, name_len
+ 1);
1023 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1024 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1025 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1026 cifs_stats_inc(&tcon
->num_mkdirs
);
1028 cFYI(1, "Error in Mkdir = %d", rc
);
1030 cifs_buf_release(pSMB
);
1037 CIFSPOSIXCreate(const int xid
, struct cifs_tcon
*tcon
, __u32 posix_flags
,
1038 __u64 mode
, __u16
*netfid
, FILE_UNIX_BASIC_INFO
*pRetData
,
1039 __u32
*pOplock
, const char *name
,
1040 const struct nls_table
*nls_codepage
, int remap
)
1042 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
1043 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
1046 int bytes_returned
= 0;
1047 __u16 params
, param_offset
, offset
, byte_count
, count
;
1048 OPEN_PSX_REQ
*pdata
;
1049 OPEN_PSX_RSP
*psx_rsp
;
1051 cFYI(1, "In POSIX Create");
1053 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1058 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1060 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, name
,
1061 PATH_MAX
, nls_codepage
, remap
);
1062 name_len
++; /* trailing null */
1064 } else { /* BB improve the check for buffer overruns BB */
1065 name_len
= strnlen(name
, PATH_MAX
);
1066 name_len
++; /* trailing null */
1067 strncpy(pSMB
->FileName
, name
, name_len
);
1070 params
= 6 + name_len
;
1071 count
= sizeof(OPEN_PSX_REQ
);
1072 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1073 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* large enough */
1074 pSMB
->MaxSetupCount
= 0;
1078 pSMB
->Reserved2
= 0;
1079 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
1080 InformationLevel
) - 4;
1081 offset
= param_offset
+ params
;
1082 pdata
= (OPEN_PSX_REQ
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
1083 pdata
->Level
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
1084 pdata
->Permissions
= cpu_to_le64(mode
);
1085 pdata
->PosixOpenFlags
= cpu_to_le32(posix_flags
);
1086 pdata
->OpenFlags
= cpu_to_le32(*pOplock
);
1087 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
1088 pSMB
->DataOffset
= cpu_to_le16(offset
);
1089 pSMB
->SetupCount
= 1;
1090 pSMB
->Reserved3
= 0;
1091 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
1092 byte_count
= 3 /* pad */ + params
+ count
;
1094 pSMB
->DataCount
= cpu_to_le16(count
);
1095 pSMB
->ParameterCount
= cpu_to_le16(params
);
1096 pSMB
->TotalDataCount
= pSMB
->DataCount
;
1097 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1098 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_OPEN
);
1099 pSMB
->Reserved4
= 0;
1100 inc_rfc1001_len(pSMB
, byte_count
);
1101 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1102 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1103 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1105 cFYI(1, "Posix create returned %d", rc
);
1106 goto psx_create_err
;
1109 cFYI(1, "copying inode info");
1110 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
1112 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)) {
1113 rc
= -EIO
; /* bad smb */
1114 goto psx_create_err
;
1117 /* copy return information to pRetData */
1118 psx_rsp
= (OPEN_PSX_RSP
*)((char *) &pSMBr
->hdr
.Protocol
1119 + le16_to_cpu(pSMBr
->t2
.DataOffset
));
1121 *pOplock
= le16_to_cpu(psx_rsp
->OplockFlags
);
1123 *netfid
= psx_rsp
->Fid
; /* cifs fid stays in le */
1124 /* Let caller know file was created so we can set the mode. */
1125 /* Do we care about the CreateAction in any other cases? */
1126 if (cpu_to_le32(FILE_CREATE
) == psx_rsp
->CreateAction
)
1127 *pOplock
|= CIFS_CREATE_ACTION
;
1128 /* check to make sure response data is there */
1129 if (psx_rsp
->ReturnedLevel
!= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
)) {
1130 pRetData
->Type
= cpu_to_le32(-1); /* unknown */
1131 cFYI(DBG2
, "unknown type");
1133 if (get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)
1134 + sizeof(FILE_UNIX_BASIC_INFO
)) {
1135 cERROR(1, "Open response data too small");
1136 pRetData
->Type
= cpu_to_le32(-1);
1137 goto psx_create_err
;
1139 memcpy((char *) pRetData
,
1140 (char *)psx_rsp
+ sizeof(OPEN_PSX_RSP
),
1141 sizeof(FILE_UNIX_BASIC_INFO
));
1145 cifs_buf_release(pSMB
);
1147 if (posix_flags
& SMB_O_DIRECTORY
)
1148 cifs_stats_inc(&tcon
->num_posixmkdirs
);
1150 cifs_stats_inc(&tcon
->num_posixopens
);
1158 static __u16
convert_disposition(int disposition
)
1162 switch (disposition
) {
1163 case FILE_SUPERSEDE
:
1164 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1167 ofun
= SMBOPEN_OAPPEND
;
1170 ofun
= SMBOPEN_OCREATE
;
1173 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OAPPEND
;
1175 case FILE_OVERWRITE
:
1176 ofun
= SMBOPEN_OTRUNC
;
1178 case FILE_OVERWRITE_IF
:
1179 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1182 cFYI(1, "unknown disposition %d", disposition
);
1183 ofun
= SMBOPEN_OAPPEND
; /* regular open */
1189 access_flags_to_smbopen_mode(const int access_flags
)
1191 int masked_flags
= access_flags
& (GENERIC_READ
| GENERIC_WRITE
);
1193 if (masked_flags
== GENERIC_READ
)
1194 return SMBOPEN_READ
;
1195 else if (masked_flags
== GENERIC_WRITE
)
1196 return SMBOPEN_WRITE
;
1198 /* just go for read/write */
1199 return SMBOPEN_READWRITE
;
1203 SMBLegacyOpen(const int xid
, struct cifs_tcon
*tcon
,
1204 const char *fileName
, const int openDisposition
,
1205 const int access_flags
, const int create_options
, __u16
*netfid
,
1206 int *pOplock
, FILE_ALL_INFO
*pfile_info
,
1207 const struct nls_table
*nls_codepage
, int remap
)
1210 OPENX_REQ
*pSMB
= NULL
;
1211 OPENX_RSP
*pSMBr
= NULL
;
1217 rc
= smb_init(SMB_COM_OPEN_ANDX
, 15, tcon
, (void **) &pSMB
,
1222 pSMB
->AndXCommand
= 0xFF; /* none */
1224 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1225 count
= 1; /* account for one byte pad to word boundary */
1227 cifsConvertToUTF16((__le16
*) (pSMB
->fileName
+ 1),
1228 fileName
, PATH_MAX
, nls_codepage
, remap
);
1229 name_len
++; /* trailing null */
1231 } else { /* BB improve check for buffer overruns BB */
1232 count
= 0; /* no pad */
1233 name_len
= strnlen(fileName
, PATH_MAX
);
1234 name_len
++; /* trailing null */
1235 strncpy(pSMB
->fileName
, fileName
, name_len
);
1237 if (*pOplock
& REQ_OPLOCK
)
1238 pSMB
->OpenFlags
= cpu_to_le16(REQ_OPLOCK
);
1239 else if (*pOplock
& REQ_BATCHOPLOCK
)
1240 pSMB
->OpenFlags
= cpu_to_le16(REQ_BATCHOPLOCK
);
1242 pSMB
->OpenFlags
|= cpu_to_le16(REQ_MORE_INFO
);
1243 pSMB
->Mode
= cpu_to_le16(access_flags_to_smbopen_mode(access_flags
));
1244 pSMB
->Mode
|= cpu_to_le16(0x40); /* deny none */
1245 /* set file as system file if special file such
1246 as fifo and server expecting SFU style and
1247 no Unix extensions */
1249 if (create_options
& CREATE_OPTION_SPECIAL
)
1250 pSMB
->FileAttributes
= cpu_to_le16(ATTR_SYSTEM
);
1251 else /* BB FIXME BB */
1252 pSMB
->FileAttributes
= cpu_to_le16(0/*ATTR_NORMAL*/);
1254 if (create_options
& CREATE_OPTION_READONLY
)
1255 pSMB
->FileAttributes
|= cpu_to_le16(ATTR_READONLY
);
1258 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1259 CREATE_OPTIONS_MASK); */
1260 /* BB FIXME END BB */
1262 pSMB
->Sattr
= cpu_to_le16(ATTR_HIDDEN
| ATTR_SYSTEM
| ATTR_DIRECTORY
);
1263 pSMB
->OpenFunction
= cpu_to_le16(convert_disposition(openDisposition
));
1265 inc_rfc1001_len(pSMB
, count
);
1267 pSMB
->ByteCount
= cpu_to_le16(count
);
1268 /* long_op set to 1 to allow for oplock break timeouts */
1269 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1270 (struct smb_hdr
*)pSMBr
, &bytes_returned
, 0);
1271 cifs_stats_inc(&tcon
->num_opens
);
1273 cFYI(1, "Error in Open = %d", rc
);
1275 /* BB verify if wct == 15 */
1277 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1279 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
1280 /* Let caller know file was created so we can set the mode. */
1281 /* Do we care about the CreateAction in any other cases? */
1283 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1284 *pOplock |= CIFS_CREATE_ACTION; */
1288 pfile_info
->CreationTime
= 0; /* BB convert CreateTime*/
1289 pfile_info
->LastAccessTime
= 0; /* BB fixme */
1290 pfile_info
->LastWriteTime
= 0; /* BB fixme */
1291 pfile_info
->ChangeTime
= 0; /* BB fixme */
1292 pfile_info
->Attributes
=
1293 cpu_to_le32(le16_to_cpu(pSMBr
->FileAttributes
));
1294 /* the file_info buf is endian converted by caller */
1295 pfile_info
->AllocationSize
=
1296 cpu_to_le64(le32_to_cpu(pSMBr
->EndOfFile
));
1297 pfile_info
->EndOfFile
= pfile_info
->AllocationSize
;
1298 pfile_info
->NumberOfLinks
= cpu_to_le32(1);
1299 pfile_info
->DeletePending
= 0;
1303 cifs_buf_release(pSMB
);
1310 CIFSSMBOpen(const int xid
, struct cifs_tcon
*tcon
,
1311 const char *fileName
, const int openDisposition
,
1312 const int access_flags
, const int create_options
, __u16
*netfid
,
1313 int *pOplock
, FILE_ALL_INFO
*pfile_info
,
1314 const struct nls_table
*nls_codepage
, int remap
)
1317 OPEN_REQ
*pSMB
= NULL
;
1318 OPEN_RSP
*pSMBr
= NULL
;
1324 rc
= smb_init(SMB_COM_NT_CREATE_ANDX
, 24, tcon
, (void **) &pSMB
,
1329 pSMB
->AndXCommand
= 0xFF; /* none */
1331 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1332 count
= 1; /* account for one byte pad to word boundary */
1334 cifsConvertToUTF16((__le16
*) (pSMB
->fileName
+ 1),
1335 fileName
, PATH_MAX
, nls_codepage
, remap
);
1336 name_len
++; /* trailing null */
1338 pSMB
->NameLength
= cpu_to_le16(name_len
);
1339 } else { /* BB improve check for buffer overruns BB */
1340 count
= 0; /* no pad */
1341 name_len
= strnlen(fileName
, PATH_MAX
);
1342 name_len
++; /* trailing null */
1343 pSMB
->NameLength
= cpu_to_le16(name_len
);
1344 strncpy(pSMB
->fileName
, fileName
, name_len
);
1346 if (*pOplock
& REQ_OPLOCK
)
1347 pSMB
->OpenFlags
= cpu_to_le32(REQ_OPLOCK
);
1348 else if (*pOplock
& REQ_BATCHOPLOCK
)
1349 pSMB
->OpenFlags
= cpu_to_le32(REQ_BATCHOPLOCK
);
1350 pSMB
->DesiredAccess
= cpu_to_le32(access_flags
);
1351 pSMB
->AllocationSize
= 0;
1352 /* set file as system file if special file such
1353 as fifo and server expecting SFU style and
1354 no Unix extensions */
1355 if (create_options
& CREATE_OPTION_SPECIAL
)
1356 pSMB
->FileAttributes
= cpu_to_le32(ATTR_SYSTEM
);
1358 pSMB
->FileAttributes
= cpu_to_le32(ATTR_NORMAL
);
1360 /* XP does not handle ATTR_POSIX_SEMANTICS */
1361 /* but it helps speed up case sensitive checks for other
1362 servers such as Samba */
1363 if (tcon
->ses
->capabilities
& CAP_UNIX
)
1364 pSMB
->FileAttributes
|= cpu_to_le32(ATTR_POSIX_SEMANTICS
);
1366 if (create_options
& CREATE_OPTION_READONLY
)
1367 pSMB
->FileAttributes
|= cpu_to_le32(ATTR_READONLY
);
1369 pSMB
->ShareAccess
= cpu_to_le32(FILE_SHARE_ALL
);
1370 pSMB
->CreateDisposition
= cpu_to_le32(openDisposition
);
1371 pSMB
->CreateOptions
= cpu_to_le32(create_options
& CREATE_OPTIONS_MASK
);
1372 /* BB Expirement with various impersonation levels and verify */
1373 pSMB
->ImpersonationLevel
= cpu_to_le32(SECURITY_IMPERSONATION
);
1374 pSMB
->SecurityFlags
=
1375 SECURITY_CONTEXT_TRACKING
| SECURITY_EFFECTIVE_ONLY
;
1378 inc_rfc1001_len(pSMB
, count
);
1380 pSMB
->ByteCount
= cpu_to_le16(count
);
1381 /* long_op set to 1 to allow for oplock break timeouts */
1382 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1383 (struct smb_hdr
*)pSMBr
, &bytes_returned
, 0);
1384 cifs_stats_inc(&tcon
->num_opens
);
1386 cFYI(1, "Error in Open = %d", rc
);
1388 *pOplock
= pSMBr
->OplockLevel
; /* 1 byte no need to le_to_cpu */
1389 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
1390 /* Let caller know file was created so we can set the mode. */
1391 /* Do we care about the CreateAction in any other cases? */
1392 if (cpu_to_le32(FILE_CREATE
) == pSMBr
->CreateAction
)
1393 *pOplock
|= CIFS_CREATE_ACTION
;
1395 memcpy((char *)pfile_info
, (char *)&pSMBr
->CreationTime
,
1396 36 /* CreationTime to Attributes */);
1397 /* the file_info buf is endian converted by caller */
1398 pfile_info
->AllocationSize
= pSMBr
->AllocationSize
;
1399 pfile_info
->EndOfFile
= pSMBr
->EndOfFile
;
1400 pfile_info
->NumberOfLinks
= cpu_to_le32(1);
1401 pfile_info
->DeletePending
= 0;
1405 cifs_buf_release(pSMB
);
1412 * Discard any remaining data in the current SMB. To do this, we borrow the
1416 cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1418 unsigned int rfclen
= get_rfc1002_length(server
->smallbuf
);
1419 int remaining
= rfclen
+ 4 - server
->total_read
;
1420 struct cifs_readdata
*rdata
= mid
->callback_data
;
1422 while (remaining
> 0) {
1425 length
= cifs_read_from_socket(server
, server
->bigbuf
,
1426 min_t(unsigned int, remaining
,
1427 CIFSMaxBufSize
+ MAX_HEADER_SIZE(server
)));
1430 server
->total_read
+= length
;
1431 remaining
-= length
;
1434 dequeue_mid(mid
, rdata
->result
);
1439 cifs_readv_receive(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1442 unsigned int data_offset
, data_len
;
1443 struct cifs_readdata
*rdata
= mid
->callback_data
;
1444 char *buf
= server
->smallbuf
;
1445 unsigned int buflen
= get_rfc1002_length(buf
) + 4;
1447 cFYI(1, "%s: mid=%llu offset=%llu bytes=%u", __func__
,
1448 mid
->mid
, rdata
->offset
, rdata
->bytes
);
1451 * read the rest of READ_RSP header (sans Data array), or whatever we
1452 * can if there's not enough data. At this point, we've read down to
1455 len
= min_t(unsigned int, buflen
, server
->vals
->read_rsp_size
) -
1456 HEADER_SIZE(server
) + 1;
1458 rdata
->iov
[0].iov_base
= buf
+ HEADER_SIZE(server
) - 1;
1459 rdata
->iov
[0].iov_len
= len
;
1461 length
= cifs_readv_from_socket(server
, rdata
->iov
, 1, len
);
1464 server
->total_read
+= length
;
1466 /* Was the SMB read successful? */
1467 rdata
->result
= server
->ops
->map_error(buf
, false);
1468 if (rdata
->result
!= 0) {
1469 cFYI(1, "%s: server returned error %d", __func__
,
1471 return cifs_readv_discard(server
, mid
);
1474 /* Is there enough to get to the rest of the READ_RSP header? */
1475 if (server
->total_read
< server
->vals
->read_rsp_size
) {
1476 cFYI(1, "%s: server returned short header. got=%u expected=%zu",
1477 __func__
, server
->total_read
,
1478 server
->vals
->read_rsp_size
);
1479 rdata
->result
= -EIO
;
1480 return cifs_readv_discard(server
, mid
);
1483 data_offset
= server
->ops
->read_data_offset(buf
) + 4;
1484 if (data_offset
< server
->total_read
) {
1486 * win2k8 sometimes sends an offset of 0 when the read
1487 * is beyond the EOF. Treat it as if the data starts just after
1490 cFYI(1, "%s: data offset (%u) inside read response header",
1491 __func__
, data_offset
);
1492 data_offset
= server
->total_read
;
1493 } else if (data_offset
> MAX_CIFS_SMALL_BUFFER_SIZE
) {
1494 /* data_offset is beyond the end of smallbuf */
1495 cFYI(1, "%s: data offset (%u) beyond end of smallbuf",
1496 __func__
, data_offset
);
1497 rdata
->result
= -EIO
;
1498 return cifs_readv_discard(server
, mid
);
1501 cFYI(1, "%s: total_read=%u data_offset=%u", __func__
,
1502 server
->total_read
, data_offset
);
1504 len
= data_offset
- server
->total_read
;
1506 /* read any junk before data into the rest of smallbuf */
1507 rdata
->iov
[0].iov_base
= buf
+ server
->total_read
;
1508 rdata
->iov
[0].iov_len
= len
;
1509 length
= cifs_readv_from_socket(server
, rdata
->iov
, 1, len
);
1512 server
->total_read
+= length
;
1515 /* set up first iov for signature check */
1516 rdata
->iov
[0].iov_base
= buf
;
1517 rdata
->iov
[0].iov_len
= server
->total_read
;
1518 cFYI(1, "0: iov_base=%p iov_len=%zu",
1519 rdata
->iov
[0].iov_base
, rdata
->iov
[0].iov_len
);
1521 /* how much data is in the response? */
1522 data_len
= server
->ops
->read_data_length(buf
);
1523 if (data_offset
+ data_len
> buflen
) {
1524 /* data_len is corrupt -- discard frame */
1525 rdata
->result
= -EIO
;
1526 return cifs_readv_discard(server
, mid
);
1529 /* marshal up the page array */
1531 len
= rdata
->marshal_iov(rdata
, data_len
);
1535 /* issue the read if we have any iovecs left to fill */
1536 if (rdata
->nr_iov
> 1) {
1537 length
= cifs_readv_from_socket(server
, &rdata
->iov
[1],
1538 rdata
->nr_iov
- 1, len
);
1541 server
->total_read
+= length
;
1546 rdata
->bytes
= length
;
1548 cFYI(1, "total_read=%u buflen=%u remaining=%u", server
->total_read
,
1551 /* discard anything left over */
1552 if (server
->total_read
< buflen
)
1553 return cifs_readv_discard(server
, mid
);
1555 dequeue_mid(mid
, false);
1560 cifs_readv_callback(struct mid_q_entry
*mid
)
1562 struct cifs_readdata
*rdata
= mid
->callback_data
;
1563 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1564 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
1566 cFYI(1, "%s: mid=%llu state=%d result=%d bytes=%u", __func__
,
1567 mid
->mid
, mid
->mid_state
, rdata
->result
, rdata
->bytes
);
1569 switch (mid
->mid_state
) {
1570 case MID_RESPONSE_RECEIVED
:
1571 /* result already set, check signature */
1572 if (server
->sec_mode
&
1573 (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
)) {
1574 if (cifs_verify_signature(rdata
->iov
, rdata
->nr_iov
,
1575 server
, mid
->sequence_number
+ 1))
1576 cERROR(1, "Unexpected SMB signature");
1578 /* FIXME: should this be counted toward the initiating task? */
1579 task_io_account_read(rdata
->bytes
);
1580 cifs_stats_bytes_read(tcon
, rdata
->bytes
);
1582 case MID_REQUEST_SUBMITTED
:
1583 case MID_RETRY_NEEDED
:
1584 rdata
->result
= -EAGAIN
;
1587 rdata
->result
= -EIO
;
1590 queue_work(cifsiod_wq
, &rdata
->work
);
1591 DeleteMidQEntry(mid
);
1592 add_credits(server
, 1, 0);
1595 /* cifs_async_readv - send an async write, and set up mid to handle result */
1597 cifs_async_readv(struct cifs_readdata
*rdata
)
1600 READ_REQ
*smb
= NULL
;
1602 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1604 cFYI(1, "%s: offset=%llu bytes=%u", __func__
,
1605 rdata
->offset
, rdata
->bytes
);
1607 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1610 wct
= 10; /* old style read */
1611 if ((rdata
->offset
>> 32) > 0) {
1612 /* can not handle this big offset for old */
1617 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **)&smb
);
1621 smb
->hdr
.Pid
= cpu_to_le16((__u16
)rdata
->pid
);
1622 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(rdata
->pid
>> 16));
1624 smb
->AndXCommand
= 0xFF; /* none */
1625 smb
->Fid
= rdata
->cfile
->netfid
;
1626 smb
->OffsetLow
= cpu_to_le32(rdata
->offset
& 0xFFFFFFFF);
1628 smb
->OffsetHigh
= cpu_to_le32(rdata
->offset
>> 32);
1630 smb
->MaxCount
= cpu_to_le16(rdata
->bytes
& 0xFFFF);
1631 smb
->MaxCountHigh
= cpu_to_le32(rdata
->bytes
>> 16);
1635 /* old style read */
1636 struct smb_com_readx_req
*smbr
=
1637 (struct smb_com_readx_req
*)smb
;
1638 smbr
->ByteCount
= 0;
1641 /* 4 for RFC1001 length + 1 for BCC */
1642 rdata
->iov
[0].iov_base
= smb
;
1643 rdata
->iov
[0].iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4;
1645 kref_get(&rdata
->refcount
);
1646 rc
= cifs_call_async(tcon
->ses
->server
, rdata
->iov
, 1,
1647 cifs_readv_receive
, cifs_readv_callback
,
1651 cifs_stats_inc(&tcon
->num_reads
);
1653 kref_put(&rdata
->refcount
, cifs_readdata_release
);
1655 cifs_small_buf_release(smb
);
1660 CIFSSMBRead(const int xid
, struct cifs_io_parms
*io_parms
, unsigned int *nbytes
,
1661 char **buf
, int *pbuf_type
)
1664 READ_REQ
*pSMB
= NULL
;
1665 READ_RSP
*pSMBr
= NULL
;
1666 char *pReadData
= NULL
;
1668 int resp_buf_type
= 0;
1670 __u32 pid
= io_parms
->pid
;
1671 __u16 netfid
= io_parms
->netfid
;
1672 __u64 offset
= io_parms
->offset
;
1673 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1674 unsigned int count
= io_parms
->length
;
1676 cFYI(1, "Reading %d bytes on fid %d", count
, netfid
);
1677 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1680 wct
= 10; /* old style read */
1681 if ((offset
>> 32) > 0) {
1682 /* can not handle this big offset for old */
1688 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **) &pSMB
);
1692 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1693 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1695 /* tcon and ses pointer are checked in smb_init */
1696 if (tcon
->ses
->server
== NULL
)
1697 return -ECONNABORTED
;
1699 pSMB
->AndXCommand
= 0xFF; /* none */
1701 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1703 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1705 pSMB
->Remaining
= 0;
1706 pSMB
->MaxCount
= cpu_to_le16(count
& 0xFFFF);
1707 pSMB
->MaxCountHigh
= cpu_to_le32(count
>> 16);
1709 pSMB
->ByteCount
= 0; /* no need to do le conversion since 0 */
1711 /* old style read */
1712 struct smb_com_readx_req
*pSMBW
=
1713 (struct smb_com_readx_req
*)pSMB
;
1714 pSMBW
->ByteCount
= 0;
1717 iov
[0].iov_base
= (char *)pSMB
;
1718 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
1719 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
1720 &resp_buf_type
, CIFS_LOG_ERROR
);
1721 cifs_stats_inc(&tcon
->num_reads
);
1722 pSMBr
= (READ_RSP
*)iov
[0].iov_base
;
1724 cERROR(1, "Send error in read = %d", rc
);
1726 int data_length
= le16_to_cpu(pSMBr
->DataLengthHigh
);
1727 data_length
= data_length
<< 16;
1728 data_length
+= le16_to_cpu(pSMBr
->DataLength
);
1729 *nbytes
= data_length
;
1731 /*check that DataLength would not go beyond end of SMB */
1732 if ((data_length
> CIFSMaxBufSize
)
1733 || (data_length
> count
)) {
1734 cFYI(1, "bad length %d for count %d",
1735 data_length
, count
);
1739 pReadData
= (char *) (&pSMBr
->hdr
.Protocol
) +
1740 le16_to_cpu(pSMBr
->DataOffset
);
1741 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1742 cERROR(1, "Faulting on read rc = %d",rc);
1744 }*/ /* can not use copy_to_user when using page cache*/
1746 memcpy(*buf
, pReadData
, data_length
);
1750 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1752 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1753 cifs_small_buf_release(iov
[0].iov_base
);
1754 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1755 cifs_buf_release(iov
[0].iov_base
);
1756 } else if (resp_buf_type
!= CIFS_NO_BUFFER
) {
1757 /* return buffer to caller to free */
1758 *buf
= iov
[0].iov_base
;
1759 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1760 *pbuf_type
= CIFS_SMALL_BUFFER
;
1761 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1762 *pbuf_type
= CIFS_LARGE_BUFFER
;
1763 } /* else no valid buffer on return - leave as null */
1765 /* Note: On -EAGAIN error only caller can retry on handle based calls
1766 since file handle passed in no longer valid */
1772 CIFSSMBWrite(const int xid
, struct cifs_io_parms
*io_parms
,
1773 unsigned int *nbytes
, const char *buf
,
1774 const char __user
*ubuf
, const int long_op
)
1777 WRITE_REQ
*pSMB
= NULL
;
1778 WRITE_RSP
*pSMBr
= NULL
;
1779 int bytes_returned
, wct
;
1782 __u32 pid
= io_parms
->pid
;
1783 __u16 netfid
= io_parms
->netfid
;
1784 __u64 offset
= io_parms
->offset
;
1785 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1786 unsigned int count
= io_parms
->length
;
1790 /* cFYI(1, "write at %lld %d bytes", offset, count);*/
1791 if (tcon
->ses
== NULL
)
1792 return -ECONNABORTED
;
1794 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1798 if ((offset
>> 32) > 0) {
1799 /* can not handle big offset for old srv */
1804 rc
= smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
,
1809 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1810 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1812 /* tcon and ses pointer are checked in smb_init */
1813 if (tcon
->ses
->server
== NULL
)
1814 return -ECONNABORTED
;
1816 pSMB
->AndXCommand
= 0xFF; /* none */
1818 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1820 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1822 pSMB
->Reserved
= 0xFFFFFFFF;
1823 pSMB
->WriteMode
= 0;
1824 pSMB
->Remaining
= 0;
1826 /* Can increase buffer size if buffer is big enough in some cases ie we
1827 can send more if LARGE_WRITE_X capability returned by the server and if
1828 our buffer is big enough or if we convert to iovecs on socket writes
1829 and eliminate the copy to the CIFS buffer */
1830 if (tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
) {
1831 bytes_sent
= min_t(const unsigned int, CIFSMaxBufSize
, count
);
1833 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
)
1837 if (bytes_sent
> count
)
1840 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1842 memcpy(pSMB
->Data
, buf
, bytes_sent
);
1844 if (copy_from_user(pSMB
->Data
, ubuf
, bytes_sent
)) {
1845 cifs_buf_release(pSMB
);
1848 } else if (count
!= 0) {
1850 cifs_buf_release(pSMB
);
1852 } /* else setting file size with write of zero bytes */
1854 byte_count
= bytes_sent
+ 1; /* pad */
1855 else /* wct == 12 */
1856 byte_count
= bytes_sent
+ 5; /* bigger pad, smaller smb hdr */
1858 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
& 0xFFFF);
1859 pSMB
->DataLengthHigh
= cpu_to_le16(bytes_sent
>> 16);
1860 inc_rfc1001_len(pSMB
, byte_count
);
1863 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1864 else { /* old style write has byte count 4 bytes earlier
1866 struct smb_com_writex_req
*pSMBW
=
1867 (struct smb_com_writex_req
*)pSMB
;
1868 pSMBW
->ByteCount
= cpu_to_le16(byte_count
);
1871 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1872 (struct smb_hdr
*) pSMBr
, &bytes_returned
, long_op
);
1873 cifs_stats_inc(&tcon
->num_writes
);
1875 cFYI(1, "Send error in write = %d", rc
);
1877 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
1878 *nbytes
= (*nbytes
) << 16;
1879 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
1882 * Mask off high 16 bits when bytes written as returned by the
1883 * server is greater than bytes requested by the client. Some
1884 * OS/2 servers are known to set incorrect CountHigh values.
1886 if (*nbytes
> count
)
1890 cifs_buf_release(pSMB
);
1892 /* Note: On -EAGAIN error only caller can retry on handle based calls
1893 since file handle passed in no longer valid */
1899 cifs_writedata_release(struct kref
*refcount
)
1901 struct cifs_writedata
*wdata
= container_of(refcount
,
1902 struct cifs_writedata
, refcount
);
1905 cifsFileInfo_put(wdata
->cfile
);
1911 * Write failed with a retryable error. Resend the write request. It's also
1912 * possible that the page was redirtied so re-clean the page.
1915 cifs_writev_requeue(struct cifs_writedata
*wdata
)
1918 struct inode
*inode
= wdata
->cfile
->dentry
->d_inode
;
1920 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
1921 lock_page(wdata
->pages
[i
]);
1922 clear_page_dirty_for_io(wdata
->pages
[i
]);
1926 rc
= cifs_async_writev(wdata
);
1927 } while (rc
== -EAGAIN
);
1929 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
1931 SetPageError(wdata
->pages
[i
]);
1932 unlock_page(wdata
->pages
[i
]);
1935 mapping_set_error(inode
->i_mapping
, rc
);
1936 kref_put(&wdata
->refcount
, cifs_writedata_release
);
1940 cifs_writev_complete(struct work_struct
*work
)
1942 struct cifs_writedata
*wdata
= container_of(work
,
1943 struct cifs_writedata
, work
);
1944 struct inode
*inode
= wdata
->cfile
->dentry
->d_inode
;
1947 if (wdata
->result
== 0) {
1948 spin_lock(&inode
->i_lock
);
1949 cifs_update_eof(CIFS_I(inode
), wdata
->offset
, wdata
->bytes
);
1950 spin_unlock(&inode
->i_lock
);
1951 cifs_stats_bytes_written(tlink_tcon(wdata
->cfile
->tlink
),
1953 } else if (wdata
->sync_mode
== WB_SYNC_ALL
&& wdata
->result
== -EAGAIN
)
1954 return cifs_writev_requeue(wdata
);
1956 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
1957 struct page
*page
= wdata
->pages
[i
];
1958 if (wdata
->result
== -EAGAIN
)
1959 __set_page_dirty_nobuffers(page
);
1960 else if (wdata
->result
< 0)
1962 end_page_writeback(page
);
1963 page_cache_release(page
);
1965 if (wdata
->result
!= -EAGAIN
)
1966 mapping_set_error(inode
->i_mapping
, wdata
->result
);
1967 kref_put(&wdata
->refcount
, cifs_writedata_release
);
1970 struct cifs_writedata
*
1971 cifs_writedata_alloc(unsigned int nr_pages
, work_func_t complete
)
1973 struct cifs_writedata
*wdata
;
1975 /* this would overflow */
1976 if (nr_pages
== 0) {
1977 cERROR(1, "%s: called with nr_pages == 0!", __func__
);
1981 /* writedata + number of page pointers */
1982 wdata
= kzalloc(sizeof(*wdata
) +
1983 sizeof(struct page
*) * (nr_pages
- 1), GFP_NOFS
);
1984 if (wdata
!= NULL
) {
1985 kref_init(&wdata
->refcount
);
1986 INIT_LIST_HEAD(&wdata
->list
);
1987 init_completion(&wdata
->done
);
1988 INIT_WORK(&wdata
->work
, complete
);
1994 * Check the mid_state and signature on received buffer (if any), and queue the
1995 * workqueue completion task.
1998 cifs_writev_callback(struct mid_q_entry
*mid
)
2000 struct cifs_writedata
*wdata
= mid
->callback_data
;
2001 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2002 unsigned int written
;
2003 WRITE_RSP
*smb
= (WRITE_RSP
*)mid
->resp_buf
;
2005 switch (mid
->mid_state
) {
2006 case MID_RESPONSE_RECEIVED
:
2007 wdata
->result
= cifs_check_receive(mid
, tcon
->ses
->server
, 0);
2008 if (wdata
->result
!= 0)
2011 written
= le16_to_cpu(smb
->CountHigh
);
2013 written
+= le16_to_cpu(smb
->Count
);
2015 * Mask off high 16 bits when bytes written as returned
2016 * by the server is greater than bytes requested by the
2017 * client. OS/2 servers are known to set incorrect
2020 if (written
> wdata
->bytes
)
2023 if (written
< wdata
->bytes
)
2024 wdata
->result
= -ENOSPC
;
2026 wdata
->bytes
= written
;
2028 case MID_REQUEST_SUBMITTED
:
2029 case MID_RETRY_NEEDED
:
2030 wdata
->result
= -EAGAIN
;
2033 wdata
->result
= -EIO
;
2037 queue_work(cifsiod_wq
, &wdata
->work
);
2038 DeleteMidQEntry(mid
);
2039 add_credits(tcon
->ses
->server
, 1, 0);
2042 /* cifs_async_writev - send an async write, and set up mid to handle result */
2044 cifs_async_writev(struct cifs_writedata
*wdata
)
2046 int i
, rc
= -EACCES
;
2047 WRITE_REQ
*smb
= NULL
;
2049 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2050 struct kvec
*iov
= NULL
;
2052 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2056 if (wdata
->offset
>> 32 > 0) {
2057 /* can not handle big offset for old srv */
2062 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **)&smb
);
2064 goto async_writev_out
;
2066 /* 1 iov per page + 1 for header */
2067 iov
= kzalloc((wdata
->nr_pages
+ 1) * sizeof(*iov
), GFP_NOFS
);
2070 goto async_writev_out
;
2073 smb
->hdr
.Pid
= cpu_to_le16((__u16
)wdata
->pid
);
2074 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(wdata
->pid
>> 16));
2076 smb
->AndXCommand
= 0xFF; /* none */
2077 smb
->Fid
= wdata
->cfile
->netfid
;
2078 smb
->OffsetLow
= cpu_to_le32(wdata
->offset
& 0xFFFFFFFF);
2080 smb
->OffsetHigh
= cpu_to_le32(wdata
->offset
>> 32);
2081 smb
->Reserved
= 0xFFFFFFFF;
2086 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2088 /* 4 for RFC1001 length + 1 for BCC */
2089 iov
[0].iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4 + 1;
2090 iov
[0].iov_base
= smb
;
2093 * This function should marshal up the page array into the kvec
2094 * array, reserving [0] for the header. It should kmap the pages
2095 * and set the iov_len properly for each one. It may also set
2099 wdata
->marshal_iov(iov
, wdata
);
2102 cFYI(1, "async write at %llu %u bytes", wdata
->offset
, wdata
->bytes
);
2104 smb
->DataLengthLow
= cpu_to_le16(wdata
->bytes
& 0xFFFF);
2105 smb
->DataLengthHigh
= cpu_to_le16(wdata
->bytes
>> 16);
2108 inc_rfc1001_len(&smb
->hdr
, wdata
->bytes
+ 1);
2109 put_bcc(wdata
->bytes
+ 1, &smb
->hdr
);
2112 struct smb_com_writex_req
*smbw
=
2113 (struct smb_com_writex_req
*)smb
;
2114 inc_rfc1001_len(&smbw
->hdr
, wdata
->bytes
+ 5);
2115 put_bcc(wdata
->bytes
+ 5, &smbw
->hdr
);
2116 iov
[0].iov_len
+= 4; /* pad bigger by four bytes */
2119 kref_get(&wdata
->refcount
);
2120 rc
= cifs_call_async(tcon
->ses
->server
, iov
, wdata
->nr_pages
+ 1,
2121 NULL
, cifs_writev_callback
, wdata
, 0);
2124 cifs_stats_inc(&tcon
->num_writes
);
2126 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2128 /* send is done, unmap pages */
2129 for (i
= 0; i
< wdata
->nr_pages
; i
++)
2130 kunmap(wdata
->pages
[i
]);
2133 cifs_small_buf_release(smb
);
2139 CIFSSMBWrite2(const int xid
, struct cifs_io_parms
*io_parms
,
2140 unsigned int *nbytes
, struct kvec
*iov
, int n_vec
,
2144 WRITE_REQ
*pSMB
= NULL
;
2147 int resp_buf_type
= 0;
2148 __u32 pid
= io_parms
->pid
;
2149 __u16 netfid
= io_parms
->netfid
;
2150 __u64 offset
= io_parms
->offset
;
2151 struct cifs_tcon
*tcon
= io_parms
->tcon
;
2152 unsigned int count
= io_parms
->length
;
2156 cFYI(1, "write2 at %lld %d bytes", (long long)offset
, count
);
2158 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2162 if ((offset
>> 32) > 0) {
2163 /* can not handle big offset for old srv */
2167 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
);
2171 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
2172 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
2174 /* tcon and ses pointer are checked in smb_init */
2175 if (tcon
->ses
->server
== NULL
)
2176 return -ECONNABORTED
;
2178 pSMB
->AndXCommand
= 0xFF; /* none */
2180 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
2182 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
2183 pSMB
->Reserved
= 0xFFFFFFFF;
2184 pSMB
->WriteMode
= 0;
2185 pSMB
->Remaining
= 0;
2188 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2190 pSMB
->DataLengthLow
= cpu_to_le16(count
& 0xFFFF);
2191 pSMB
->DataLengthHigh
= cpu_to_le16(count
>> 16);
2192 /* header + 1 byte pad */
2193 smb_hdr_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 1;
2195 inc_rfc1001_len(pSMB
, count
+ 1);
2196 else /* wct == 12 */
2197 inc_rfc1001_len(pSMB
, count
+ 5); /* smb data starts later */
2199 pSMB
->ByteCount
= cpu_to_le16(count
+ 1);
2200 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2201 struct smb_com_writex_req
*pSMBW
=
2202 (struct smb_com_writex_req
*)pSMB
;
2203 pSMBW
->ByteCount
= cpu_to_le16(count
+ 5);
2205 iov
[0].iov_base
= pSMB
;
2207 iov
[0].iov_len
= smb_hdr_len
+ 4;
2208 else /* wct == 12 pad bigger by four bytes */
2209 iov
[0].iov_len
= smb_hdr_len
+ 8;
2212 rc
= SendReceive2(xid
, tcon
->ses
, iov
, n_vec
+ 1, &resp_buf_type
,
2214 cifs_stats_inc(&tcon
->num_writes
);
2216 cFYI(1, "Send error Write2 = %d", rc
);
2217 } else if (resp_buf_type
== 0) {
2218 /* presumably this can not happen, but best to be safe */
2221 WRITE_RSP
*pSMBr
= (WRITE_RSP
*)iov
[0].iov_base
;
2222 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2223 *nbytes
= (*nbytes
) << 16;
2224 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2227 * Mask off high 16 bits when bytes written as returned by the
2228 * server is greater than bytes requested by the client. OS/2
2229 * servers are known to set incorrect CountHigh values.
2231 if (*nbytes
> count
)
2235 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2236 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
2237 cifs_small_buf_release(iov
[0].iov_base
);
2238 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
2239 cifs_buf_release(iov
[0].iov_base
);
2241 /* Note: On -EAGAIN error only caller can retry on handle based calls
2242 since file handle passed in no longer valid */
2247 int cifs_lockv(const int xid
, struct cifs_tcon
*tcon
, const __u16 netfid
,
2248 const __u8 lock_type
, const __u32 num_unlock
,
2249 const __u32 num_lock
, LOCKING_ANDX_RANGE
*buf
)
2252 LOCK_REQ
*pSMB
= NULL
;
2257 cFYI(1, "cifs_lockv num lock %d num unlock %d", num_lock
, num_unlock
);
2259 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2264 pSMB
->NumberOfLocks
= cpu_to_le16(num_lock
);
2265 pSMB
->NumberOfUnlocks
= cpu_to_le16(num_unlock
);
2266 pSMB
->LockType
= lock_type
;
2267 pSMB
->AndXCommand
= 0xFF; /* none */
2268 pSMB
->Fid
= netfid
; /* netfid stays le */
2270 count
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2271 inc_rfc1001_len(pSMB
, count
);
2272 pSMB
->ByteCount
= cpu_to_le16(count
);
2274 iov
[0].iov_base
= (char *)pSMB
;
2275 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4 -
2276 (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2277 iov
[1].iov_base
= (char *)buf
;
2278 iov
[1].iov_len
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2280 cifs_stats_inc(&tcon
->num_locks
);
2281 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 2, &resp_buf_type
, CIFS_NO_RESP
);
2283 cFYI(1, "Send error in cifs_lockv = %d", rc
);
2289 CIFSSMBLock(const int xid
, struct cifs_tcon
*tcon
,
2290 const __u16 smb_file_id
, const __u32 netpid
, const __u64 len
,
2291 const __u64 offset
, const __u32 numUnlock
,
2292 const __u32 numLock
, const __u8 lockType
,
2293 const bool waitFlag
, const __u8 oplock_level
)
2296 LOCK_REQ
*pSMB
= NULL
;
2297 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2302 cFYI(1, "CIFSSMBLock timeout %d numLock %d", (int)waitFlag
, numLock
);
2303 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2308 if (lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
2309 /* no response expected */
2310 flags
= CIFS_ASYNC_OP
| CIFS_OBREAK_OP
;
2312 } else if (waitFlag
) {
2313 flags
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2314 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
2319 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
2320 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
2321 pSMB
->LockType
= lockType
;
2322 pSMB
->OplockLevel
= oplock_level
;
2323 pSMB
->AndXCommand
= 0xFF; /* none */
2324 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
2326 if ((numLock
!= 0) || (numUnlock
!= 0)) {
2327 pSMB
->Locks
[0].Pid
= cpu_to_le16(netpid
);
2328 /* BB where to store pid high? */
2329 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
2330 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
2331 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
2332 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
2333 count
= sizeof(LOCKING_ANDX_RANGE
);
2338 inc_rfc1001_len(pSMB
, count
);
2339 pSMB
->ByteCount
= cpu_to_le16(count
);
2342 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2343 (struct smb_hdr
*) pSMB
, &bytes_returned
);
2344 cifs_small_buf_release(pSMB
);
2346 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)pSMB
, flags
);
2347 /* SMB buffer freed by function above */
2349 cifs_stats_inc(&tcon
->num_locks
);
2351 cFYI(1, "Send error in Lock = %d", rc
);
2353 /* Note: On -EAGAIN error only caller can retry on handle based calls
2354 since file handle passed in no longer valid */
2359 CIFSSMBPosixLock(const int xid
, struct cifs_tcon
*tcon
,
2360 const __u16 smb_file_id
, const __u32 netpid
,
2361 const loff_t start_offset
, const __u64 len
,
2362 struct file_lock
*pLockData
, const __u16 lock_type
,
2363 const bool waitFlag
)
2365 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2366 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2367 struct cifs_posix_lock
*parm_data
;
2370 int bytes_returned
= 0;
2371 int resp_buf_type
= 0;
2372 __u16 params
, param_offset
, offset
, byte_count
, count
;
2375 cFYI(1, "Posix Lock");
2377 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
2382 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)pSMB
;
2385 pSMB
->MaxSetupCount
= 0;
2388 pSMB
->Reserved2
= 0;
2389 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2390 offset
= param_offset
+ params
;
2392 count
= sizeof(struct cifs_posix_lock
);
2393 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2394 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2395 pSMB
->SetupCount
= 1;
2396 pSMB
->Reserved3
= 0;
2398 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
2400 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2401 byte_count
= 3 /* pad */ + params
+ count
;
2402 pSMB
->DataCount
= cpu_to_le16(count
);
2403 pSMB
->ParameterCount
= cpu_to_le16(params
);
2404 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2405 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2406 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2407 parm_data
= (struct cifs_posix_lock
*)
2408 (((char *) &pSMB
->hdr
.Protocol
) + offset
);
2410 parm_data
->lock_type
= cpu_to_le16(lock_type
);
2412 timeout
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2413 parm_data
->lock_flags
= cpu_to_le16(1);
2414 pSMB
->Timeout
= cpu_to_le32(-1);
2418 parm_data
->pid
= cpu_to_le32(netpid
);
2419 parm_data
->start
= cpu_to_le64(start_offset
);
2420 parm_data
->length
= cpu_to_le64(len
); /* normalize negative numbers */
2422 pSMB
->DataOffset
= cpu_to_le16(offset
);
2423 pSMB
->Fid
= smb_file_id
;
2424 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_LOCK
);
2425 pSMB
->Reserved4
= 0;
2426 inc_rfc1001_len(pSMB
, byte_count
);
2427 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2429 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2430 (struct smb_hdr
*) pSMBr
, &bytes_returned
);
2432 iov
[0].iov_base
= (char *)pSMB
;
2433 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
2434 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
2435 &resp_buf_type
, timeout
);
2436 pSMB
= NULL
; /* request buf already freed by SendReceive2. Do
2437 not try to free it twice below on exit */
2438 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)iov
[0].iov_base
;
2442 cFYI(1, "Send error in Posix Lock = %d", rc
);
2443 } else if (pLockData
) {
2444 /* lock structure can be returned on get */
2447 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2449 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(*parm_data
)) {
2450 rc
= -EIO
; /* bad smb */
2453 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
2454 data_count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2455 if (data_count
< sizeof(struct cifs_posix_lock
)) {
2459 parm_data
= (struct cifs_posix_lock
*)
2460 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2461 if (parm_data
->lock_type
== __constant_cpu_to_le16(CIFS_UNLCK
))
2462 pLockData
->fl_type
= F_UNLCK
;
2464 if (parm_data
->lock_type
==
2465 __constant_cpu_to_le16(CIFS_RDLCK
))
2466 pLockData
->fl_type
= F_RDLCK
;
2467 else if (parm_data
->lock_type
==
2468 __constant_cpu_to_le16(CIFS_WRLCK
))
2469 pLockData
->fl_type
= F_WRLCK
;
2471 pLockData
->fl_start
= le64_to_cpu(parm_data
->start
);
2472 pLockData
->fl_end
= pLockData
->fl_start
+
2473 le64_to_cpu(parm_data
->length
) - 1;
2474 pLockData
->fl_pid
= le32_to_cpu(parm_data
->pid
);
2480 cifs_small_buf_release(pSMB
);
2482 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
2483 cifs_small_buf_release(iov
[0].iov_base
);
2484 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
2485 cifs_buf_release(iov
[0].iov_base
);
2487 /* Note: On -EAGAIN error only caller can retry on handle based calls
2488 since file handle passed in no longer valid */
2495 CIFSSMBClose(const int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2498 CLOSE_REQ
*pSMB
= NULL
;
2499 cFYI(1, "In CIFSSMBClose");
2501 /* do not retry on dead session on close */
2502 rc
= small_smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
);
2508 pSMB
->FileID
= (__u16
) smb_file_id
;
2509 pSMB
->LastWriteTime
= 0xFFFFFFFF;
2510 pSMB
->ByteCount
= 0;
2511 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2512 cifs_stats_inc(&tcon
->num_closes
);
2515 /* EINTR is expected when user ctl-c to kill app */
2516 cERROR(1, "Send error in Close = %d", rc
);
2520 /* Since session is dead, file will be closed on server already */
2528 CIFSSMBFlush(const int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2531 FLUSH_REQ
*pSMB
= NULL
;
2532 cFYI(1, "In CIFSSMBFlush");
2534 rc
= small_smb_init(SMB_COM_FLUSH
, 1, tcon
, (void **) &pSMB
);
2538 pSMB
->FileID
= (__u16
) smb_file_id
;
2539 pSMB
->ByteCount
= 0;
2540 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2541 cifs_stats_inc(&tcon
->num_flushes
);
2543 cERROR(1, "Send error in Flush = %d", rc
);
2549 CIFSSMBRename(const int xid
, struct cifs_tcon
*tcon
,
2550 const char *fromName
, const char *toName
,
2551 const struct nls_table
*nls_codepage
, int remap
)
2554 RENAME_REQ
*pSMB
= NULL
;
2555 RENAME_RSP
*pSMBr
= NULL
;
2557 int name_len
, name_len2
;
2560 cFYI(1, "In CIFSSMBRename");
2562 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
2567 pSMB
->BufferFormat
= 0x04;
2568 pSMB
->SearchAttributes
=
2569 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2572 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2574 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, fromName
,
2575 PATH_MAX
, nls_codepage
, remap
);
2576 name_len
++; /* trailing null */
2578 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2579 /* protocol requires ASCII signature byte on Unicode string */
2580 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2582 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2583 toName
, PATH_MAX
, nls_codepage
, remap
);
2584 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2585 name_len2
*= 2; /* convert to bytes */
2586 } else { /* BB improve the check for buffer overruns BB */
2587 name_len
= strnlen(fromName
, PATH_MAX
);
2588 name_len
++; /* trailing null */
2589 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
2590 name_len2
= strnlen(toName
, PATH_MAX
);
2591 name_len2
++; /* trailing null */
2592 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2593 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
2594 name_len2
++; /* trailing null */
2595 name_len2
++; /* signature byte */
2598 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2599 inc_rfc1001_len(pSMB
, count
);
2600 pSMB
->ByteCount
= cpu_to_le16(count
);
2602 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2603 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2604 cifs_stats_inc(&tcon
->num_renames
);
2606 cFYI(1, "Send error in rename = %d", rc
);
2608 cifs_buf_release(pSMB
);
2616 int CIFSSMBRenameOpenFile(const int xid
, struct cifs_tcon
*pTcon
,
2617 int netfid
, const char *target_name
,
2618 const struct nls_table
*nls_codepage
, int remap
)
2620 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2621 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2622 struct set_file_rename
*rename_info
;
2624 char dummy_string
[30];
2626 int bytes_returned
= 0;
2628 __u16 params
, param_offset
, offset
, count
, byte_count
;
2630 cFYI(1, "Rename to File by handle");
2631 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
2637 pSMB
->MaxSetupCount
= 0;
2641 pSMB
->Reserved2
= 0;
2642 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2643 offset
= param_offset
+ params
;
2645 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2646 rename_info
= (struct set_file_rename
*) data_offset
;
2647 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2648 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2649 pSMB
->SetupCount
= 1;
2650 pSMB
->Reserved3
= 0;
2651 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2652 byte_count
= 3 /* pad */ + params
;
2653 pSMB
->ParameterCount
= cpu_to_le16(params
);
2654 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2655 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2656 pSMB
->DataOffset
= cpu_to_le16(offset
);
2657 /* construct random name ".cifs_tmp<inodenum><mid>" */
2658 rename_info
->overwrite
= cpu_to_le32(1);
2659 rename_info
->root_fid
= 0;
2660 /* unicode only call */
2661 if (target_name
== NULL
) {
2662 sprintf(dummy_string
, "cifs%x", pSMB
->hdr
.Mid
);
2664 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2665 dummy_string
, 24, nls_codepage
, remap
);
2668 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2669 target_name
, PATH_MAX
, nls_codepage
,
2672 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
2673 count
= 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str
);
2674 byte_count
+= count
;
2675 pSMB
->DataCount
= cpu_to_le16(count
);
2676 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2678 pSMB
->InformationLevel
=
2679 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
2680 pSMB
->Reserved4
= 0;
2681 inc_rfc1001_len(pSMB
, byte_count
);
2682 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2683 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
2684 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2685 cifs_stats_inc(&pTcon
->num_t2renames
);
2687 cFYI(1, "Send error in Rename (by file handle) = %d", rc
);
2689 cifs_buf_release(pSMB
);
2691 /* Note: On -EAGAIN error only caller can retry on handle based calls
2692 since file handle passed in no longer valid */
2698 CIFSSMBCopy(const int xid
, struct cifs_tcon
*tcon
, const char *fromName
,
2699 const __u16 target_tid
, const char *toName
, const int flags
,
2700 const struct nls_table
*nls_codepage
, int remap
)
2703 COPY_REQ
*pSMB
= NULL
;
2704 COPY_RSP
*pSMBr
= NULL
;
2706 int name_len
, name_len2
;
2709 cFYI(1, "In CIFSSMBCopy");
2711 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
2716 pSMB
->BufferFormat
= 0x04;
2717 pSMB
->Tid2
= target_tid
;
2719 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
2721 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2722 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2723 fromName
, PATH_MAX
, nls_codepage
,
2725 name_len
++; /* trailing null */
2727 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2728 /* protocol requires ASCII signature byte on Unicode string */
2729 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2731 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2732 toName
, PATH_MAX
, nls_codepage
, remap
);
2733 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2734 name_len2
*= 2; /* convert to bytes */
2735 } else { /* BB improve the check for buffer overruns BB */
2736 name_len
= strnlen(fromName
, PATH_MAX
);
2737 name_len
++; /* trailing null */
2738 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
2739 name_len2
= strnlen(toName
, PATH_MAX
);
2740 name_len2
++; /* trailing null */
2741 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2742 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
2743 name_len2
++; /* trailing null */
2744 name_len2
++; /* signature byte */
2747 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2748 inc_rfc1001_len(pSMB
, count
);
2749 pSMB
->ByteCount
= cpu_to_le16(count
);
2751 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2752 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2754 cFYI(1, "Send error in copy = %d with %d files copied",
2755 rc
, le16_to_cpu(pSMBr
->CopyCount
));
2757 cifs_buf_release(pSMB
);
2766 CIFSUnixCreateSymLink(const int xid
, struct cifs_tcon
*tcon
,
2767 const char *fromName
, const char *toName
,
2768 const struct nls_table
*nls_codepage
)
2770 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2771 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2774 int name_len_target
;
2776 int bytes_returned
= 0;
2777 __u16 params
, param_offset
, offset
, byte_count
;
2779 cFYI(1, "In Symlink Unix style");
2781 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2786 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2788 cifs_strtoUTF16((__le16
*) pSMB
->FileName
, fromName
,
2789 /* find define for this maxpathcomponent */
2790 PATH_MAX
, nls_codepage
);
2791 name_len
++; /* trailing null */
2794 } else { /* BB improve the check for buffer overruns BB */
2795 name_len
= strnlen(fromName
, PATH_MAX
);
2796 name_len
++; /* trailing null */
2797 strncpy(pSMB
->FileName
, fromName
, name_len
);
2799 params
= 6 + name_len
;
2800 pSMB
->MaxSetupCount
= 0;
2804 pSMB
->Reserved2
= 0;
2805 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2806 InformationLevel
) - 4;
2807 offset
= param_offset
+ params
;
2809 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2810 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2812 cifs_strtoUTF16((__le16
*) data_offset
, toName
, PATH_MAX
2813 /* find define for this maxpathcomponent */
2815 name_len_target
++; /* trailing null */
2816 name_len_target
*= 2;
2817 } else { /* BB improve the check for buffer overruns BB */
2818 name_len_target
= strnlen(toName
, PATH_MAX
);
2819 name_len_target
++; /* trailing null */
2820 strncpy(data_offset
, toName
, name_len_target
);
2823 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2824 /* BB find exact max on data count below from sess */
2825 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2826 pSMB
->SetupCount
= 1;
2827 pSMB
->Reserved3
= 0;
2828 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2829 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2830 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2831 pSMB
->ParameterCount
= cpu_to_le16(params
);
2832 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2833 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2834 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2835 pSMB
->DataOffset
= cpu_to_le16(offset
);
2836 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
2837 pSMB
->Reserved4
= 0;
2838 inc_rfc1001_len(pSMB
, byte_count
);
2839 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2840 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2841 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2842 cifs_stats_inc(&tcon
->num_symlinks
);
2844 cFYI(1, "Send error in SetPathInfo create symlink = %d", rc
);
2846 cifs_buf_release(pSMB
);
2849 goto createSymLinkRetry
;
2855 CIFSUnixCreateHardLink(const int xid
, struct cifs_tcon
*tcon
,
2856 const char *fromName
, const char *toName
,
2857 const struct nls_table
*nls_codepage
, int remap
)
2859 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2860 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2863 int name_len_target
;
2865 int bytes_returned
= 0;
2866 __u16 params
, param_offset
, offset
, byte_count
;
2868 cFYI(1, "In Create Hard link Unix style");
2869 createHardLinkRetry
:
2870 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2875 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2876 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->FileName
, toName
,
2877 PATH_MAX
, nls_codepage
, remap
);
2878 name_len
++; /* trailing null */
2881 } else { /* BB improve the check for buffer overruns BB */
2882 name_len
= strnlen(toName
, PATH_MAX
);
2883 name_len
++; /* trailing null */
2884 strncpy(pSMB
->FileName
, toName
, name_len
);
2886 params
= 6 + name_len
;
2887 pSMB
->MaxSetupCount
= 0;
2891 pSMB
->Reserved2
= 0;
2892 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2893 InformationLevel
) - 4;
2894 offset
= param_offset
+ params
;
2896 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2897 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2899 cifsConvertToUTF16((__le16
*) data_offset
, fromName
,
2900 PATH_MAX
, nls_codepage
, remap
);
2901 name_len_target
++; /* trailing null */
2902 name_len_target
*= 2;
2903 } else { /* BB improve the check for buffer overruns BB */
2904 name_len_target
= strnlen(fromName
, PATH_MAX
);
2905 name_len_target
++; /* trailing null */
2906 strncpy(data_offset
, fromName
, name_len_target
);
2909 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2910 /* BB find exact max on data count below from sess*/
2911 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2912 pSMB
->SetupCount
= 1;
2913 pSMB
->Reserved3
= 0;
2914 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2915 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2916 pSMB
->ParameterCount
= cpu_to_le16(params
);
2917 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2918 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2919 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2920 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2921 pSMB
->DataOffset
= cpu_to_le16(offset
);
2922 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
2923 pSMB
->Reserved4
= 0;
2924 inc_rfc1001_len(pSMB
, byte_count
);
2925 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2926 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2927 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2928 cifs_stats_inc(&tcon
->num_hardlinks
);
2930 cFYI(1, "Send error in SetPathInfo (hard link) = %d", rc
);
2932 cifs_buf_release(pSMB
);
2934 goto createHardLinkRetry
;
2940 CIFSCreateHardLink(const int xid
, struct cifs_tcon
*tcon
,
2941 const char *fromName
, const char *toName
,
2942 const struct nls_table
*nls_codepage
, int remap
)
2945 NT_RENAME_REQ
*pSMB
= NULL
;
2946 RENAME_RSP
*pSMBr
= NULL
;
2948 int name_len
, name_len2
;
2951 cFYI(1, "In CIFSCreateHardLink");
2952 winCreateHardLinkRetry
:
2954 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
2959 pSMB
->SearchAttributes
=
2960 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2962 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
2963 pSMB
->ClusterCount
= 0;
2965 pSMB
->BufferFormat
= 0x04;
2967 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2969 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, fromName
,
2970 PATH_MAX
, nls_codepage
, remap
);
2971 name_len
++; /* trailing null */
2974 /* protocol specifies ASCII buffer format (0x04) for unicode */
2975 pSMB
->OldFileName
[name_len
] = 0x04;
2976 pSMB
->OldFileName
[name_len
+ 1] = 0x00; /* pad */
2978 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2979 toName
, PATH_MAX
, nls_codepage
, remap
);
2980 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2981 name_len2
*= 2; /* convert to bytes */
2982 } else { /* BB improve the check for buffer overruns BB */
2983 name_len
= strnlen(fromName
, PATH_MAX
);
2984 name_len
++; /* trailing null */
2985 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
2986 name_len2
= strnlen(toName
, PATH_MAX
);
2987 name_len2
++; /* trailing null */
2988 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2989 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
2990 name_len2
++; /* trailing null */
2991 name_len2
++; /* signature byte */
2994 count
= 1 /* string type byte */ + name_len
+ name_len2
;
2995 inc_rfc1001_len(pSMB
, count
);
2996 pSMB
->ByteCount
= cpu_to_le16(count
);
2998 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2999 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3000 cifs_stats_inc(&tcon
->num_hardlinks
);
3002 cFYI(1, "Send error in hard link (NT rename) = %d", rc
);
3004 cifs_buf_release(pSMB
);
3006 goto winCreateHardLinkRetry
;
3012 CIFSSMBUnixQuerySymLink(const int xid
, struct cifs_tcon
*tcon
,
3013 const unsigned char *searchName
, char **symlinkinfo
,
3014 const struct nls_table
*nls_codepage
)
3016 /* SMB_QUERY_FILE_UNIX_LINK */
3017 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3018 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3022 __u16 params
, byte_count
;
3025 cFYI(1, "In QPathSymLinkInfo (Unix) for path %s", searchName
);
3028 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3033 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3035 cifs_strtoUTF16((__le16
*) pSMB
->FileName
, searchName
,
3036 PATH_MAX
, nls_codepage
);
3037 name_len
++; /* trailing null */
3039 } else { /* BB improve the check for buffer overruns BB */
3040 name_len
= strnlen(searchName
, PATH_MAX
);
3041 name_len
++; /* trailing null */
3042 strncpy(pSMB
->FileName
, searchName
, name_len
);
3045 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3046 pSMB
->TotalDataCount
= 0;
3047 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3048 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3049 pSMB
->MaxSetupCount
= 0;
3053 pSMB
->Reserved2
= 0;
3054 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3055 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3056 pSMB
->DataCount
= 0;
3057 pSMB
->DataOffset
= 0;
3058 pSMB
->SetupCount
= 1;
3059 pSMB
->Reserved3
= 0;
3060 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3061 byte_count
= params
+ 1 /* pad */ ;
3062 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3063 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3064 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
3065 pSMB
->Reserved4
= 0;
3066 inc_rfc1001_len(pSMB
, byte_count
);
3067 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3069 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3070 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3072 cFYI(1, "Send error in QuerySymLinkInfo = %d", rc
);
3074 /* decode response */
3076 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3077 /* BB also check enough total bytes returned */
3078 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3082 u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3084 data_start
= ((char *) &pSMBr
->hdr
.Protocol
) +
3085 le16_to_cpu(pSMBr
->t2
.DataOffset
);
3087 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3092 /* BB FIXME investigate remapping reserved chars here */
3093 *symlinkinfo
= cifs_strndup_from_utf16(data_start
,
3094 count
, is_unicode
, nls_codepage
);
3099 cifs_buf_release(pSMB
);
3101 goto querySymLinkRetry
;
3105 #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
3107 * Recent Windows versions now create symlinks more frequently
3108 * and they use the "reparse point" mechanism below. We can of course
3109 * do symlinks nicely to Samba and other servers which support the
3110 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3111 * "MF" symlinks optionally, but for recent Windows we really need to
3112 * reenable the code below and fix the cifs_symlink callers to handle this.
3113 * In the interim this code has been moved to its own config option so
3114 * it is not compiled in by default until callers fixed up and more tested.
3117 CIFSSMBQueryReparseLinkInfo(const int xid
, struct cifs_tcon
*tcon
,
3118 const unsigned char *searchName
,
3119 char *symlinkinfo
, const int buflen
, __u16 fid
,
3120 const struct nls_table
*nls_codepage
)
3124 struct smb_com_transaction_ioctl_req
*pSMB
;
3125 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3127 cFYI(1, "In Windows reparse style QueryLink for path %s", searchName
);
3128 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3133 pSMB
->TotalParameterCount
= 0 ;
3134 pSMB
->TotalDataCount
= 0;
3135 pSMB
->MaxParameterCount
= cpu_to_le32(2);
3136 /* BB find exact data count max from sess structure BB */
3137 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3138 pSMB
->MaxSetupCount
= 4;
3140 pSMB
->ParameterOffset
= 0;
3141 pSMB
->DataCount
= 0;
3142 pSMB
->DataOffset
= 0;
3143 pSMB
->SetupCount
= 4;
3144 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3145 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3146 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
3147 pSMB
->IsFsctl
= 1; /* FSCTL */
3148 pSMB
->IsRootFlag
= 0;
3149 pSMB
->Fid
= fid
; /* file handle always le */
3150 pSMB
->ByteCount
= 0;
3152 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3153 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3155 cFYI(1, "Send error in QueryReparseLinkInfo = %d", rc
);
3156 } else { /* decode response */
3157 __u32 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3158 __u32 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3159 if (get_bcc(&pSMBr
->hdr
) < 2 || data_offset
> 512) {
3160 /* BB also check enough total bytes returned */
3161 rc
= -EIO
; /* bad smb */
3164 if (data_count
&& (data_count
< 2048)) {
3165 char *end_of_smb
= 2 /* sizeof byte count */ +
3166 get_bcc(&pSMBr
->hdr
) + (char *)&pSMBr
->ByteCount
;
3168 struct reparse_data
*reparse_buf
=
3169 (struct reparse_data
*)
3170 ((char *)&pSMBr
->hdr
.Protocol
3172 if ((char *)reparse_buf
>= end_of_smb
) {
3176 if ((reparse_buf
->LinkNamesBuf
+
3177 reparse_buf
->TargetNameOffset
+
3178 reparse_buf
->TargetNameLen
) > end_of_smb
) {
3179 cFYI(1, "reparse buf beyond SMB");
3184 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3185 cifs_from_ucs2(symlinkinfo
, (__le16
*)
3186 (reparse_buf
->LinkNamesBuf
+
3187 reparse_buf
->TargetNameOffset
),
3189 reparse_buf
->TargetNameLen
,
3191 } else { /* ASCII names */
3192 strncpy(symlinkinfo
,
3193 reparse_buf
->LinkNamesBuf
+
3194 reparse_buf
->TargetNameOffset
,
3195 min_t(const int, buflen
,
3196 reparse_buf
->TargetNameLen
));
3200 cFYI(1, "Invalid return data count on "
3201 "get reparse info ioctl");
3203 symlinkinfo
[buflen
] = 0; /* just in case so the caller
3204 does not go off the end of the buffer */
3205 cFYI(1, "readlink result - %s", symlinkinfo
);
3209 cifs_buf_release(pSMB
);
3211 /* Note: On -EAGAIN error only caller can retry on handle based calls
3212 since file handle passed in no longer valid */
3216 #endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
3218 #ifdef CONFIG_CIFS_POSIX
3220 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3221 static void cifs_convert_ace(posix_acl_xattr_entry
*ace
,
3222 struct cifs_posix_ace
*cifs_ace
)
3224 /* u8 cifs fields do not need le conversion */
3225 ace
->e_perm
= cpu_to_le16(cifs_ace
->cifs_e_perm
);
3226 ace
->e_tag
= cpu_to_le16(cifs_ace
->cifs_e_tag
);
3227 ace
->e_id
= cpu_to_le32(le64_to_cpu(cifs_ace
->cifs_uid
));
3228 /* cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id); */
3233 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3234 static int cifs_copy_posix_acl(char *trgt
, char *src
, const int buflen
,
3235 const int acl_type
, const int size_of_data_area
)
3240 struct cifs_posix_ace
*pACE
;
3241 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)src
;
3242 posix_acl_xattr_header
*local_acl
= (posix_acl_xattr_header
*)trgt
;
3244 if (le16_to_cpu(cifs_acl
->version
) != CIFS_ACL_VERSION
)
3247 if (acl_type
& ACL_TYPE_ACCESS
) {
3248 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3249 pACE
= &cifs_acl
->ace_array
[0];
3250 size
= sizeof(struct cifs_posix_acl
);
3251 size
+= sizeof(struct cifs_posix_ace
) * count
;
3252 /* check if we would go beyond end of SMB */
3253 if (size_of_data_area
< size
) {
3254 cFYI(1, "bad CIFS POSIX ACL size %d vs. %d",
3255 size_of_data_area
, size
);
3258 } else if (acl_type
& ACL_TYPE_DEFAULT
) {
3259 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3260 size
= sizeof(struct cifs_posix_acl
);
3261 size
+= sizeof(struct cifs_posix_ace
) * count
;
3262 /* skip past access ACEs to get to default ACEs */
3263 pACE
= &cifs_acl
->ace_array
[count
];
3264 count
= le16_to_cpu(cifs_acl
->default_entry_count
);
3265 size
+= sizeof(struct cifs_posix_ace
) * count
;
3266 /* check if we would go beyond end of SMB */
3267 if (size_of_data_area
< size
)
3274 size
= posix_acl_xattr_size(count
);
3275 if ((buflen
== 0) || (local_acl
== NULL
)) {
3276 /* used to query ACL EA size */
3277 } else if (size
> buflen
) {
3279 } else /* buffer big enough */ {
3280 local_acl
->a_version
= cpu_to_le32(POSIX_ACL_XATTR_VERSION
);
3281 for (i
= 0; i
< count
; i
++) {
3282 cifs_convert_ace(&local_acl
->a_entries
[i
], pACE
);
3289 static __u16
convert_ace_to_cifs_ace(struct cifs_posix_ace
*cifs_ace
,
3290 const posix_acl_xattr_entry
*local_ace
)
3292 __u16 rc
= 0; /* 0 = ACL converted ok */
3294 cifs_ace
->cifs_e_perm
= le16_to_cpu(local_ace
->e_perm
);
3295 cifs_ace
->cifs_e_tag
= le16_to_cpu(local_ace
->e_tag
);
3296 /* BB is there a better way to handle the large uid? */
3297 if (local_ace
->e_id
== cpu_to_le32(-1)) {
3298 /* Probably no need to le convert -1 on any arch but can not hurt */
3299 cifs_ace
->cifs_uid
= cpu_to_le64(-1);
3301 cifs_ace
->cifs_uid
= cpu_to_le64(le32_to_cpu(local_ace
->e_id
));
3302 /*cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id);*/
3306 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3307 static __u16
ACL_to_cifs_posix(char *parm_data
, const char *pACL
,
3308 const int buflen
, const int acl_type
)
3311 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)parm_data
;
3312 posix_acl_xattr_header
*local_acl
= (posix_acl_xattr_header
*)pACL
;
3316 if ((buflen
== 0) || (pACL
== NULL
) || (cifs_acl
== NULL
))
3319 count
= posix_acl_xattr_count((size_t)buflen
);
3320 cFYI(1, "setting acl with %d entries from buf of length %d and "
3322 count
, buflen
, le32_to_cpu(local_acl
->a_version
));
3323 if (le32_to_cpu(local_acl
->a_version
) != 2) {
3324 cFYI(1, "unknown POSIX ACL version %d",
3325 le32_to_cpu(local_acl
->a_version
));
3328 cifs_acl
->version
= cpu_to_le16(1);
3329 if (acl_type
== ACL_TYPE_ACCESS
)
3330 cifs_acl
->access_entry_count
= cpu_to_le16(count
);
3331 else if (acl_type
== ACL_TYPE_DEFAULT
)
3332 cifs_acl
->default_entry_count
= cpu_to_le16(count
);
3334 cFYI(1, "unknown ACL type %d", acl_type
);
3337 for (i
= 0; i
< count
; i
++) {
3338 rc
= convert_ace_to_cifs_ace(&cifs_acl
->ace_array
[i
],
3339 &local_acl
->a_entries
[i
]);
3341 /* ACE not converted */
3346 rc
= (__u16
)(count
* sizeof(struct cifs_posix_ace
));
3347 rc
+= sizeof(struct cifs_posix_acl
);
3348 /* BB add check to make sure ACL does not overflow SMB */
3354 CIFSSMBGetPosixACL(const int xid
, struct cifs_tcon
*tcon
,
3355 const unsigned char *searchName
,
3356 char *acl_inf
, const int buflen
, const int acl_type
,
3357 const struct nls_table
*nls_codepage
, int remap
)
3359 /* SMB_QUERY_POSIX_ACL */
3360 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3361 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3365 __u16 params
, byte_count
;
3367 cFYI(1, "In GetPosixACL (Unix) for path %s", searchName
);
3370 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3375 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3377 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3378 searchName
, PATH_MAX
, nls_codepage
,
3380 name_len
++; /* trailing null */
3382 pSMB
->FileName
[name_len
] = 0;
3383 pSMB
->FileName
[name_len
+1] = 0;
3384 } else { /* BB improve the check for buffer overruns BB */
3385 name_len
= strnlen(searchName
, PATH_MAX
);
3386 name_len
++; /* trailing null */
3387 strncpy(pSMB
->FileName
, searchName
, name_len
);
3390 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3391 pSMB
->TotalDataCount
= 0;
3392 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3393 /* BB find exact max data count below from sess structure BB */
3394 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3395 pSMB
->MaxSetupCount
= 0;
3399 pSMB
->Reserved2
= 0;
3400 pSMB
->ParameterOffset
= cpu_to_le16(
3401 offsetof(struct smb_com_transaction2_qpi_req
,
3402 InformationLevel
) - 4);
3403 pSMB
->DataCount
= 0;
3404 pSMB
->DataOffset
= 0;
3405 pSMB
->SetupCount
= 1;
3406 pSMB
->Reserved3
= 0;
3407 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3408 byte_count
= params
+ 1 /* pad */ ;
3409 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3410 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3411 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_ACL
);
3412 pSMB
->Reserved4
= 0;
3413 inc_rfc1001_len(pSMB
, byte_count
);
3414 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3416 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3417 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3418 cifs_stats_inc(&tcon
->num_acl_get
);
3420 cFYI(1, "Send error in Query POSIX ACL = %d", rc
);
3422 /* decode response */
3424 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3425 /* BB also check enough total bytes returned */
3426 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3427 rc
= -EIO
; /* bad smb */
3429 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3430 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3431 rc
= cifs_copy_posix_acl(acl_inf
,
3432 (char *)&pSMBr
->hdr
.Protocol
+data_offset
,
3433 buflen
, acl_type
, count
);
3436 cifs_buf_release(pSMB
);
3443 CIFSSMBSetPosixACL(const int xid
, struct cifs_tcon
*tcon
,
3444 const unsigned char *fileName
,
3445 const char *local_acl
, const int buflen
,
3447 const struct nls_table
*nls_codepage
, int remap
)
3449 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3450 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3454 int bytes_returned
= 0;
3455 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
3457 cFYI(1, "In SetPosixACL (Unix) for path %s", fileName
);
3459 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3463 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3465 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
3466 PATH_MAX
, nls_codepage
, remap
);
3467 name_len
++; /* trailing null */
3469 } else { /* BB improve the check for buffer overruns BB */
3470 name_len
= strnlen(fileName
, PATH_MAX
);
3471 name_len
++; /* trailing null */
3472 strncpy(pSMB
->FileName
, fileName
, name_len
);
3474 params
= 6 + name_len
;
3475 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3476 /* BB find max SMB size from sess */
3477 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3478 pSMB
->MaxSetupCount
= 0;
3482 pSMB
->Reserved2
= 0;
3483 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3484 InformationLevel
) - 4;
3485 offset
= param_offset
+ params
;
3486 parm_data
= ((char *) &pSMB
->hdr
.Protocol
) + offset
;
3487 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3489 /* convert to on the wire format for POSIX ACL */
3490 data_count
= ACL_to_cifs_posix(parm_data
, local_acl
, buflen
, acl_type
);
3492 if (data_count
== 0) {
3494 goto setACLerrorExit
;
3496 pSMB
->DataOffset
= cpu_to_le16(offset
);
3497 pSMB
->SetupCount
= 1;
3498 pSMB
->Reserved3
= 0;
3499 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3500 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_ACL
);
3501 byte_count
= 3 /* pad */ + params
+ data_count
;
3502 pSMB
->DataCount
= cpu_to_le16(data_count
);
3503 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3504 pSMB
->ParameterCount
= cpu_to_le16(params
);
3505 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3506 pSMB
->Reserved4
= 0;
3507 inc_rfc1001_len(pSMB
, byte_count
);
3508 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3509 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3510 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3512 cFYI(1, "Set POSIX ACL returned %d", rc
);
3515 cifs_buf_release(pSMB
);
3521 /* BB fix tabs in this function FIXME BB */
3523 CIFSGetExtAttr(const int xid
, struct cifs_tcon
*tcon
,
3524 const int netfid
, __u64
*pExtAttrBits
, __u64
*pMask
)
3527 struct smb_t2_qfi_req
*pSMB
= NULL
;
3528 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3530 __u16 params
, byte_count
;
3532 cFYI(1, "In GetExtAttr");
3537 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3542 params
= 2 /* level */ + 2 /* fid */;
3543 pSMB
->t2
.TotalDataCount
= 0;
3544 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3545 /* BB find exact max data count below from sess structure BB */
3546 pSMB
->t2
.MaxDataCount
= cpu_to_le16(4000);
3547 pSMB
->t2
.MaxSetupCount
= 0;
3548 pSMB
->t2
.Reserved
= 0;
3550 pSMB
->t2
.Timeout
= 0;
3551 pSMB
->t2
.Reserved2
= 0;
3552 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3554 pSMB
->t2
.DataCount
= 0;
3555 pSMB
->t2
.DataOffset
= 0;
3556 pSMB
->t2
.SetupCount
= 1;
3557 pSMB
->t2
.Reserved3
= 0;
3558 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3559 byte_count
= params
+ 1 /* pad */ ;
3560 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3561 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3562 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_ATTR_FLAGS
);
3565 inc_rfc1001_len(pSMB
, byte_count
);
3566 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3568 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3569 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3571 cFYI(1, "error %d in GetExtAttr", rc
);
3573 /* decode response */
3574 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3575 /* BB also check enough total bytes returned */
3576 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3577 /* If rc should we check for EOPNOSUPP and
3578 disable the srvino flag? or in caller? */
3579 rc
= -EIO
; /* bad smb */
3581 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3582 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3583 struct file_chattr_info
*pfinfo
;
3584 /* BB Do we need a cast or hash here ? */
3586 cFYI(1, "Illegal size ret in GetExtAttr");
3590 pfinfo
= (struct file_chattr_info
*)
3591 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
3592 *pExtAttrBits
= le64_to_cpu(pfinfo
->mode
);
3593 *pMask
= le64_to_cpu(pfinfo
->mask
);
3597 cifs_buf_release(pSMB
);
3599 goto GetExtAttrRetry
;
3603 #endif /* CONFIG_POSIX */
3605 #ifdef CONFIG_CIFS_ACL
3607 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3608 * all NT TRANSACTS that we init here have total parm and data under about 400
3609 * bytes (to fit in small cifs buffer size), which is the case so far, it
3610 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3611 * returned setup area) and MaxParameterCount (returned parms size) must be set
3615 smb_init_nttransact(const __u16 sub_command
, const int setup_count
,
3616 const int parm_len
, struct cifs_tcon
*tcon
,
3621 struct smb_com_ntransact_req
*pSMB
;
3623 rc
= small_smb_init(SMB_COM_NT_TRANSACT
, 19 + setup_count
, tcon
,
3627 *ret_buf
= (void *)pSMB
;
3629 pSMB
->TotalParameterCount
= cpu_to_le32(parm_len
);
3630 pSMB
->TotalDataCount
= 0;
3631 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3632 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3633 pSMB
->DataCount
= pSMB
->TotalDataCount
;
3634 temp_offset
= offsetof(struct smb_com_ntransact_req
, Parms
) +
3635 (setup_count
* 2) - 4 /* for rfc1001 length itself */;
3636 pSMB
->ParameterOffset
= cpu_to_le32(temp_offset
);
3637 pSMB
->DataOffset
= cpu_to_le32(temp_offset
+ parm_len
);
3638 pSMB
->SetupCount
= setup_count
; /* no need to le convert byte fields */
3639 pSMB
->SubCommand
= cpu_to_le16(sub_command
);
3644 validate_ntransact(char *buf
, char **ppparm
, char **ppdata
,
3645 __u32
*pparmlen
, __u32
*pdatalen
)
3648 __u32 data_count
, data_offset
, parm_count
, parm_offset
;
3649 struct smb_com_ntransact_rsp
*pSMBr
;
3658 pSMBr
= (struct smb_com_ntransact_rsp
*)buf
;
3660 bcc
= get_bcc(&pSMBr
->hdr
);
3661 end_of_smb
= 2 /* sizeof byte count */ + bcc
+
3662 (char *)&pSMBr
->ByteCount
;
3664 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3665 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3666 parm_offset
= le32_to_cpu(pSMBr
->ParameterOffset
);
3667 parm_count
= le32_to_cpu(pSMBr
->ParameterCount
);
3669 *ppparm
= (char *)&pSMBr
->hdr
.Protocol
+ parm_offset
;
3670 *ppdata
= (char *)&pSMBr
->hdr
.Protocol
+ data_offset
;
3672 /* should we also check that parm and data areas do not overlap? */
3673 if (*ppparm
> end_of_smb
) {
3674 cFYI(1, "parms start after end of smb");
3676 } else if (parm_count
+ *ppparm
> end_of_smb
) {
3677 cFYI(1, "parm end after end of smb");
3679 } else if (*ppdata
> end_of_smb
) {
3680 cFYI(1, "data starts after end of smb");
3682 } else if (data_count
+ *ppdata
> end_of_smb
) {
3683 cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
3684 *ppdata
, data_count
, (data_count
+ *ppdata
),
3687 } else if (parm_count
+ data_count
> bcc
) {
3688 cFYI(1, "parm count and data count larger than SMB");
3691 *pdatalen
= data_count
;
3692 *pparmlen
= parm_count
;
3696 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3698 CIFSSMBGetCIFSACL(const int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3699 struct cifs_ntsd
**acl_inf
, __u32
*pbuflen
)
3703 QUERY_SEC_DESC_REQ
*pSMB
;
3706 cFYI(1, "GetCifsACL");
3711 rc
= smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC
, 0,
3712 8 /* parm len */, tcon
, (void **) &pSMB
);
3716 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3717 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3718 pSMB
->MaxSetupCount
= 0;
3719 pSMB
->Fid
= fid
; /* file handle always le */
3720 pSMB
->AclFlags
= cpu_to_le32(CIFS_ACL_OWNER
| CIFS_ACL_GROUP
|
3722 pSMB
->ByteCount
= cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3723 inc_rfc1001_len(pSMB
, 11);
3724 iov
[0].iov_base
= (char *)pSMB
;
3725 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
3727 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovec */, &buf_type
,
3729 cifs_stats_inc(&tcon
->num_acl_get
);
3731 cFYI(1, "Send error in QuerySecDesc = %d", rc
);
3732 } else { /* decode response */
3736 struct smb_com_ntransact_rsp
*pSMBr
;
3739 /* validate_nttransact */
3740 rc
= validate_ntransact(iov
[0].iov_base
, (char **)&parm
,
3741 &pdata
, &parm_len
, pbuflen
);
3744 pSMBr
= (struct smb_com_ntransact_rsp
*)iov
[0].iov_base
;
3746 cFYI(1, "smb %p parm %p data %p", pSMBr
, parm
, *acl_inf
);
3748 if (le32_to_cpu(pSMBr
->ParameterCount
) != 4) {
3749 rc
= -EIO
; /* bad smb */
3754 /* BB check that data area is minimum length and as big as acl_len */
3756 acl_len
= le32_to_cpu(*parm
);
3757 if (acl_len
!= *pbuflen
) {
3758 cERROR(1, "acl length %d does not match %d",
3760 if (*pbuflen
> acl_len
)
3764 /* check if buffer is big enough for the acl
3765 header followed by the smallest SID */
3766 if ((*pbuflen
< sizeof(struct cifs_ntsd
) + 8) ||
3767 (*pbuflen
>= 64 * 1024)) {
3768 cERROR(1, "bad acl length %d", *pbuflen
);
3772 *acl_inf
= kmalloc(*pbuflen
, GFP_KERNEL
);
3773 if (*acl_inf
== NULL
) {
3777 memcpy(*acl_inf
, pdata
, *pbuflen
);
3781 if (buf_type
== CIFS_SMALL_BUFFER
)
3782 cifs_small_buf_release(iov
[0].iov_base
);
3783 else if (buf_type
== CIFS_LARGE_BUFFER
)
3784 cifs_buf_release(iov
[0].iov_base
);
3785 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3790 CIFSSMBSetCIFSACL(const int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3791 struct cifs_ntsd
*pntsd
, __u32 acllen
, int aclflag
)
3793 __u16 byte_count
, param_count
, data_count
, param_offset
, data_offset
;
3795 int bytes_returned
= 0;
3796 SET_SEC_DESC_REQ
*pSMB
= NULL
;
3800 rc
= smb_init(SMB_COM_NT_TRANSACT
, 19, tcon
, (void **) &pSMB
, &pSMBr
);
3804 pSMB
->MaxSetupCount
= 0;
3808 param_offset
= offsetof(struct smb_com_transaction_ssec_req
, Fid
) - 4;
3809 data_count
= acllen
;
3810 data_offset
= param_offset
+ param_count
;
3811 byte_count
= 3 /* pad */ + param_count
;
3813 pSMB
->DataCount
= cpu_to_le32(data_count
);
3814 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3815 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3816 pSMB
->MaxDataCount
= cpu_to_le32(16384);
3817 pSMB
->ParameterCount
= cpu_to_le32(param_count
);
3818 pSMB
->ParameterOffset
= cpu_to_le32(param_offset
);
3819 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3820 pSMB
->DataOffset
= cpu_to_le32(data_offset
);
3821 pSMB
->SetupCount
= 0;
3822 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC
);
3823 pSMB
->ByteCount
= cpu_to_le16(byte_count
+data_count
);
3825 pSMB
->Fid
= fid
; /* file handle always le */
3826 pSMB
->Reserved2
= 0;
3827 pSMB
->AclFlags
= cpu_to_le32(aclflag
);
3829 if (pntsd
&& acllen
) {
3830 memcpy((char *)pSMBr
+ offsetof(struct smb_hdr
, Protocol
) +
3831 data_offset
, pntsd
, acllen
);
3832 inc_rfc1001_len(pSMB
, byte_count
+ data_count
);
3834 inc_rfc1001_len(pSMB
, byte_count
);
3836 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3837 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3839 cFYI(1, "SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned
, rc
);
3841 cFYI(1, "Set CIFS ACL returned %d", rc
);
3842 cifs_buf_release(pSMB
);
3845 goto setCifsAclRetry
;
3850 #endif /* CONFIG_CIFS_ACL */
3852 /* Legacy Query Path Information call for lookup to old servers such
3854 int SMBQueryInformation(const int xid
, struct cifs_tcon
*tcon
,
3855 const unsigned char *searchName
,
3856 FILE_ALL_INFO
*pFinfo
,
3857 const struct nls_table
*nls_codepage
, int remap
)
3859 QUERY_INFORMATION_REQ
*pSMB
;
3860 QUERY_INFORMATION_RSP
*pSMBr
;
3865 cFYI(1, "In SMBQPath path %s", searchName
);
3867 rc
= smb_init(SMB_COM_QUERY_INFORMATION
, 0, tcon
, (void **) &pSMB
,
3872 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3874 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3875 searchName
, PATH_MAX
, nls_codepage
,
3877 name_len
++; /* trailing null */
3880 name_len
= strnlen(searchName
, PATH_MAX
);
3881 name_len
++; /* trailing null */
3882 strncpy(pSMB
->FileName
, searchName
, name_len
);
3884 pSMB
->BufferFormat
= 0x04;
3885 name_len
++; /* account for buffer type byte */
3886 inc_rfc1001_len(pSMB
, (__u16
)name_len
);
3887 pSMB
->ByteCount
= cpu_to_le16(name_len
);
3889 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3890 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3892 cFYI(1, "Send error in QueryInfo = %d", rc
);
3893 } else if (pFinfo
) {
3895 __u32 time
= le32_to_cpu(pSMBr
->last_write_time
);
3897 /* decode response */
3898 /* BB FIXME - add time zone adjustment BB */
3899 memset(pFinfo
, 0, sizeof(FILE_ALL_INFO
));
3902 /* decode time fields */
3903 pFinfo
->ChangeTime
= cpu_to_le64(cifs_UnixTimeToNT(ts
));
3904 pFinfo
->LastWriteTime
= pFinfo
->ChangeTime
;
3905 pFinfo
->LastAccessTime
= 0;
3906 pFinfo
->AllocationSize
=
3907 cpu_to_le64(le32_to_cpu(pSMBr
->size
));
3908 pFinfo
->EndOfFile
= pFinfo
->AllocationSize
;
3909 pFinfo
->Attributes
=
3910 cpu_to_le32(le16_to_cpu(pSMBr
->attr
));
3912 rc
= -EIO
; /* bad buffer passed in */
3914 cifs_buf_release(pSMB
);
3923 CIFSSMBQFileInfo(const int xid
, struct cifs_tcon
*tcon
,
3924 u16 netfid
, FILE_ALL_INFO
*pFindData
)
3926 struct smb_t2_qfi_req
*pSMB
= NULL
;
3927 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3930 __u16 params
, byte_count
;
3933 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3938 params
= 2 /* level */ + 2 /* fid */;
3939 pSMB
->t2
.TotalDataCount
= 0;
3940 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3941 /* BB find exact max data count below from sess structure BB */
3942 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3943 pSMB
->t2
.MaxSetupCount
= 0;
3944 pSMB
->t2
.Reserved
= 0;
3946 pSMB
->t2
.Timeout
= 0;
3947 pSMB
->t2
.Reserved2
= 0;
3948 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3950 pSMB
->t2
.DataCount
= 0;
3951 pSMB
->t2
.DataOffset
= 0;
3952 pSMB
->t2
.SetupCount
= 1;
3953 pSMB
->t2
.Reserved3
= 0;
3954 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3955 byte_count
= params
+ 1 /* pad */ ;
3956 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3957 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3958 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
3961 inc_rfc1001_len(pSMB
, byte_count
);
3963 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3964 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3966 cFYI(1, "Send error in QPathInfo = %d", rc
);
3967 } else { /* decode response */
3968 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3970 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
3972 else if (get_bcc(&pSMBr
->hdr
) < 40)
3973 rc
= -EIO
; /* bad smb */
3974 else if (pFindData
) {
3975 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3976 memcpy((char *) pFindData
,
3977 (char *) &pSMBr
->hdr
.Protocol
+
3978 data_offset
, sizeof(FILE_ALL_INFO
));
3982 cifs_buf_release(pSMB
);
3984 goto QFileInfoRetry
;
3990 CIFSSMBQPathInfo(const int xid
, struct cifs_tcon
*tcon
,
3991 const unsigned char *searchName
,
3992 FILE_ALL_INFO
*pFindData
,
3993 int legacy
/* old style infolevel */,
3994 const struct nls_table
*nls_codepage
, int remap
)
3996 /* level 263 SMB_QUERY_FILE_ALL_INFO */
3997 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3998 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4002 __u16 params
, byte_count
;
4004 /* cFYI(1, "In QPathInfo path %s", searchName); */
4006 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4011 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4013 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4014 PATH_MAX
, nls_codepage
, remap
);
4015 name_len
++; /* trailing null */
4017 } else { /* BB improve the check for buffer overruns BB */
4018 name_len
= strnlen(searchName
, PATH_MAX
);
4019 name_len
++; /* trailing null */
4020 strncpy(pSMB
->FileName
, searchName
, name_len
);
4023 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4024 pSMB
->TotalDataCount
= 0;
4025 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4026 /* BB find exact max SMB PDU from sess structure BB */
4027 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4028 pSMB
->MaxSetupCount
= 0;
4032 pSMB
->Reserved2
= 0;
4033 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4034 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4035 pSMB
->DataCount
= 0;
4036 pSMB
->DataOffset
= 0;
4037 pSMB
->SetupCount
= 1;
4038 pSMB
->Reserved3
= 0;
4039 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4040 byte_count
= params
+ 1 /* pad */ ;
4041 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4042 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4044 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
4046 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4047 pSMB
->Reserved4
= 0;
4048 inc_rfc1001_len(pSMB
, byte_count
);
4049 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4051 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4052 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4054 cFYI(1, "Send error in QPathInfo = %d", rc
);
4055 } else { /* decode response */
4056 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4058 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4060 else if (!legacy
&& get_bcc(&pSMBr
->hdr
) < 40)
4061 rc
= -EIO
; /* bad smb */
4062 else if (legacy
&& get_bcc(&pSMBr
->hdr
) < 24)
4063 rc
= -EIO
; /* 24 or 26 expected but we do not read
4065 else if (pFindData
) {
4067 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4069 /* On legacy responses we do not read the last field,
4070 EAsize, fortunately since it varies by subdialect and
4071 also note it differs on Set vs. Get, ie two bytes or 4
4072 bytes depending but we don't care here */
4074 size
= sizeof(FILE_INFO_STANDARD
);
4076 size
= sizeof(FILE_ALL_INFO
);
4077 memcpy((char *) pFindData
,
4078 (char *) &pSMBr
->hdr
.Protocol
+
4083 cifs_buf_release(pSMB
);
4085 goto QPathInfoRetry
;
4091 CIFSSMBUnixQFileInfo(const int xid
, struct cifs_tcon
*tcon
,
4092 u16 netfid
, FILE_UNIX_BASIC_INFO
*pFindData
)
4094 struct smb_t2_qfi_req
*pSMB
= NULL
;
4095 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4098 __u16 params
, byte_count
;
4101 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4106 params
= 2 /* level */ + 2 /* fid */;
4107 pSMB
->t2
.TotalDataCount
= 0;
4108 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4109 /* BB find exact max data count below from sess structure BB */
4110 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4111 pSMB
->t2
.MaxSetupCount
= 0;
4112 pSMB
->t2
.Reserved
= 0;
4114 pSMB
->t2
.Timeout
= 0;
4115 pSMB
->t2
.Reserved2
= 0;
4116 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4118 pSMB
->t2
.DataCount
= 0;
4119 pSMB
->t2
.DataOffset
= 0;
4120 pSMB
->t2
.SetupCount
= 1;
4121 pSMB
->t2
.Reserved3
= 0;
4122 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4123 byte_count
= params
+ 1 /* pad */ ;
4124 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4125 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4126 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4129 inc_rfc1001_len(pSMB
, byte_count
);
4131 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4132 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4134 cFYI(1, "Send error in QPathInfo = %d", rc
);
4135 } else { /* decode response */
4136 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4138 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4139 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response. "
4140 "Unix Extensions can be disabled on mount "
4141 "by specifying the nosfu mount option.");
4142 rc
= -EIO
; /* bad smb */
4144 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4145 memcpy((char *) pFindData
,
4146 (char *) &pSMBr
->hdr
.Protocol
+
4148 sizeof(FILE_UNIX_BASIC_INFO
));
4152 cifs_buf_release(pSMB
);
4154 goto UnixQFileInfoRetry
;
4160 CIFSSMBUnixQPathInfo(const int xid
, struct cifs_tcon
*tcon
,
4161 const unsigned char *searchName
,
4162 FILE_UNIX_BASIC_INFO
*pFindData
,
4163 const struct nls_table
*nls_codepage
, int remap
)
4165 /* SMB_QUERY_FILE_UNIX_BASIC */
4166 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4167 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4169 int bytes_returned
= 0;
4171 __u16 params
, byte_count
;
4173 cFYI(1, "In QPathInfo (Unix) the path %s", searchName
);
4175 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4180 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4182 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4183 PATH_MAX
, nls_codepage
, remap
);
4184 name_len
++; /* trailing null */
4186 } else { /* BB improve the check for buffer overruns BB */
4187 name_len
= strnlen(searchName
, PATH_MAX
);
4188 name_len
++; /* trailing null */
4189 strncpy(pSMB
->FileName
, searchName
, name_len
);
4192 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4193 pSMB
->TotalDataCount
= 0;
4194 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4195 /* BB find exact max SMB PDU from sess structure BB */
4196 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4197 pSMB
->MaxSetupCount
= 0;
4201 pSMB
->Reserved2
= 0;
4202 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4203 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4204 pSMB
->DataCount
= 0;
4205 pSMB
->DataOffset
= 0;
4206 pSMB
->SetupCount
= 1;
4207 pSMB
->Reserved3
= 0;
4208 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4209 byte_count
= params
+ 1 /* pad */ ;
4210 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4211 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4212 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4213 pSMB
->Reserved4
= 0;
4214 inc_rfc1001_len(pSMB
, byte_count
);
4215 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4217 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4218 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4220 cFYI(1, "Send error in QPathInfo = %d", rc
);
4221 } else { /* decode response */
4222 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4224 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4225 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response. "
4226 "Unix Extensions can be disabled on mount "
4227 "by specifying the nosfu mount option.");
4228 rc
= -EIO
; /* bad smb */
4230 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4231 memcpy((char *) pFindData
,
4232 (char *) &pSMBr
->hdr
.Protocol
+
4234 sizeof(FILE_UNIX_BASIC_INFO
));
4237 cifs_buf_release(pSMB
);
4239 goto UnixQPathInfoRetry
;
4244 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4246 CIFSFindFirst(const int xid
, struct cifs_tcon
*tcon
,
4247 const char *searchName
,
4248 const struct nls_table
*nls_codepage
,
4249 __u16
*pnetfid
, __u16 search_flags
,
4250 struct cifs_search_info
*psrch_inf
, int remap
, const char dirsep
)
4252 /* level 257 SMB_ */
4253 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
4254 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
4255 T2_FFIRST_RSP_PARMS
*parms
;
4257 int bytes_returned
= 0;
4259 __u16 params
, byte_count
;
4261 cFYI(1, "In FindFirst for %s", searchName
);
4264 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4269 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4271 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4272 PATH_MAX
, nls_codepage
, remap
);
4273 /* We can not add the asterik earlier in case
4274 it got remapped to 0xF03A as if it were part of the
4275 directory name instead of a wildcard */
4277 pSMB
->FileName
[name_len
] = dirsep
;
4278 pSMB
->FileName
[name_len
+1] = 0;
4279 pSMB
->FileName
[name_len
+2] = '*';
4280 pSMB
->FileName
[name_len
+3] = 0;
4281 name_len
+= 4; /* now the trailing null */
4282 pSMB
->FileName
[name_len
] = 0; /* null terminate just in case */
4283 pSMB
->FileName
[name_len
+1] = 0;
4285 } else { /* BB add check for overrun of SMB buf BB */
4286 name_len
= strnlen(searchName
, PATH_MAX
);
4287 /* BB fix here and in unicode clause above ie
4288 if (name_len > buffersize-header)
4289 free buffer exit; BB */
4290 strncpy(pSMB
->FileName
, searchName
, name_len
);
4291 pSMB
->FileName
[name_len
] = dirsep
;
4292 pSMB
->FileName
[name_len
+1] = '*';
4293 pSMB
->FileName
[name_len
+2] = 0;
4297 params
= 12 + name_len
/* includes null */ ;
4298 pSMB
->TotalDataCount
= 0; /* no EAs */
4299 pSMB
->MaxParameterCount
= cpu_to_le16(10);
4300 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4301 pSMB
->MaxSetupCount
= 0;
4305 pSMB
->Reserved2
= 0;
4306 byte_count
= params
+ 1 /* pad */ ;
4307 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4308 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4309 pSMB
->ParameterOffset
= cpu_to_le16(
4310 offsetof(struct smb_com_transaction2_ffirst_req
, SearchAttributes
)
4312 pSMB
->DataCount
= 0;
4313 pSMB
->DataOffset
= 0;
4314 pSMB
->SetupCount
= 1; /* one byte, no need to make endian neutral */
4315 pSMB
->Reserved3
= 0;
4316 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
4317 pSMB
->SearchAttributes
=
4318 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
4320 pSMB
->SearchCount
= cpu_to_le16(CIFSMaxBufSize
/sizeof(FILE_UNIX_INFO
));
4321 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4322 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4324 /* BB what should we set StorageType to? Does it matter? BB */
4325 pSMB
->SearchStorageType
= 0;
4326 inc_rfc1001_len(pSMB
, byte_count
);
4327 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4329 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4330 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4331 cifs_stats_inc(&tcon
->num_ffirst
);
4333 if (rc
) {/* BB add logic to retry regular search if Unix search
4334 rejected unexpectedly by server */
4335 /* BB Add code to handle unsupported level rc */
4336 cFYI(1, "Error in FindFirst = %d", rc
);
4338 cifs_buf_release(pSMB
);
4340 /* BB eventually could optimize out free and realloc of buf */
4343 goto findFirstRetry
;
4344 } else { /* decode response */
4345 /* BB remember to free buffer if error BB */
4346 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4350 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4351 psrch_inf
->unicode
= true;
4353 psrch_inf
->unicode
= false;
4355 psrch_inf
->ntwrk_buf_start
= (char *)pSMBr
;
4356 psrch_inf
->smallBuf
= 0;
4357 psrch_inf
->srch_entries_start
=
4358 (char *) &pSMBr
->hdr
.Protocol
+
4359 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4360 parms
= (T2_FFIRST_RSP_PARMS
*)((char *) &pSMBr
->hdr
.Protocol
+
4361 le16_to_cpu(pSMBr
->t2
.ParameterOffset
));
4363 if (parms
->EndofSearch
)
4364 psrch_inf
->endOfSearch
= true;
4366 psrch_inf
->endOfSearch
= false;
4368 psrch_inf
->entries_in_buffer
=
4369 le16_to_cpu(parms
->SearchCount
);
4370 psrch_inf
->index_of_last_entry
= 2 /* skip . and .. */ +
4371 psrch_inf
->entries_in_buffer
;
4372 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4373 if (CIFSMaxBufSize
< lnoff
) {
4374 cERROR(1, "ignoring corrupt resume name");
4375 psrch_inf
->last_entry
= NULL
;
4379 psrch_inf
->last_entry
= psrch_inf
->srch_entries_start
+
4382 *pnetfid
= parms
->SearchHandle
;
4384 cifs_buf_release(pSMB
);
4391 int CIFSFindNext(const int xid
, struct cifs_tcon
*tcon
, __u16 searchHandle
,
4392 __u16 search_flags
, struct cifs_search_info
*psrch_inf
)
4394 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
4395 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
4396 T2_FNEXT_RSP_PARMS
*parms
;
4397 char *response_data
;
4400 unsigned int name_len
;
4401 __u16 params
, byte_count
;
4403 cFYI(1, "In FindNext");
4405 if (psrch_inf
->endOfSearch
)
4408 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4413 params
= 14; /* includes 2 bytes of null string, converted to LE below*/
4415 pSMB
->TotalDataCount
= 0; /* no EAs */
4416 pSMB
->MaxParameterCount
= cpu_to_le16(8);
4417 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4418 pSMB
->MaxSetupCount
= 0;
4422 pSMB
->Reserved2
= 0;
4423 pSMB
->ParameterOffset
= cpu_to_le16(
4424 offsetof(struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
4425 pSMB
->DataCount
= 0;
4426 pSMB
->DataOffset
= 0;
4427 pSMB
->SetupCount
= 1;
4428 pSMB
->Reserved3
= 0;
4429 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
4430 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
4432 cpu_to_le16(CIFSMaxBufSize
/ sizeof(FILE_UNIX_INFO
));
4433 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4434 pSMB
->ResumeKey
= psrch_inf
->resume_key
;
4435 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4437 name_len
= psrch_inf
->resume_name_len
;
4439 if (name_len
< PATH_MAX
) {
4440 memcpy(pSMB
->ResumeFileName
, psrch_inf
->presume_name
, name_len
);
4441 byte_count
+= name_len
;
4442 /* 14 byte parm len above enough for 2 byte null terminator */
4443 pSMB
->ResumeFileName
[name_len
] = 0;
4444 pSMB
->ResumeFileName
[name_len
+1] = 0;
4447 goto FNext2_err_exit
;
4449 byte_count
= params
+ 1 /* pad */ ;
4450 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4451 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4452 inc_rfc1001_len(pSMB
, byte_count
);
4453 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4455 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4456 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4457 cifs_stats_inc(&tcon
->num_fnext
);
4460 psrch_inf
->endOfSearch
= true;
4461 cifs_buf_release(pSMB
);
4462 rc
= 0; /* search probably was closed at end of search*/
4464 cFYI(1, "FindNext returned = %d", rc
);
4465 } else { /* decode response */
4466 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4471 /* BB fixme add lock for file (srch_info) struct here */
4472 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4473 psrch_inf
->unicode
= true;
4475 psrch_inf
->unicode
= false;
4476 response_data
= (char *) &pSMBr
->hdr
.Protocol
+
4477 le16_to_cpu(pSMBr
->t2
.ParameterOffset
);
4478 parms
= (T2_FNEXT_RSP_PARMS
*)response_data
;
4479 response_data
= (char *)&pSMBr
->hdr
.Protocol
+
4480 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4481 if (psrch_inf
->smallBuf
)
4482 cifs_small_buf_release(
4483 psrch_inf
->ntwrk_buf_start
);
4485 cifs_buf_release(psrch_inf
->ntwrk_buf_start
);
4486 psrch_inf
->srch_entries_start
= response_data
;
4487 psrch_inf
->ntwrk_buf_start
= (char *)pSMB
;
4488 psrch_inf
->smallBuf
= 0;
4489 if (parms
->EndofSearch
)
4490 psrch_inf
->endOfSearch
= true;
4492 psrch_inf
->endOfSearch
= false;
4493 psrch_inf
->entries_in_buffer
=
4494 le16_to_cpu(parms
->SearchCount
);
4495 psrch_inf
->index_of_last_entry
+=
4496 psrch_inf
->entries_in_buffer
;
4497 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4498 if (CIFSMaxBufSize
< lnoff
) {
4499 cERROR(1, "ignoring corrupt resume name");
4500 psrch_inf
->last_entry
= NULL
;
4503 psrch_inf
->last_entry
=
4504 psrch_inf
->srch_entries_start
+ lnoff
;
4506 /* cFYI(1, "fnxt2 entries in buf %d index_of_last %d",
4507 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4509 /* BB fixme add unlock here */
4514 /* BB On error, should we leave previous search buf (and count and
4515 last entry fields) intact or free the previous one? */
4517 /* Note: On -EAGAIN error only caller can retry on handle based calls
4518 since file handle passed in no longer valid */
4521 cifs_buf_release(pSMB
);
4526 CIFSFindClose(const int xid
, struct cifs_tcon
*tcon
,
4527 const __u16 searchHandle
)
4530 FINDCLOSE_REQ
*pSMB
= NULL
;
4532 cFYI(1, "In CIFSSMBFindClose");
4533 rc
= small_smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **)&pSMB
);
4535 /* no sense returning error if session restarted
4536 as file handle has been closed */
4542 pSMB
->FileID
= searchHandle
;
4543 pSMB
->ByteCount
= 0;
4544 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
4546 cERROR(1, "Send error in FindClose = %d", rc
);
4548 cifs_stats_inc(&tcon
->num_fclose
);
4550 /* Since session is dead, search handle closed on server already */
4558 CIFSGetSrvInodeNumber(const int xid
, struct cifs_tcon
*tcon
,
4559 const unsigned char *searchName
,
4560 __u64
*inode_number
,
4561 const struct nls_table
*nls_codepage
, int remap
)
4564 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4565 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4566 int name_len
, bytes_returned
;
4567 __u16 params
, byte_count
;
4569 cFYI(1, "In GetSrvInodeNum for %s", searchName
);
4573 GetInodeNumberRetry
:
4574 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4579 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4581 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4582 searchName
, PATH_MAX
, nls_codepage
,
4584 name_len
++; /* trailing null */
4586 } else { /* BB improve the check for buffer overruns BB */
4587 name_len
= strnlen(searchName
, PATH_MAX
);
4588 name_len
++; /* trailing null */
4589 strncpy(pSMB
->FileName
, searchName
, name_len
);
4592 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
4593 pSMB
->TotalDataCount
= 0;
4594 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4595 /* BB find exact max data count below from sess structure BB */
4596 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4597 pSMB
->MaxSetupCount
= 0;
4601 pSMB
->Reserved2
= 0;
4602 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4603 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4604 pSMB
->DataCount
= 0;
4605 pSMB
->DataOffset
= 0;
4606 pSMB
->SetupCount
= 1;
4607 pSMB
->Reserved3
= 0;
4608 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4609 byte_count
= params
+ 1 /* pad */ ;
4610 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4611 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4612 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO
);
4613 pSMB
->Reserved4
= 0;
4614 inc_rfc1001_len(pSMB
, byte_count
);
4615 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4617 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4618 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4620 cFYI(1, "error %d in QueryInternalInfo", rc
);
4622 /* decode response */
4623 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4624 /* BB also check enough total bytes returned */
4625 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
4626 /* If rc should we check for EOPNOSUPP and
4627 disable the srvino flag? or in caller? */
4628 rc
= -EIO
; /* bad smb */
4630 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4631 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
4632 struct file_internal_info
*pfinfo
;
4633 /* BB Do we need a cast or hash here ? */
4635 cFYI(1, "Illegal size ret in QryIntrnlInf");
4637 goto GetInodeNumOut
;
4639 pfinfo
= (struct file_internal_info
*)
4640 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
4641 *inode_number
= le64_to_cpu(pfinfo
->UniqueId
);
4645 cifs_buf_release(pSMB
);
4647 goto GetInodeNumberRetry
;
4651 /* parses DFS refferal V3 structure
4652 * caller is responsible for freeing target_nodes
4655 * on failure - errno
4658 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
,
4659 unsigned int *num_of_nodes
,
4660 struct dfs_info3_param
**target_nodes
,
4661 const struct nls_table
*nls_codepage
, int remap
,
4662 const char *searchName
)
4667 struct dfs_referral_level_3
*ref
;
4669 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4673 *num_of_nodes
= le16_to_cpu(pSMBr
->NumberOfReferrals
);
4675 if (*num_of_nodes
< 1) {
4676 cERROR(1, "num_referrals: must be at least > 0,"
4677 "but we get num_referrals = %d", *num_of_nodes
);
4679 goto parse_DFS_referrals_exit
;
4682 ref
= (struct dfs_referral_level_3
*) &(pSMBr
->referrals
);
4683 if (ref
->VersionNumber
!= cpu_to_le16(3)) {
4684 cERROR(1, "Referrals of V%d version are not supported,"
4685 "should be V3", le16_to_cpu(ref
->VersionNumber
));
4687 goto parse_DFS_referrals_exit
;
4690 /* get the upper boundary of the resp buffer */
4691 data_end
= (char *)(&(pSMBr
->PathConsumed
)) +
4692 le16_to_cpu(pSMBr
->t2
.DataCount
);
4694 cFYI(1, "num_referrals: %d dfs flags: 0x%x ...",
4696 le32_to_cpu(pSMBr
->DFSFlags
));
4698 *target_nodes
= kzalloc(sizeof(struct dfs_info3_param
) *
4699 *num_of_nodes
, GFP_KERNEL
);
4700 if (*target_nodes
== NULL
) {
4701 cERROR(1, "Failed to allocate buffer for target_nodes");
4703 goto parse_DFS_referrals_exit
;
4706 /* collect necessary data from referrals */
4707 for (i
= 0; i
< *num_of_nodes
; i
++) {
4710 struct dfs_info3_param
*node
= (*target_nodes
)+i
;
4712 node
->flags
= le32_to_cpu(pSMBr
->DFSFlags
);
4714 __le16
*tmp
= kmalloc(strlen(searchName
)*2 + 2,
4718 goto parse_DFS_referrals_exit
;
4720 cifsConvertToUTF16((__le16
*) tmp
, searchName
,
4721 PATH_MAX
, nls_codepage
, remap
);
4722 node
->path_consumed
= cifs_utf16_bytes(tmp
,
4723 le16_to_cpu(pSMBr
->PathConsumed
),
4727 node
->path_consumed
= le16_to_cpu(pSMBr
->PathConsumed
);
4729 node
->server_type
= le16_to_cpu(ref
->ServerType
);
4730 node
->ref_flag
= le16_to_cpu(ref
->ReferralEntryFlags
);
4733 temp
= (char *)ref
+ le16_to_cpu(ref
->DfsPathOffset
);
4734 max_len
= data_end
- temp
;
4735 node
->path_name
= cifs_strndup_from_utf16(temp
, max_len
,
4736 is_unicode
, nls_codepage
);
4737 if (!node
->path_name
) {
4739 goto parse_DFS_referrals_exit
;
4742 /* copy link target UNC */
4743 temp
= (char *)ref
+ le16_to_cpu(ref
->NetworkAddressOffset
);
4744 max_len
= data_end
- temp
;
4745 node
->node_name
= cifs_strndup_from_utf16(temp
, max_len
,
4746 is_unicode
, nls_codepage
);
4747 if (!node
->node_name
) {
4749 goto parse_DFS_referrals_exit
;
4755 parse_DFS_referrals_exit
:
4757 free_dfs_info_array(*target_nodes
, *num_of_nodes
);
4758 *target_nodes
= NULL
;
4765 CIFSGetDFSRefer(const int xid
, struct cifs_ses
*ses
,
4766 const unsigned char *searchName
,
4767 struct dfs_info3_param
**target_nodes
,
4768 unsigned int *num_of_nodes
,
4769 const struct nls_table
*nls_codepage
, int remap
)
4771 /* TRANS2_GET_DFS_REFERRAL */
4772 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
4773 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
4777 __u16 params
, byte_count
;
4779 *target_nodes
= NULL
;
4781 cFYI(1, "In GetDFSRefer the path %s", searchName
);
4785 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, NULL
, (void **) &pSMB
,
4790 /* server pointer checked in called function,
4791 but should never be null here anyway */
4792 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
4793 pSMB
->hdr
.Tid
= ses
->ipc_tid
;
4794 pSMB
->hdr
.Uid
= ses
->Suid
;
4795 if (ses
->capabilities
& CAP_STATUS32
)
4796 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
4797 if (ses
->capabilities
& CAP_DFS
)
4798 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
4800 if (ses
->capabilities
& CAP_UNICODE
) {
4801 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
4803 cifsConvertToUTF16((__le16
*) pSMB
->RequestFileName
,
4804 searchName
, PATH_MAX
, nls_codepage
,
4806 name_len
++; /* trailing null */
4808 } else { /* BB improve the check for buffer overruns BB */
4809 name_len
= strnlen(searchName
, PATH_MAX
);
4810 name_len
++; /* trailing null */
4811 strncpy(pSMB
->RequestFileName
, searchName
, name_len
);
4815 if (ses
->server
->sec_mode
&
4816 (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
))
4817 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
4820 pSMB
->hdr
.Uid
= ses
->Suid
;
4822 params
= 2 /* level */ + name_len
/*includes null */ ;
4823 pSMB
->TotalDataCount
= 0;
4824 pSMB
->DataCount
= 0;
4825 pSMB
->DataOffset
= 0;
4826 pSMB
->MaxParameterCount
= 0;
4827 /* BB find exact max SMB PDU from sess structure BB */
4828 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4829 pSMB
->MaxSetupCount
= 0;
4833 pSMB
->Reserved2
= 0;
4834 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4835 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
4836 pSMB
->SetupCount
= 1;
4837 pSMB
->Reserved3
= 0;
4838 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
4839 byte_count
= params
+ 3 /* pad */ ;
4840 pSMB
->ParameterCount
= cpu_to_le16(params
);
4841 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4842 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
4843 inc_rfc1001_len(pSMB
, byte_count
);
4844 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4846 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
4847 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4849 cFYI(1, "Send error in GetDFSRefer = %d", rc
);
4852 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4854 /* BB Also check if enough total bytes returned? */
4855 if (rc
|| get_bcc(&pSMBr
->hdr
) < 17) {
4856 rc
= -EIO
; /* bad smb */
4860 cFYI(1, "Decoding GetDFSRefer response BCC: %d Offset %d",
4861 get_bcc(&pSMBr
->hdr
),
4862 le16_to_cpu(pSMBr
->t2
.DataOffset
));
4864 /* parse returned result into more usable form */
4865 rc
= parse_DFS_referrals(pSMBr
, num_of_nodes
,
4866 target_nodes
, nls_codepage
, remap
,
4870 cifs_buf_release(pSMB
);
4878 /* Query File System Info such as free space to old servers such as Win 9x */
4880 SMBOldQFSInfo(const int xid
, struct cifs_tcon
*tcon
, struct kstatfs
*FSData
)
4882 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4883 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4884 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4885 FILE_SYSTEM_ALLOC_INFO
*response_data
;
4887 int bytes_returned
= 0;
4888 __u16 params
, byte_count
;
4890 cFYI(1, "OldQFSInfo");
4892 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4897 params
= 2; /* level */
4898 pSMB
->TotalDataCount
= 0;
4899 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4900 pSMB
->MaxDataCount
= cpu_to_le16(1000);
4901 pSMB
->MaxSetupCount
= 0;
4905 pSMB
->Reserved2
= 0;
4906 byte_count
= params
+ 1 /* pad */ ;
4907 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4908 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4909 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4910 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
4911 pSMB
->DataCount
= 0;
4912 pSMB
->DataOffset
= 0;
4913 pSMB
->SetupCount
= 1;
4914 pSMB
->Reserved3
= 0;
4915 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
4916 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_ALLOCATION
);
4917 inc_rfc1001_len(pSMB
, byte_count
);
4918 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4920 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4921 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4923 cFYI(1, "Send error in QFSInfo = %d", rc
);
4924 } else { /* decode response */
4925 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4927 if (rc
|| get_bcc(&pSMBr
->hdr
) < 18)
4928 rc
= -EIO
; /* bad smb */
4930 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4931 cFYI(1, "qfsinf resp BCC: %d Offset %d",
4932 get_bcc(&pSMBr
->hdr
), data_offset
);
4934 response_data
= (FILE_SYSTEM_ALLOC_INFO
*)
4935 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
4937 le16_to_cpu(response_data
->BytesPerSector
) *
4938 le32_to_cpu(response_data
->
4939 SectorsPerAllocationUnit
);
4941 le32_to_cpu(response_data
->TotalAllocationUnits
);
4942 FSData
->f_bfree
= FSData
->f_bavail
=
4943 le32_to_cpu(response_data
->FreeAllocationUnits
);
4944 cFYI(1, "Blocks: %lld Free: %lld Block size %ld",
4945 (unsigned long long)FSData
->f_blocks
,
4946 (unsigned long long)FSData
->f_bfree
,
4950 cifs_buf_release(pSMB
);
4953 goto oldQFSInfoRetry
;
4959 CIFSSMBQFSInfo(const int xid
, struct cifs_tcon
*tcon
, struct kstatfs
*FSData
)
4961 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4962 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4963 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4964 FILE_SYSTEM_INFO
*response_data
;
4966 int bytes_returned
= 0;
4967 __u16 params
, byte_count
;
4969 cFYI(1, "In QFSInfo");
4971 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4976 params
= 2; /* level */
4977 pSMB
->TotalDataCount
= 0;
4978 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4979 pSMB
->MaxDataCount
= cpu_to_le16(1000);
4980 pSMB
->MaxSetupCount
= 0;
4984 pSMB
->Reserved2
= 0;
4985 byte_count
= params
+ 1 /* pad */ ;
4986 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4987 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4988 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4989 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
4990 pSMB
->DataCount
= 0;
4991 pSMB
->DataOffset
= 0;
4992 pSMB
->SetupCount
= 1;
4993 pSMB
->Reserved3
= 0;
4994 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
4995 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
4996 inc_rfc1001_len(pSMB
, byte_count
);
4997 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4999 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5000 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5002 cFYI(1, "Send error in QFSInfo = %d", rc
);
5003 } else { /* decode response */
5004 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5006 if (rc
|| get_bcc(&pSMBr
->hdr
) < 24)
5007 rc
= -EIO
; /* bad smb */
5009 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5013 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5016 le32_to_cpu(response_data
->BytesPerSector
) *
5017 le32_to_cpu(response_data
->
5018 SectorsPerAllocationUnit
);
5020 le64_to_cpu(response_data
->TotalAllocationUnits
);
5021 FSData
->f_bfree
= FSData
->f_bavail
=
5022 le64_to_cpu(response_data
->FreeAllocationUnits
);
5023 cFYI(1, "Blocks: %lld Free: %lld Block size %ld",
5024 (unsigned long long)FSData
->f_blocks
,
5025 (unsigned long long)FSData
->f_bfree
,
5029 cifs_buf_release(pSMB
);
5038 CIFSSMBQFSAttributeInfo(const int xid
, struct cifs_tcon
*tcon
)
5040 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5041 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5042 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5043 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
5045 int bytes_returned
= 0;
5046 __u16 params
, byte_count
;
5048 cFYI(1, "In QFSAttributeInfo");
5050 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5055 params
= 2; /* level */
5056 pSMB
->TotalDataCount
= 0;
5057 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5058 /* BB find exact max SMB PDU from sess structure BB */
5059 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5060 pSMB
->MaxSetupCount
= 0;
5064 pSMB
->Reserved2
= 0;
5065 byte_count
= params
+ 1 /* pad */ ;
5066 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5067 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5068 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5069 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5070 pSMB
->DataCount
= 0;
5071 pSMB
->DataOffset
= 0;
5072 pSMB
->SetupCount
= 1;
5073 pSMB
->Reserved3
= 0;
5074 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5075 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
5076 inc_rfc1001_len(pSMB
, byte_count
);
5077 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5079 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5080 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5082 cERROR(1, "Send error in QFSAttributeInfo = %d", rc
);
5083 } else { /* decode response */
5084 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5086 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5087 /* BB also check if enough bytes returned */
5088 rc
= -EIO
; /* bad smb */
5090 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5092 (FILE_SYSTEM_ATTRIBUTE_INFO
5093 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5095 memcpy(&tcon
->fsAttrInfo
, response_data
,
5096 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO
));
5099 cifs_buf_release(pSMB
);
5102 goto QFSAttributeRetry
;
5108 CIFSSMBQFSDeviceInfo(const int xid
, struct cifs_tcon
*tcon
)
5110 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5111 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5112 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5113 FILE_SYSTEM_DEVICE_INFO
*response_data
;
5115 int bytes_returned
= 0;
5116 __u16 params
, byte_count
;
5118 cFYI(1, "In QFSDeviceInfo");
5120 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5125 params
= 2; /* level */
5126 pSMB
->TotalDataCount
= 0;
5127 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5128 /* BB find exact max SMB PDU from sess structure BB */
5129 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5130 pSMB
->MaxSetupCount
= 0;
5134 pSMB
->Reserved2
= 0;
5135 byte_count
= params
+ 1 /* pad */ ;
5136 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5137 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5138 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5139 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5141 pSMB
->DataCount
= 0;
5142 pSMB
->DataOffset
= 0;
5143 pSMB
->SetupCount
= 1;
5144 pSMB
->Reserved3
= 0;
5145 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5146 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
5147 inc_rfc1001_len(pSMB
, byte_count
);
5148 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5150 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5151 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5153 cFYI(1, "Send error in QFSDeviceInfo = %d", rc
);
5154 } else { /* decode response */
5155 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5157 if (rc
|| get_bcc(&pSMBr
->hdr
) <
5158 sizeof(FILE_SYSTEM_DEVICE_INFO
))
5159 rc
= -EIO
; /* bad smb */
5161 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5163 (FILE_SYSTEM_DEVICE_INFO
*)
5164 (((char *) &pSMBr
->hdr
.Protocol
) +
5166 memcpy(&tcon
->fsDevInfo
, response_data
,
5167 sizeof(FILE_SYSTEM_DEVICE_INFO
));
5170 cifs_buf_release(pSMB
);
5173 goto QFSDeviceRetry
;
5179 CIFSSMBQFSUnixInfo(const int xid
, struct cifs_tcon
*tcon
)
5181 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5182 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5183 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5184 FILE_SYSTEM_UNIX_INFO
*response_data
;
5186 int bytes_returned
= 0;
5187 __u16 params
, byte_count
;
5189 cFYI(1, "In QFSUnixInfo");
5191 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5192 (void **) &pSMB
, (void **) &pSMBr
);
5196 params
= 2; /* level */
5197 pSMB
->TotalDataCount
= 0;
5198 pSMB
->DataCount
= 0;
5199 pSMB
->DataOffset
= 0;
5200 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5201 /* BB find exact max SMB PDU from sess structure BB */
5202 pSMB
->MaxDataCount
= cpu_to_le16(100);
5203 pSMB
->MaxSetupCount
= 0;
5207 pSMB
->Reserved2
= 0;
5208 byte_count
= params
+ 1 /* pad */ ;
5209 pSMB
->ParameterCount
= cpu_to_le16(params
);
5210 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5211 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5212 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5213 pSMB
->SetupCount
= 1;
5214 pSMB
->Reserved3
= 0;
5215 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5216 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
5217 inc_rfc1001_len(pSMB
, byte_count
);
5218 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5220 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5221 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5223 cERROR(1, "Send error in QFSUnixInfo = %d", rc
);
5224 } else { /* decode response */
5225 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5227 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5228 rc
= -EIO
; /* bad smb */
5230 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5232 (FILE_SYSTEM_UNIX_INFO
5233 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5235 memcpy(&tcon
->fsUnixInfo
, response_data
,
5236 sizeof(FILE_SYSTEM_UNIX_INFO
));
5239 cifs_buf_release(pSMB
);
5249 CIFSSMBSetFSUnixInfo(const int xid
, struct cifs_tcon
*tcon
, __u64 cap
)
5251 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5252 TRANSACTION2_SETFSI_REQ
*pSMB
= NULL
;
5253 TRANSACTION2_SETFSI_RSP
*pSMBr
= NULL
;
5255 int bytes_returned
= 0;
5256 __u16 params
, param_offset
, offset
, byte_count
;
5258 cFYI(1, "In SETFSUnixInfo");
5260 /* BB switch to small buf init to save memory */
5261 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5262 (void **) &pSMB
, (void **) &pSMBr
);
5266 params
= 4; /* 2 bytes zero followed by info level. */
5267 pSMB
->MaxSetupCount
= 0;
5271 pSMB
->Reserved2
= 0;
5272 param_offset
= offsetof(struct smb_com_transaction2_setfsi_req
, FileNum
)
5274 offset
= param_offset
+ params
;
5276 pSMB
->MaxParameterCount
= cpu_to_le16(4);
5277 /* BB find exact max SMB PDU from sess structure BB */
5278 pSMB
->MaxDataCount
= cpu_to_le16(100);
5279 pSMB
->SetupCount
= 1;
5280 pSMB
->Reserved3
= 0;
5281 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FS_INFORMATION
);
5282 byte_count
= 1 /* pad */ + params
+ 12;
5284 pSMB
->DataCount
= cpu_to_le16(12);
5285 pSMB
->ParameterCount
= cpu_to_le16(params
);
5286 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5287 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5288 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5289 pSMB
->DataOffset
= cpu_to_le16(offset
);
5293 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_CIFS_UNIX_INFO
);
5296 pSMB
->ClientUnixMajor
= cpu_to_le16(CIFS_UNIX_MAJOR_VERSION
);
5297 pSMB
->ClientUnixMinor
= cpu_to_le16(CIFS_UNIX_MINOR_VERSION
);
5298 pSMB
->ClientUnixCap
= cpu_to_le64(cap
);
5300 inc_rfc1001_len(pSMB
, byte_count
);
5301 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5303 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5304 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5306 cERROR(1, "Send error in SETFSUnixInfo = %d", rc
);
5307 } else { /* decode response */
5308 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5310 rc
= -EIO
; /* bad smb */
5312 cifs_buf_release(pSMB
);
5315 goto SETFSUnixRetry
;
5323 CIFSSMBQFSPosixInfo(const int xid
, struct cifs_tcon
*tcon
,
5324 struct kstatfs
*FSData
)
5326 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5327 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5328 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5329 FILE_SYSTEM_POSIX_INFO
*response_data
;
5331 int bytes_returned
= 0;
5332 __u16 params
, byte_count
;
5334 cFYI(1, "In QFSPosixInfo");
5336 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5341 params
= 2; /* level */
5342 pSMB
->TotalDataCount
= 0;
5343 pSMB
->DataCount
= 0;
5344 pSMB
->DataOffset
= 0;
5345 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5346 /* BB find exact max SMB PDU from sess structure BB */
5347 pSMB
->MaxDataCount
= cpu_to_le16(100);
5348 pSMB
->MaxSetupCount
= 0;
5352 pSMB
->Reserved2
= 0;
5353 byte_count
= params
+ 1 /* pad */ ;
5354 pSMB
->ParameterCount
= cpu_to_le16(params
);
5355 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5356 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5357 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5358 pSMB
->SetupCount
= 1;
5359 pSMB
->Reserved3
= 0;
5360 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5361 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_FS_INFO
);
5362 inc_rfc1001_len(pSMB
, byte_count
);
5363 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5365 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5366 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5368 cFYI(1, "Send error in QFSUnixInfo = %d", rc
);
5369 } else { /* decode response */
5370 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5372 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5373 rc
= -EIO
; /* bad smb */
5375 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5377 (FILE_SYSTEM_POSIX_INFO
5378 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5381 le32_to_cpu(response_data
->BlockSize
);
5383 le64_to_cpu(response_data
->TotalBlocks
);
5385 le64_to_cpu(response_data
->BlocksAvail
);
5386 if (response_data
->UserBlocksAvail
== cpu_to_le64(-1)) {
5387 FSData
->f_bavail
= FSData
->f_bfree
;
5390 le64_to_cpu(response_data
->UserBlocksAvail
);
5392 if (response_data
->TotalFileNodes
!= cpu_to_le64(-1))
5394 le64_to_cpu(response_data
->TotalFileNodes
);
5395 if (response_data
->FreeFileNodes
!= cpu_to_le64(-1))
5397 le64_to_cpu(response_data
->FreeFileNodes
);
5400 cifs_buf_release(pSMB
);
5409 /* We can not use write of zero bytes trick to
5410 set file size due to need for large file support. Also note that
5411 this SetPathInfo is preferred to SetFileInfo based method in next
5412 routine which is only needed to work around a sharing violation bug
5413 in Samba which this routine can run into */
5416 CIFSSMBSetEOF(const int xid
, struct cifs_tcon
*tcon
, const char *fileName
,
5417 __u64 size
, bool SetAllocation
,
5418 const struct nls_table
*nls_codepage
, int remap
)
5420 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5421 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5422 struct file_end_of_file_info
*parm_data
;
5425 int bytes_returned
= 0;
5426 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
5428 cFYI(1, "In SetEOF");
5430 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5435 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5437 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5438 PATH_MAX
, nls_codepage
, remap
);
5439 name_len
++; /* trailing null */
5441 } else { /* BB improve the check for buffer overruns BB */
5442 name_len
= strnlen(fileName
, PATH_MAX
);
5443 name_len
++; /* trailing null */
5444 strncpy(pSMB
->FileName
, fileName
, name_len
);
5446 params
= 6 + name_len
;
5447 data_count
= sizeof(struct file_end_of_file_info
);
5448 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5449 pSMB
->MaxDataCount
= cpu_to_le16(4100);
5450 pSMB
->MaxSetupCount
= 0;
5454 pSMB
->Reserved2
= 0;
5455 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5456 InformationLevel
) - 4;
5457 offset
= param_offset
+ params
;
5458 if (SetAllocation
) {
5459 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5460 pSMB
->InformationLevel
=
5461 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5463 pSMB
->InformationLevel
=
5464 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5465 } else /* Set File Size */ {
5466 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5467 pSMB
->InformationLevel
=
5468 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5470 pSMB
->InformationLevel
=
5471 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5475 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
5477 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5478 pSMB
->DataOffset
= cpu_to_le16(offset
);
5479 pSMB
->SetupCount
= 1;
5480 pSMB
->Reserved3
= 0;
5481 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5482 byte_count
= 3 /* pad */ + params
+ data_count
;
5483 pSMB
->DataCount
= cpu_to_le16(data_count
);
5484 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5485 pSMB
->ParameterCount
= cpu_to_le16(params
);
5486 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5487 pSMB
->Reserved4
= 0;
5488 inc_rfc1001_len(pSMB
, byte_count
);
5489 parm_data
->FileSize
= cpu_to_le64(size
);
5490 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5491 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5492 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5494 cFYI(1, "SetPathInfo (file size) returned %d", rc
);
5496 cifs_buf_release(pSMB
);
5505 CIFSSMBSetFileSize(const int xid
, struct cifs_tcon
*tcon
, __u64 size
,
5506 __u16 fid
, __u32 pid_of_opener
, bool SetAllocation
)
5508 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5509 struct file_end_of_file_info
*parm_data
;
5511 __u16 params
, param_offset
, offset
, byte_count
, count
;
5513 cFYI(1, "SetFileSize (via SetFileInfo) %lld",
5515 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5520 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5521 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5524 pSMB
->MaxSetupCount
= 0;
5528 pSMB
->Reserved2
= 0;
5529 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5530 offset
= param_offset
+ params
;
5532 count
= sizeof(struct file_end_of_file_info
);
5533 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5534 /* BB find exact max SMB PDU from sess structure BB */
5535 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5536 pSMB
->SetupCount
= 1;
5537 pSMB
->Reserved3
= 0;
5538 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5539 byte_count
= 3 /* pad */ + params
+ count
;
5540 pSMB
->DataCount
= cpu_to_le16(count
);
5541 pSMB
->ParameterCount
= cpu_to_le16(params
);
5542 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5543 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5544 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5546 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
)
5548 pSMB
->DataOffset
= cpu_to_le16(offset
);
5549 parm_data
->FileSize
= cpu_to_le64(size
);
5551 if (SetAllocation
) {
5552 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5553 pSMB
->InformationLevel
=
5554 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5556 pSMB
->InformationLevel
=
5557 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5558 } else /* Set File Size */ {
5559 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5560 pSMB
->InformationLevel
=
5561 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5563 pSMB
->InformationLevel
=
5564 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5566 pSMB
->Reserved4
= 0;
5567 inc_rfc1001_len(pSMB
, byte_count
);
5568 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5569 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5571 cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc
);
5574 /* Note: On -EAGAIN error only caller can retry on handle based calls
5575 since file handle passed in no longer valid */
5580 /* Some legacy servers such as NT4 require that the file times be set on
5581 an open handle, rather than by pathname - this is awkward due to
5582 potential access conflicts on the open, but it is unavoidable for these
5583 old servers since the only other choice is to go from 100 nanosecond DCE
5584 time and resort to the original setpathinfo level which takes the ancient
5585 DOS time format with 2 second granularity */
5587 CIFSSMBSetFileInfo(const int xid
, struct cifs_tcon
*tcon
,
5588 const FILE_BASIC_INFO
*data
, __u16 fid
, __u32 pid_of_opener
)
5590 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5593 __u16 params
, param_offset
, offset
, byte_count
, count
;
5595 cFYI(1, "Set Times (via SetFileInfo)");
5596 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5601 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5602 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5605 pSMB
->MaxSetupCount
= 0;
5609 pSMB
->Reserved2
= 0;
5610 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5611 offset
= param_offset
+ params
;
5613 data_offset
= (char *)pSMB
+
5614 offsetof(struct smb_hdr
, Protocol
) + offset
;
5616 count
= sizeof(FILE_BASIC_INFO
);
5617 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5618 /* BB find max SMB PDU from sess */
5619 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5620 pSMB
->SetupCount
= 1;
5621 pSMB
->Reserved3
= 0;
5622 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5623 byte_count
= 3 /* pad */ + params
+ count
;
5624 pSMB
->DataCount
= cpu_to_le16(count
);
5625 pSMB
->ParameterCount
= cpu_to_le16(params
);
5626 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5627 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5628 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5629 pSMB
->DataOffset
= cpu_to_le16(offset
);
5631 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5632 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5634 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5635 pSMB
->Reserved4
= 0;
5636 inc_rfc1001_len(pSMB
, byte_count
);
5637 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5638 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5639 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5641 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc
);
5643 /* Note: On -EAGAIN error only caller can retry on handle based calls
5644 since file handle passed in no longer valid */
5650 CIFSSMBSetFileDisposition(const int xid
, struct cifs_tcon
*tcon
,
5651 bool delete_file
, __u16 fid
, __u32 pid_of_opener
)
5653 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5656 __u16 params
, param_offset
, offset
, byte_count
, count
;
5658 cFYI(1, "Set File Disposition (via SetFileInfo)");
5659 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5664 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5665 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5668 pSMB
->MaxSetupCount
= 0;
5672 pSMB
->Reserved2
= 0;
5673 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5674 offset
= param_offset
+ params
;
5676 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5679 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5680 /* BB find max SMB PDU from sess */
5681 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5682 pSMB
->SetupCount
= 1;
5683 pSMB
->Reserved3
= 0;
5684 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5685 byte_count
= 3 /* pad */ + params
+ count
;
5686 pSMB
->DataCount
= cpu_to_le16(count
);
5687 pSMB
->ParameterCount
= cpu_to_le16(params
);
5688 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5689 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5690 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5691 pSMB
->DataOffset
= cpu_to_le16(offset
);
5693 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO
);
5694 pSMB
->Reserved4
= 0;
5695 inc_rfc1001_len(pSMB
, byte_count
);
5696 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5697 *data_offset
= delete_file
? 1 : 0;
5698 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5700 cFYI(1, "Send error in SetFileDisposition = %d", rc
);
5706 CIFSSMBSetPathInfo(const int xid
, struct cifs_tcon
*tcon
,
5707 const char *fileName
, const FILE_BASIC_INFO
*data
,
5708 const struct nls_table
*nls_codepage
, int remap
)
5710 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5711 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5714 int bytes_returned
= 0;
5716 __u16 params
, param_offset
, offset
, byte_count
, count
;
5718 cFYI(1, "In SetTimes");
5721 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5726 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5728 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5729 PATH_MAX
, nls_codepage
, remap
);
5730 name_len
++; /* trailing null */
5732 } else { /* BB improve the check for buffer overruns BB */
5733 name_len
= strnlen(fileName
, PATH_MAX
);
5734 name_len
++; /* trailing null */
5735 strncpy(pSMB
->FileName
, fileName
, name_len
);
5738 params
= 6 + name_len
;
5739 count
= sizeof(FILE_BASIC_INFO
);
5740 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5741 /* BB find max SMB PDU from sess structure BB */
5742 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5743 pSMB
->MaxSetupCount
= 0;
5747 pSMB
->Reserved2
= 0;
5748 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5749 InformationLevel
) - 4;
5750 offset
= param_offset
+ params
;
5751 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5752 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5753 pSMB
->DataOffset
= cpu_to_le16(offset
);
5754 pSMB
->SetupCount
= 1;
5755 pSMB
->Reserved3
= 0;
5756 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5757 byte_count
= 3 /* pad */ + params
+ count
;
5759 pSMB
->DataCount
= cpu_to_le16(count
);
5760 pSMB
->ParameterCount
= cpu_to_le16(params
);
5761 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5762 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5763 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5764 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5766 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5767 pSMB
->Reserved4
= 0;
5768 inc_rfc1001_len(pSMB
, byte_count
);
5769 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5770 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5771 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5772 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5774 cFYI(1, "SetPathInfo (times) returned %d", rc
);
5776 cifs_buf_release(pSMB
);
5784 /* Can not be used to set time stamps yet (due to old DOS time format) */
5785 /* Can be used to set attributes */
5786 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5787 handling it anyway and NT4 was what we thought it would be needed for
5788 Do not delete it until we prove whether needed for Win9x though */
5790 CIFSSMBSetAttrLegacy(int xid
, struct cifs_tcon
*tcon
, char *fileName
,
5791 __u16 dos_attrs
, const struct nls_table
*nls_codepage
)
5793 SETATTR_REQ
*pSMB
= NULL
;
5794 SETATTR_RSP
*pSMBr
= NULL
;
5799 cFYI(1, "In SetAttrLegacy");
5802 rc
= smb_init(SMB_COM_SETATTR
, 8, tcon
, (void **) &pSMB
,
5807 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5809 ConvertToUTF16((__le16
*) pSMB
->fileName
, fileName
,
5810 PATH_MAX
, nls_codepage
);
5811 name_len
++; /* trailing null */
5813 } else { /* BB improve the check for buffer overruns BB */
5814 name_len
= strnlen(fileName
, PATH_MAX
);
5815 name_len
++; /* trailing null */
5816 strncpy(pSMB
->fileName
, fileName
, name_len
);
5818 pSMB
->attr
= cpu_to_le16(dos_attrs
);
5819 pSMB
->BufferFormat
= 0x04;
5820 inc_rfc1001_len(pSMB
, name_len
+ 1);
5821 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
5822 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5823 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5825 cFYI(1, "Error in LegacySetAttr = %d", rc
);
5827 cifs_buf_release(pSMB
);
5830 goto SetAttrLgcyRetry
;
5834 #endif /* temporarily unneeded SetAttr legacy function */
5837 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO
*data_offset
,
5838 const struct cifs_unix_set_info_args
*args
)
5840 u64 mode
= args
->mode
;
5843 * Samba server ignores set of file size to zero due to bugs in some
5844 * older clients, but we should be precise - we use SetFileSize to
5845 * set file size and do not want to truncate file size to zero
5846 * accidentally as happened on one Samba server beta by putting
5847 * zero instead of -1 here
5849 data_offset
->EndOfFile
= cpu_to_le64(NO_CHANGE_64
);
5850 data_offset
->NumOfBytes
= cpu_to_le64(NO_CHANGE_64
);
5851 data_offset
->LastStatusChange
= cpu_to_le64(args
->ctime
);
5852 data_offset
->LastAccessTime
= cpu_to_le64(args
->atime
);
5853 data_offset
->LastModificationTime
= cpu_to_le64(args
->mtime
);
5854 data_offset
->Uid
= cpu_to_le64(args
->uid
);
5855 data_offset
->Gid
= cpu_to_le64(args
->gid
);
5856 /* better to leave device as zero when it is */
5857 data_offset
->DevMajor
= cpu_to_le64(MAJOR(args
->device
));
5858 data_offset
->DevMinor
= cpu_to_le64(MINOR(args
->device
));
5859 data_offset
->Permissions
= cpu_to_le64(mode
);
5862 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
5863 else if (S_ISDIR(mode
))
5864 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
5865 else if (S_ISLNK(mode
))
5866 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
5867 else if (S_ISCHR(mode
))
5868 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
5869 else if (S_ISBLK(mode
))
5870 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
5871 else if (S_ISFIFO(mode
))
5872 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
5873 else if (S_ISSOCK(mode
))
5874 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
5878 CIFSSMBUnixSetFileInfo(const int xid
, struct cifs_tcon
*tcon
,
5879 const struct cifs_unix_set_info_args
*args
,
5880 u16 fid
, u32 pid_of_opener
)
5882 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5885 u16 params
, param_offset
, offset
, byte_count
, count
;
5887 cFYI(1, "Set Unix Info (via SetFileInfo)");
5888 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5893 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5894 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5897 pSMB
->MaxSetupCount
= 0;
5901 pSMB
->Reserved2
= 0;
5902 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5903 offset
= param_offset
+ params
;
5905 data_offset
= (char *)pSMB
+
5906 offsetof(struct smb_hdr
, Protocol
) + offset
;
5908 count
= sizeof(FILE_UNIX_BASIC_INFO
);
5910 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5911 /* BB find max SMB PDU from sess */
5912 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5913 pSMB
->SetupCount
= 1;
5914 pSMB
->Reserved3
= 0;
5915 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5916 byte_count
= 3 /* pad */ + params
+ count
;
5917 pSMB
->DataCount
= cpu_to_le16(count
);
5918 pSMB
->ParameterCount
= cpu_to_le16(params
);
5919 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5920 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5921 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5922 pSMB
->DataOffset
= cpu_to_le16(offset
);
5924 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
5925 pSMB
->Reserved4
= 0;
5926 inc_rfc1001_len(pSMB
, byte_count
);
5927 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5929 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO
*)data_offset
, args
);
5931 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5933 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc
);
5935 /* Note: On -EAGAIN error only caller can retry on handle based calls
5936 since file handle passed in no longer valid */
5942 CIFSSMBUnixSetPathInfo(const int xid
, struct cifs_tcon
*tcon
, char *fileName
,
5943 const struct cifs_unix_set_info_args
*args
,
5944 const struct nls_table
*nls_codepage
, int remap
)
5946 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5947 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5950 int bytes_returned
= 0;
5951 FILE_UNIX_BASIC_INFO
*data_offset
;
5952 __u16 params
, param_offset
, offset
, count
, byte_count
;
5954 cFYI(1, "In SetUID/GID/Mode");
5956 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5961 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5963 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5964 PATH_MAX
, nls_codepage
, remap
);
5965 name_len
++; /* trailing null */
5967 } else { /* BB improve the check for buffer overruns BB */
5968 name_len
= strnlen(fileName
, PATH_MAX
);
5969 name_len
++; /* trailing null */
5970 strncpy(pSMB
->FileName
, fileName
, name_len
);
5973 params
= 6 + name_len
;
5974 count
= sizeof(FILE_UNIX_BASIC_INFO
);
5975 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5976 /* BB find max SMB PDU from sess structure BB */
5977 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5978 pSMB
->MaxSetupCount
= 0;
5982 pSMB
->Reserved2
= 0;
5983 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5984 InformationLevel
) - 4;
5985 offset
= param_offset
+ params
;
5987 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
5989 memset(data_offset
, 0, count
);
5990 pSMB
->DataOffset
= cpu_to_le16(offset
);
5991 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5992 pSMB
->SetupCount
= 1;
5993 pSMB
->Reserved3
= 0;
5994 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5995 byte_count
= 3 /* pad */ + params
+ count
;
5996 pSMB
->ParameterCount
= cpu_to_le16(params
);
5997 pSMB
->DataCount
= cpu_to_le16(count
);
5998 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5999 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6000 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6001 pSMB
->Reserved4
= 0;
6002 inc_rfc1001_len(pSMB
, byte_count
);
6004 cifs_fill_unix_set_info(data_offset
, args
);
6006 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6007 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6008 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6010 cFYI(1, "SetPathInfo (perms) returned %d", rc
);
6012 cifs_buf_release(pSMB
);
6018 #ifdef CONFIG_CIFS_XATTR
6020 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6021 * function used by listxattr and getxattr type calls. When ea_name is set,
6022 * it looks for that attribute name and stuffs that value into the EAData
6023 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6024 * buffer. In both cases, the return value is either the length of the
6025 * resulting data or a negative error code. If EAData is a NULL pointer then
6026 * the data isn't copied to it, but the length is returned.
6029 CIFSSMBQAllEAs(const int xid
, struct cifs_tcon
*tcon
,
6030 const unsigned char *searchName
, const unsigned char *ea_name
,
6031 char *EAData
, size_t buf_size
,
6032 const struct nls_table
*nls_codepage
, int remap
)
6034 /* BB assumes one setup word */
6035 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
6036 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
6040 struct fealist
*ea_response_data
;
6041 struct fea
*temp_fea
;
6044 __u16 params
, byte_count
, data_offset
;
6045 unsigned int ea_name_len
= ea_name
? strlen(ea_name
) : 0;
6047 cFYI(1, "In Query All EAs path %s", searchName
);
6049 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6054 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6056 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
6057 PATH_MAX
, nls_codepage
, remap
);
6058 list_len
++; /* trailing null */
6060 } else { /* BB improve the check for buffer overruns BB */
6061 list_len
= strnlen(searchName
, PATH_MAX
);
6062 list_len
++; /* trailing null */
6063 strncpy(pSMB
->FileName
, searchName
, list_len
);
6066 params
= 2 /* level */ + 4 /* reserved */ + list_len
/* includes NUL */;
6067 pSMB
->TotalDataCount
= 0;
6068 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6069 /* BB find exact max SMB PDU from sess structure BB */
6070 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
6071 pSMB
->MaxSetupCount
= 0;
6075 pSMB
->Reserved2
= 0;
6076 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
6077 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
6078 pSMB
->DataCount
= 0;
6079 pSMB
->DataOffset
= 0;
6080 pSMB
->SetupCount
= 1;
6081 pSMB
->Reserved3
= 0;
6082 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
6083 byte_count
= params
+ 1 /* pad */ ;
6084 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
6085 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6086 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
6087 pSMB
->Reserved4
= 0;
6088 inc_rfc1001_len(pSMB
, byte_count
);
6089 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6091 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6092 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6094 cFYI(1, "Send error in QueryAllEAs = %d", rc
);
6099 /* BB also check enough total bytes returned */
6100 /* BB we need to improve the validity checking
6101 of these trans2 responses */
6103 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
6104 if (rc
|| get_bcc(&pSMBr
->hdr
) < 4) {
6105 rc
= -EIO
; /* bad smb */
6109 /* check that length of list is not more than bcc */
6110 /* check that each entry does not go beyond length
6112 /* check that each element of each entry does not
6113 go beyond end of list */
6114 /* validate_trans2_offsets() */
6115 /* BB check if start of smb + data_offset > &bcc+ bcc */
6117 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
6118 ea_response_data
= (struct fealist
*)
6119 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
6121 list_len
= le32_to_cpu(ea_response_data
->list_len
);
6122 cFYI(1, "ea length %d", list_len
);
6123 if (list_len
<= 8) {
6124 cFYI(1, "empty EA list returned from server");
6128 /* make sure list_len doesn't go past end of SMB */
6129 end_of_smb
= (char *)pByteArea(&pSMBr
->hdr
) + get_bcc(&pSMBr
->hdr
);
6130 if ((char *)ea_response_data
+ list_len
> end_of_smb
) {
6131 cFYI(1, "EA list appears to go beyond SMB");
6136 /* account for ea list len */
6138 temp_fea
= ea_response_data
->list
;
6139 temp_ptr
= (char *)temp_fea
;
6140 while (list_len
> 0) {
6141 unsigned int name_len
;
6146 /* make sure we can read name_len and value_len */
6148 cFYI(1, "EA entry goes beyond length of list");
6153 name_len
= temp_fea
->name_len
;
6154 value_len
= le16_to_cpu(temp_fea
->value_len
);
6155 list_len
-= name_len
+ 1 + value_len
;
6157 cFYI(1, "EA entry goes beyond length of list");
6163 if (ea_name_len
== name_len
&&
6164 memcmp(ea_name
, temp_ptr
, name_len
) == 0) {
6165 temp_ptr
+= name_len
+ 1;
6169 if ((size_t)value_len
> buf_size
) {
6173 memcpy(EAData
, temp_ptr
, value_len
);
6177 /* account for prefix user. and trailing null */
6178 rc
+= (5 + 1 + name_len
);
6179 if (rc
< (int) buf_size
) {
6180 memcpy(EAData
, "user.", 5);
6182 memcpy(EAData
, temp_ptr
, name_len
);
6184 /* null terminate name */
6187 } else if (buf_size
== 0) {
6188 /* skip copy - calc size only */
6190 /* stop before overrun buffer */
6195 temp_ptr
+= name_len
+ 1 + value_len
;
6196 temp_fea
= (struct fea
*)temp_ptr
;
6199 /* didn't find the named attribute */
6204 cifs_buf_release(pSMB
);
6212 CIFSSMBSetEA(const int xid
, struct cifs_tcon
*tcon
, const char *fileName
,
6213 const char *ea_name
, const void *ea_value
,
6214 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
,
6217 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
6218 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
6219 struct fealist
*parm_data
;
6222 int bytes_returned
= 0;
6223 __u16 params
, param_offset
, byte_count
, offset
, count
;
6225 cFYI(1, "In SetEA");
6227 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6232 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6234 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
6235 PATH_MAX
, nls_codepage
, remap
);
6236 name_len
++; /* trailing null */
6238 } else { /* BB improve the check for buffer overruns BB */
6239 name_len
= strnlen(fileName
, PATH_MAX
);
6240 name_len
++; /* trailing null */
6241 strncpy(pSMB
->FileName
, fileName
, name_len
);
6244 params
= 6 + name_len
;
6246 /* done calculating parms using name_len of file name,
6247 now use name_len to calculate length of ea name
6248 we are going to create in the inode xattrs */
6249 if (ea_name
== NULL
)
6252 name_len
= strnlen(ea_name
, 255);
6254 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
;
6255 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6256 /* BB find max SMB PDU from sess */
6257 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6258 pSMB
->MaxSetupCount
= 0;
6262 pSMB
->Reserved2
= 0;
6263 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6264 InformationLevel
) - 4;
6265 offset
= param_offset
+ params
;
6266 pSMB
->InformationLevel
=
6267 cpu_to_le16(SMB_SET_FILE_EA
);
6270 (struct fealist
*) (((char *) &pSMB
->hdr
.Protocol
) +
6272 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6273 pSMB
->DataOffset
= cpu_to_le16(offset
);
6274 pSMB
->SetupCount
= 1;
6275 pSMB
->Reserved3
= 0;
6276 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6277 byte_count
= 3 /* pad */ + params
+ count
;
6278 pSMB
->DataCount
= cpu_to_le16(count
);
6279 parm_data
->list_len
= cpu_to_le32(count
);
6280 parm_data
->list
[0].EA_flags
= 0;
6281 /* we checked above that name len is less than 255 */
6282 parm_data
->list
[0].name_len
= (__u8
)name_len
;
6283 /* EA names are always ASCII */
6285 strncpy(parm_data
->list
[0].name
, ea_name
, name_len
);
6286 parm_data
->list
[0].name
[name_len
] = 0;
6287 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
6288 /* caller ensures that ea_value_len is less than 64K but
6289 we need to ensure that it fits within the smb */
6291 /*BB add length check to see if it would fit in
6292 negotiated SMB buffer size BB */
6293 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6295 memcpy(parm_data
->list
[0].name
+name_len
+1,
6296 ea_value
, ea_value_len
);
6298 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6299 pSMB
->ParameterCount
= cpu_to_le16(params
);
6300 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6301 pSMB
->Reserved4
= 0;
6302 inc_rfc1001_len(pSMB
, byte_count
);
6303 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6304 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6305 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6307 cFYI(1, "SetPathInfo (EA) returned %d", rc
);
6309 cifs_buf_release(pSMB
);
6318 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6320 * Years ago the kernel added a "dnotify" function for Samba server,
6321 * to allow network clients (such as Windows) to display updated
6322 * lists of files in directory listings automatically when
6323 * files are added by one user when another user has the
6324 * same directory open on their desktop. The Linux cifs kernel
6325 * client hooked into the kernel side of this interface for
6326 * the same reason, but ironically when the VFS moved from
6327 * "dnotify" to "inotify" it became harder to plug in Linux
6328 * network file system clients (the most obvious use case
6329 * for notify interfaces is when multiple users can update
6330 * the contents of the same directory - exactly what network
6331 * file systems can do) although the server (Samba) could
6332 * still use it. For the short term we leave the worker
6333 * function ifdeffed out (below) until inotify is fixed
6334 * in the VFS to make it easier to plug in network file
6335 * system clients. If inotify turns out to be permanently
6336 * incompatible for network fs clients, we could instead simply
6337 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6339 int CIFSSMBNotify(const int xid
, struct cifs_tcon
*tcon
,
6340 const int notify_subdirs
, const __u16 netfid
,
6341 __u32 filter
, struct file
*pfile
, int multishot
,
6342 const struct nls_table
*nls_codepage
)
6345 struct smb_com_transaction_change_notify_req
*pSMB
= NULL
;
6346 struct smb_com_ntransaction_change_notify_rsp
*pSMBr
= NULL
;
6347 struct dir_notify_req
*dnotify_req
;
6350 cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid
);
6351 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
6356 pSMB
->TotalParameterCount
= 0 ;
6357 pSMB
->TotalDataCount
= 0;
6358 pSMB
->MaxParameterCount
= cpu_to_le32(2);
6359 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
6360 pSMB
->MaxSetupCount
= 4;
6362 pSMB
->ParameterOffset
= 0;
6363 pSMB
->DataCount
= 0;
6364 pSMB
->DataOffset
= 0;
6365 pSMB
->SetupCount
= 4; /* single byte does not need le conversion */
6366 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE
);
6367 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6369 pSMB
->WatchTree
= 1; /* one byte - no le conversion needed */
6370 pSMB
->Reserved2
= 0;
6371 pSMB
->CompletionFilter
= cpu_to_le32(filter
);
6372 pSMB
->Fid
= netfid
; /* file handle always le */
6373 pSMB
->ByteCount
= 0;
6375 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6376 (struct smb_hdr
*)pSMBr
, &bytes_returned
,
6379 cFYI(1, "Error in Notify = %d", rc
);
6381 /* Add file to outstanding requests */
6382 /* BB change to kmem cache alloc */
6383 dnotify_req
= kmalloc(
6384 sizeof(struct dir_notify_req
),
6387 dnotify_req
->Pid
= pSMB
->hdr
.Pid
;
6388 dnotify_req
->PidHigh
= pSMB
->hdr
.PidHigh
;
6389 dnotify_req
->Mid
= pSMB
->hdr
.Mid
;
6390 dnotify_req
->Tid
= pSMB
->hdr
.Tid
;
6391 dnotify_req
->Uid
= pSMB
->hdr
.Uid
;
6392 dnotify_req
->netfid
= netfid
;
6393 dnotify_req
->pfile
= pfile
;
6394 dnotify_req
->filter
= filter
;
6395 dnotify_req
->multishot
= multishot
;
6396 spin_lock(&GlobalMid_Lock
);
6397 list_add_tail(&dnotify_req
->lhead
,
6398 &GlobalDnotifyReqList
);
6399 spin_unlock(&GlobalMid_Lock
);
6403 cifs_buf_release(pSMB
);
6406 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */