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 */
90 * Mark as invalid, all open files on tree connections since they
91 * were closed when session to server was lost.
94 cifs_mark_open_files_invalid(struct cifs_tcon
*tcon
)
96 struct cifsFileInfo
*open_file
= NULL
;
97 struct list_head
*tmp
;
98 struct list_head
*tmp1
;
100 /* list all files open on tree connection and mark them invalid */
101 spin_lock(&cifs_file_list_lock
);
102 list_for_each_safe(tmp
, tmp1
, &tcon
->openFileList
) {
103 open_file
= list_entry(tmp
, struct cifsFileInfo
, tlist
);
104 open_file
->invalidHandle
= true;
105 open_file
->oplock_break_cancelled
= true;
107 spin_unlock(&cifs_file_list_lock
);
109 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
114 /* reconnect the socket, tcon, and smb session if needed */
116 cifs_reconnect_tcon(struct cifs_tcon
*tcon
, int smb_command
)
119 struct cifs_ses
*ses
;
120 struct TCP_Server_Info
*server
;
121 struct nls_table
*nls_codepage
;
124 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
125 * tcp and smb session status done differently for those three - in the
132 server
= ses
->server
;
135 * only tree disconnect, open, and write, (and ulogoff which does not
136 * have tcon) are allowed as we start force umount
138 if (tcon
->tidStatus
== CifsExiting
) {
139 if (smb_command
!= SMB_COM_WRITE_ANDX
&&
140 smb_command
!= SMB_COM_OPEN_ANDX
&&
141 smb_command
!= SMB_COM_TREE_DISCONNECT
) {
142 cifs_dbg(FYI
, "can not send cmd %d while umounting\n",
149 * Give demultiplex thread up to 10 seconds to reconnect, should be
150 * greater than cifs socket timeout which is 7 seconds
152 while (server
->tcpStatus
== CifsNeedReconnect
) {
153 wait_event_interruptible_timeout(server
->response_q
,
154 (server
->tcpStatus
!= CifsNeedReconnect
), 10 * HZ
);
156 /* are we still trying to reconnect? */
157 if (server
->tcpStatus
!= CifsNeedReconnect
)
161 * on "soft" mounts we wait once. Hard mounts keep
162 * retrying until process is killed or server comes
166 cifs_dbg(FYI
, "gave up waiting on reconnect in smb_init\n");
171 if (!ses
->need_reconnect
&& !tcon
->need_reconnect
)
174 nls_codepage
= load_nls_default();
177 * need to prevent multiple threads trying to simultaneously
178 * reconnect the same SMB session
180 mutex_lock(&ses
->session_mutex
);
181 rc
= cifs_negotiate_protocol(0, ses
);
182 if (rc
== 0 && ses
->need_reconnect
)
183 rc
= cifs_setup_session(0, ses
, nls_codepage
);
185 /* do we need to reconnect tcon? */
186 if (rc
|| !tcon
->need_reconnect
) {
187 mutex_unlock(&ses
->session_mutex
);
191 cifs_mark_open_files_invalid(tcon
);
192 rc
= CIFSTCon(0, ses
, tcon
->treeName
, tcon
, nls_codepage
);
193 mutex_unlock(&ses
->session_mutex
);
194 cifs_dbg(FYI
, "reconnect tcon rc = %d\n", rc
);
200 * FIXME: check if wsize needs updated due to negotiated smb buffer
203 atomic_inc(&tconInfoReconnectCount
);
205 /* tell server Unix caps we support */
206 if (ses
->capabilities
& CAP_UNIX
)
207 reset_cifs_unix_caps(0, tcon
, NULL
, NULL
);
210 * Removed call to reopen open files here. It is safer (and faster) to
211 * reopen files one at a time as needed in read and write.
213 * FIXME: what about file locks? don't we need to reclaim them ASAP?
218 * Check if handle based operation so we know whether we can continue
219 * or not without returning to caller to reset file handle
221 switch (smb_command
) {
222 case SMB_COM_READ_ANDX
:
223 case SMB_COM_WRITE_ANDX
:
225 case SMB_COM_FIND_CLOSE2
:
226 case SMB_COM_LOCKING_ANDX
:
230 unload_nls(nls_codepage
);
234 /* Allocate and return pointer to an SMB request buffer, and set basic
235 SMB information in the SMB header. If the return code is zero, this
236 function must have filled in request_buf pointer */
238 small_smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
243 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
247 *request_buf
= cifs_small_buf_get();
248 if (*request_buf
== NULL
) {
249 /* BB should we add a retry in here if not a writepage? */
253 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
,
257 cifs_stats_inc(&tcon
->num_smbs_sent
);
263 small_smb_init_no_tc(const int smb_command
, const int wct
,
264 struct cifs_ses
*ses
, void **request_buf
)
267 struct smb_hdr
*buffer
;
269 rc
= small_smb_init(smb_command
, wct
, NULL
, request_buf
);
273 buffer
= (struct smb_hdr
*)*request_buf
;
274 buffer
->Mid
= get_next_mid(ses
->server
);
275 if (ses
->capabilities
& CAP_UNICODE
)
276 buffer
->Flags2
|= SMBFLG2_UNICODE
;
277 if (ses
->capabilities
& CAP_STATUS32
)
278 buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
280 /* uid, tid can stay at zero as set in header assemble */
282 /* BB add support for turning on the signing when
283 this function is used after 1st of session setup requests */
288 /* If the return code is zero, this function must fill in request_buf pointer */
290 __smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
291 void **request_buf
, void **response_buf
)
293 *request_buf
= cifs_buf_get();
294 if (*request_buf
== NULL
) {
295 /* BB should we add a retry in here if not a writepage? */
298 /* Although the original thought was we needed the response buf for */
299 /* potential retries of smb operations it turns out we can determine */
300 /* from the mid flags when the request buffer can be resent without */
301 /* having to use a second distinct buffer for the response */
303 *response_buf
= *request_buf
;
305 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
, tcon
,
309 cifs_stats_inc(&tcon
->num_smbs_sent
);
314 /* If the return code is zero, this function must fill in request_buf pointer */
316 smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
317 void **request_buf
, void **response_buf
)
321 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
325 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
329 smb_init_no_reconnect(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
330 void **request_buf
, void **response_buf
)
332 if (tcon
->ses
->need_reconnect
|| tcon
->need_reconnect
)
335 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
338 static int validate_t2(struct smb_t2_rsp
*pSMB
)
340 unsigned int total_size
;
342 /* check for plausible wct */
343 if (pSMB
->hdr
.WordCount
< 10)
346 /* check for parm and data offset going beyond end of smb */
347 if (get_unaligned_le16(&pSMB
->t2_rsp
.ParameterOffset
) > 1024 ||
348 get_unaligned_le16(&pSMB
->t2_rsp
.DataOffset
) > 1024)
351 total_size
= get_unaligned_le16(&pSMB
->t2_rsp
.ParameterCount
);
352 if (total_size
>= 512)
355 /* check that bcc is at least as big as parms + data, and that it is
356 * less than negotiated smb buffer
358 total_size
+= get_unaligned_le16(&pSMB
->t2_rsp
.DataCount
);
359 if (total_size
> get_bcc(&pSMB
->hdr
) ||
360 total_size
>= CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
)
365 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB
,
366 sizeof(struct smb_t2_rsp
) + 16);
371 CIFSSMBNegotiate(const unsigned int xid
, struct cifs_ses
*ses
)
374 NEGOTIATE_RSP
*pSMBr
;
378 struct TCP_Server_Info
*server
;
380 unsigned int secFlags
;
383 server
= ses
->server
;
388 rc
= smb_init(SMB_COM_NEGOTIATE
, 0, NULL
/* no tcon yet */ ,
389 (void **) &pSMB
, (void **) &pSMBr
);
393 /* if any of auth flags (ie not sign or seal) are overriden use them */
394 if (ses
->overrideSecFlg
& (~(CIFSSEC_MUST_SIGN
| CIFSSEC_MUST_SEAL
)))
395 secFlags
= ses
->overrideSecFlg
; /* BB FIXME fix sign flags? */
396 else /* if override flags set only sign/seal OR them with global auth */
397 secFlags
= global_secflags
| ses
->overrideSecFlg
;
399 cifs_dbg(FYI
, "secFlags 0x%x\n", secFlags
);
401 pSMB
->hdr
.Mid
= get_next_mid(server
);
402 pSMB
->hdr
.Flags2
|= (SMBFLG2_UNICODE
| SMBFLG2_ERR_STATUS
);
404 if ((secFlags
& CIFSSEC_MUST_KRB5
) == CIFSSEC_MUST_KRB5
)
405 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
406 else if ((secFlags
& CIFSSEC_AUTH_MASK
) == CIFSSEC_MAY_KRB5
) {
407 cifs_dbg(FYI
, "Kerberos only mechanism, enable extended security\n");
408 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
409 } else if ((secFlags
& CIFSSEC_MUST_NTLMSSP
) == CIFSSEC_MUST_NTLMSSP
)
410 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
411 else if ((secFlags
& CIFSSEC_AUTH_MASK
) == CIFSSEC_MAY_NTLMSSP
) {
412 cifs_dbg(FYI
, "NTLMSSP only mechanism, enable extended security\n");
413 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
417 for (i
= 0; i
< CIFS_NUM_PROT
; i
++) {
418 strncpy(pSMB
->DialectsArray
+count
, protocols
[i
].name
, 16);
419 count
+= strlen(protocols
[i
].name
) + 1;
420 /* null at end of source and target buffers anyway */
422 inc_rfc1001_len(pSMB
, count
);
423 pSMB
->ByteCount
= cpu_to_le16(count
);
425 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
426 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
430 server
->dialect
= le16_to_cpu(pSMBr
->DialectIndex
);
431 cifs_dbg(FYI
, "Dialect: %d\n", server
->dialect
);
432 /* Check wct = 1 error case */
433 if ((pSMBr
->hdr
.WordCount
< 13) || (server
->dialect
== BAD_PROT
)) {
434 /* core returns wct = 1, but we do not ask for core - otherwise
435 small wct just comes when dialect index is -1 indicating we
436 could not negotiate a common dialect */
439 #ifdef CONFIG_CIFS_WEAK_PW_HASH
440 } else if ((pSMBr
->hdr
.WordCount
== 13)
441 && ((server
->dialect
== LANMAN_PROT
)
442 || (server
->dialect
== LANMAN2_PROT
))) {
444 struct lanman_neg_rsp
*rsp
= (struct lanman_neg_rsp
*)pSMBr
;
446 if ((secFlags
& CIFSSEC_MAY_LANMAN
) ||
447 (secFlags
& CIFSSEC_MAY_PLNTXT
))
448 server
->secType
= LANMAN
;
450 cifs_dbg(VFS
, "mount failed weak security disabled in /proc/fs/cifs/SecurityFlags\n");
454 server
->sec_mode
= le16_to_cpu(rsp
->SecurityMode
);
455 server
->maxReq
= min_t(unsigned int,
456 le16_to_cpu(rsp
->MaxMpxCount
),
458 set_credits(server
, server
->maxReq
);
459 server
->maxBuf
= le16_to_cpu(rsp
->MaxBufSize
);
460 server
->max_vcs
= le16_to_cpu(rsp
->MaxNumberVcs
);
461 /* even though we do not use raw we might as well set this
462 accurately, in case we ever find a need for it */
463 if ((le16_to_cpu(rsp
->RawMode
) & RAW_ENABLE
) == RAW_ENABLE
) {
464 server
->max_rw
= 0xFF00;
465 server
->capabilities
= CAP_MPX_MODE
| CAP_RAW_MODE
;
467 server
->max_rw
= 0;/* do not need to use raw anyway */
468 server
->capabilities
= CAP_MPX_MODE
;
470 tmp
= (__s16
)le16_to_cpu(rsp
->ServerTimeZone
);
472 /* OS/2 often does not set timezone therefore
473 * we must use server time to calc time zone.
474 * Could deviate slightly from the right zone.
475 * Smallest defined timezone difference is 15 minutes
476 * (i.e. Nepal). Rounding up/down is done to match
479 int val
, seconds
, remain
, result
;
480 struct timespec ts
, utc
;
482 ts
= cnvrtDosUnixTm(rsp
->SrvTime
.Date
,
483 rsp
->SrvTime
.Time
, 0);
484 cifs_dbg(FYI
, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
485 (int)ts
.tv_sec
, (int)utc
.tv_sec
,
486 (int)(utc
.tv_sec
- ts
.tv_sec
));
487 val
= (int)(utc
.tv_sec
- ts
.tv_sec
);
489 result
= (seconds
/ MIN_TZ_ADJ
) * MIN_TZ_ADJ
;
490 remain
= seconds
% MIN_TZ_ADJ
;
491 if (remain
>= (MIN_TZ_ADJ
/ 2))
492 result
+= MIN_TZ_ADJ
;
495 server
->timeAdj
= result
;
497 server
->timeAdj
= (int)tmp
;
498 server
->timeAdj
*= 60; /* also in seconds */
500 cifs_dbg(FYI
, "server->timeAdj: %d seconds\n", server
->timeAdj
);
503 /* BB get server time for time conversions and add
504 code to use it and timezone since this is not UTC */
506 if (rsp
->EncryptionKeyLength
==
507 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE
)) {
508 memcpy(ses
->server
->cryptkey
, rsp
->EncryptionKey
,
509 CIFS_CRYPTO_KEY_SIZE
);
510 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
511 rc
= -EIO
; /* need cryptkey unless plain text */
515 cifs_dbg(FYI
, "LANMAN negotiated\n");
516 /* we will not end up setting signing flags - as no signing
517 was in LANMAN and server did not return the flags on */
519 #else /* weak security disabled */
520 } else if (pSMBr
->hdr
.WordCount
== 13) {
521 cifs_dbg(VFS
, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
523 #endif /* WEAK_PW_HASH */
525 } else if (pSMBr
->hdr
.WordCount
!= 17) {
530 /* else wct == 17 NTLM */
531 server
->sec_mode
= pSMBr
->SecurityMode
;
532 if ((server
->sec_mode
& SECMODE_USER
) == 0)
533 cifs_dbg(FYI
, "share mode security\n");
535 if ((server
->sec_mode
& SECMODE_PW_ENCRYPT
) == 0)
536 #ifdef CONFIG_CIFS_WEAK_PW_HASH
537 if ((secFlags
& CIFSSEC_MAY_PLNTXT
) == 0)
538 #endif /* CIFS_WEAK_PW_HASH */
539 cifs_dbg(VFS
, "Server requests plain text password but client support disabled\n");
541 if ((secFlags
& CIFSSEC_MUST_NTLMV2
) == CIFSSEC_MUST_NTLMV2
)
542 server
->secType
= NTLMv2
;
543 else if (secFlags
& CIFSSEC_MAY_NTLM
)
544 server
->secType
= NTLM
;
545 else if (secFlags
& CIFSSEC_MAY_NTLMV2
)
546 server
->secType
= NTLMv2
;
547 else if (secFlags
& CIFSSEC_MAY_KRB5
)
548 server
->secType
= Kerberos
;
549 else if (secFlags
& CIFSSEC_MAY_NTLMSSP
)
550 server
->secType
= RawNTLMSSP
;
551 else if (secFlags
& CIFSSEC_MAY_LANMAN
)
552 server
->secType
= LANMAN
;
555 cifs_dbg(VFS
, "Invalid security type\n");
558 /* else ... any others ...? */
560 /* one byte, so no need to convert this or EncryptionKeyLen from
562 server
->maxReq
= min_t(unsigned int, le16_to_cpu(pSMBr
->MaxMpxCount
),
564 set_credits(server
, server
->maxReq
);
565 /* probably no need to store and check maxvcs */
566 server
->maxBuf
= le32_to_cpu(pSMBr
->MaxBufferSize
);
567 server
->max_rw
= le32_to_cpu(pSMBr
->MaxRawSize
);
568 cifs_dbg(NOISY
, "Max buf = %d\n", ses
->server
->maxBuf
);
569 server
->capabilities
= le32_to_cpu(pSMBr
->Capabilities
);
570 server
->timeAdj
= (int)(__s16
)le16_to_cpu(pSMBr
->ServerTimeZone
);
571 server
->timeAdj
*= 60;
572 if (pSMBr
->EncryptionKeyLength
== CIFS_CRYPTO_KEY_SIZE
) {
573 memcpy(ses
->server
->cryptkey
, pSMBr
->u
.EncryptionKey
,
574 CIFS_CRYPTO_KEY_SIZE
);
575 } else if ((pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
||
576 server
->capabilities
& CAP_EXTENDED_SECURITY
) &&
577 (pSMBr
->EncryptionKeyLength
== 0)) {
578 /* decode security blob */
579 count
= get_bcc(&pSMBr
->hdr
);
584 spin_lock(&cifs_tcp_ses_lock
);
585 if (server
->srv_count
> 1) {
586 spin_unlock(&cifs_tcp_ses_lock
);
587 if (memcmp(server
->server_GUID
,
588 pSMBr
->u
.extended_response
.
590 cifs_dbg(FYI
, "server UID changed\n");
591 memcpy(server
->server_GUID
,
592 pSMBr
->u
.extended_response
.GUID
,
596 spin_unlock(&cifs_tcp_ses_lock
);
597 memcpy(server
->server_GUID
,
598 pSMBr
->u
.extended_response
.GUID
, 16);
602 server
->secType
= RawNTLMSSP
;
604 rc
= decode_negTokenInit(pSMBr
->u
.extended_response
.
605 SecurityBlob
, count
- 16,
611 if (server
->secType
== Kerberos
) {
612 if (!server
->sec_kerberos
&&
613 !server
->sec_mskerberos
)
615 } else if (server
->secType
== RawNTLMSSP
) {
616 if (!server
->sec_ntlmssp
)
621 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
622 rc
= -EIO
; /* no crypt key only if plain text pwd */
625 server
->capabilities
&= ~CAP_EXTENDED_SECURITY
;
627 #ifdef CONFIG_CIFS_WEAK_PW_HASH
630 if ((secFlags
& CIFSSEC_MAY_SIGN
) == 0) {
631 /* MUST_SIGN already includes the MAY_SIGN FLAG
632 so if this is zero it means that signing is disabled */
633 cifs_dbg(FYI
, "Signing disabled\n");
634 if (server
->sec_mode
& SECMODE_SIGN_REQUIRED
) {
635 cifs_dbg(VFS
, "Server requires packet signing to be enabled in /proc/fs/cifs/SecurityFlags\n");
639 ~(SECMODE_SIGN_ENABLED
| SECMODE_SIGN_REQUIRED
);
640 } else if ((secFlags
& CIFSSEC_MUST_SIGN
) == CIFSSEC_MUST_SIGN
) {
641 /* signing required */
642 cifs_dbg(FYI
, "Must sign - secFlags 0x%x\n", secFlags
);
643 if ((server
->sec_mode
&
644 (SECMODE_SIGN_ENABLED
| SECMODE_SIGN_REQUIRED
)) == 0) {
645 cifs_dbg(VFS
, "signing required but server lacks support\n");
648 server
->sec_mode
|= SECMODE_SIGN_REQUIRED
;
650 /* signing optional ie CIFSSEC_MAY_SIGN */
651 if ((server
->sec_mode
& SECMODE_SIGN_REQUIRED
) == 0)
653 ~(SECMODE_SIGN_ENABLED
| SECMODE_SIGN_REQUIRED
);
657 cifs_buf_release(pSMB
);
659 cifs_dbg(FYI
, "negprot rc %d\n", rc
);
664 CIFSSMBTDis(const unsigned int xid
, struct cifs_tcon
*tcon
)
666 struct smb_hdr
*smb_buffer
;
669 cifs_dbg(FYI
, "In tree disconnect\n");
671 /* BB: do we need to check this? These should never be NULL. */
672 if ((tcon
->ses
== NULL
) || (tcon
->ses
->server
== NULL
))
676 * No need to return error on this operation if tid invalidated and
677 * closed on server already e.g. due to tcp session crashing. Also,
678 * the tcon is no longer on the list, so no need to take lock before
681 if ((tcon
->need_reconnect
) || (tcon
->ses
->need_reconnect
))
684 rc
= small_smb_init(SMB_COM_TREE_DISCONNECT
, 0, tcon
,
685 (void **)&smb_buffer
);
689 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)smb_buffer
, 0);
691 cifs_dbg(FYI
, "Tree disconnect failed %d\n", rc
);
693 /* No need to return error on this operation if tid invalidated and
694 closed on server already e.g. due to tcp session crashing */
702 * This is a no-op for now. We're not really interested in the reply, but
703 * rather in the fact that the server sent one and that server->lstrp
706 * FIXME: maybe we should consider checking that the reply matches request?
709 cifs_echo_callback(struct mid_q_entry
*mid
)
711 struct TCP_Server_Info
*server
= mid
->callback_data
;
713 DeleteMidQEntry(mid
);
714 add_credits(server
, 1, CIFS_ECHO_OP
);
718 CIFSSMBEcho(struct TCP_Server_Info
*server
)
723 struct smb_rqst rqst
= { .rq_iov
= &iov
,
726 cifs_dbg(FYI
, "In echo request\n");
728 rc
= small_smb_init(SMB_COM_ECHO
, 0, NULL
, (void **)&smb
);
732 /* set up echo request */
733 smb
->hdr
.Tid
= 0xffff;
734 smb
->hdr
.WordCount
= 1;
735 put_unaligned_le16(1, &smb
->EchoCount
);
736 put_bcc(1, &smb
->hdr
);
738 inc_rfc1001_len(smb
, 3);
740 iov
.iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4;
742 rc
= cifs_call_async(server
, &rqst
, NULL
, cifs_echo_callback
,
743 server
, CIFS_ASYNC_OP
| CIFS_ECHO_OP
);
745 cifs_dbg(FYI
, "Echo request failed: %d\n", rc
);
747 cifs_small_buf_release(smb
);
753 CIFSSMBLogoff(const unsigned int xid
, struct cifs_ses
*ses
)
755 LOGOFF_ANDX_REQ
*pSMB
;
758 cifs_dbg(FYI
, "In SMBLogoff for session disconnect\n");
761 * BB: do we need to check validity of ses and server? They should
762 * always be valid since we have an active reference. If not, that
763 * should probably be a BUG()
765 if (!ses
|| !ses
->server
)
768 mutex_lock(&ses
->session_mutex
);
769 if (ses
->need_reconnect
)
770 goto session_already_dead
; /* no need to send SMBlogoff if uid
771 already closed due to reconnect */
772 rc
= small_smb_init(SMB_COM_LOGOFF_ANDX
, 2, NULL
, (void **)&pSMB
);
774 mutex_unlock(&ses
->session_mutex
);
778 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
780 if (ses
->server
->sec_mode
&
781 (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
))
782 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
784 pSMB
->hdr
.Uid
= ses
->Suid
;
786 pSMB
->AndXCommand
= 0xFF;
787 rc
= SendReceiveNoRsp(xid
, ses
, (char *) pSMB
, 0);
788 session_already_dead
:
789 mutex_unlock(&ses
->session_mutex
);
791 /* if session dead then we do not need to do ulogoff,
792 since server closed smb session, no sense reporting
800 CIFSPOSIXDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
,
801 const char *fileName
, __u16 type
,
802 const struct nls_table
*nls_codepage
, int remap
)
804 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
805 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
806 struct unlink_psx_rq
*pRqD
;
809 int bytes_returned
= 0;
810 __u16 params
, param_offset
, offset
, byte_count
;
812 cifs_dbg(FYI
, "In POSIX delete\n");
814 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
819 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
821 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
822 PATH_MAX
, nls_codepage
, remap
);
823 name_len
++; /* trailing null */
825 } else { /* BB add path length overrun check */
826 name_len
= strnlen(fileName
, PATH_MAX
);
827 name_len
++; /* trailing null */
828 strncpy(pSMB
->FileName
, fileName
, name_len
);
831 params
= 6 + name_len
;
832 pSMB
->MaxParameterCount
= cpu_to_le16(2);
833 pSMB
->MaxDataCount
= 0; /* BB double check this with jra */
834 pSMB
->MaxSetupCount
= 0;
839 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
840 InformationLevel
) - 4;
841 offset
= param_offset
+ params
;
843 /* Setup pointer to Request Data (inode type) */
844 pRqD
= (struct unlink_psx_rq
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
845 pRqD
->type
= cpu_to_le16(type
);
846 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
847 pSMB
->DataOffset
= cpu_to_le16(offset
);
848 pSMB
->SetupCount
= 1;
850 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
851 byte_count
= 3 /* pad */ + params
+ sizeof(struct unlink_psx_rq
);
853 pSMB
->DataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
854 pSMB
->TotalDataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
855 pSMB
->ParameterCount
= cpu_to_le16(params
);
856 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
857 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_UNLINK
);
859 inc_rfc1001_len(pSMB
, byte_count
);
860 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
861 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
862 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
864 cifs_dbg(FYI
, "Posix delete returned %d\n", rc
);
865 cifs_buf_release(pSMB
);
867 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
876 CIFSSMBDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
877 struct cifs_sb_info
*cifs_sb
)
879 DELETE_FILE_REQ
*pSMB
= NULL
;
880 DELETE_FILE_RSP
*pSMBr
= NULL
;
884 int remap
= cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
;
887 rc
= smb_init(SMB_COM_DELETE
, 1, tcon
, (void **) &pSMB
,
892 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
893 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->fileName
, name
,
894 PATH_MAX
, cifs_sb
->local_nls
,
896 name_len
++; /* trailing null */
898 } else { /* BB improve check for buffer overruns BB */
899 name_len
= strnlen(name
, PATH_MAX
);
900 name_len
++; /* trailing null */
901 strncpy(pSMB
->fileName
, name
, name_len
);
903 pSMB
->SearchAttributes
=
904 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
);
905 pSMB
->BufferFormat
= 0x04;
906 inc_rfc1001_len(pSMB
, name_len
+ 1);
907 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
908 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
909 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
910 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
912 cifs_dbg(FYI
, "Error in RMFile = %d\n", rc
);
914 cifs_buf_release(pSMB
);
922 CIFSSMBRmDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
923 struct cifs_sb_info
*cifs_sb
)
925 DELETE_DIRECTORY_REQ
*pSMB
= NULL
;
926 DELETE_DIRECTORY_RSP
*pSMBr
= NULL
;
930 int remap
= cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
;
932 cifs_dbg(FYI
, "In CIFSSMBRmDir\n");
934 rc
= smb_init(SMB_COM_DELETE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
939 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
940 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
941 PATH_MAX
, cifs_sb
->local_nls
,
943 name_len
++; /* trailing null */
945 } else { /* BB improve check for buffer overruns BB */
946 name_len
= strnlen(name
, PATH_MAX
);
947 name_len
++; /* trailing null */
948 strncpy(pSMB
->DirName
, name
, name_len
);
951 pSMB
->BufferFormat
= 0x04;
952 inc_rfc1001_len(pSMB
, name_len
+ 1);
953 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
954 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
955 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
956 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_rmdirs
);
958 cifs_dbg(FYI
, "Error in RMDir = %d\n", rc
);
960 cifs_buf_release(pSMB
);
967 CIFSSMBMkDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
968 struct cifs_sb_info
*cifs_sb
)
971 CREATE_DIRECTORY_REQ
*pSMB
= NULL
;
972 CREATE_DIRECTORY_RSP
*pSMBr
= NULL
;
975 int remap
= cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
;
977 cifs_dbg(FYI
, "In CIFSSMBMkDir\n");
979 rc
= smb_init(SMB_COM_CREATE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
984 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
985 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
986 PATH_MAX
, cifs_sb
->local_nls
,
988 name_len
++; /* trailing null */
990 } else { /* BB improve check for buffer overruns BB */
991 name_len
= strnlen(name
, PATH_MAX
);
992 name_len
++; /* trailing null */
993 strncpy(pSMB
->DirName
, name
, name_len
);
996 pSMB
->BufferFormat
= 0x04;
997 inc_rfc1001_len(pSMB
, name_len
+ 1);
998 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
999 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1000 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1001 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_mkdirs
);
1003 cifs_dbg(FYI
, "Error in Mkdir = %d\n", rc
);
1005 cifs_buf_release(pSMB
);
1012 CIFSPOSIXCreate(const unsigned int xid
, struct cifs_tcon
*tcon
,
1013 __u32 posix_flags
, __u64 mode
, __u16
*netfid
,
1014 FILE_UNIX_BASIC_INFO
*pRetData
, __u32
*pOplock
,
1015 const char *name
, const struct nls_table
*nls_codepage
,
1018 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
1019 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
1022 int bytes_returned
= 0;
1023 __u16 params
, param_offset
, offset
, byte_count
, count
;
1024 OPEN_PSX_REQ
*pdata
;
1025 OPEN_PSX_RSP
*psx_rsp
;
1027 cifs_dbg(FYI
, "In POSIX Create\n");
1029 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1034 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1036 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, name
,
1037 PATH_MAX
, nls_codepage
, remap
);
1038 name_len
++; /* trailing null */
1040 } else { /* BB improve the check for buffer overruns BB */
1041 name_len
= strnlen(name
, PATH_MAX
);
1042 name_len
++; /* trailing null */
1043 strncpy(pSMB
->FileName
, name
, name_len
);
1046 params
= 6 + name_len
;
1047 count
= sizeof(OPEN_PSX_REQ
);
1048 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1049 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* large enough */
1050 pSMB
->MaxSetupCount
= 0;
1054 pSMB
->Reserved2
= 0;
1055 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
1056 InformationLevel
) - 4;
1057 offset
= param_offset
+ params
;
1058 pdata
= (OPEN_PSX_REQ
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
1059 pdata
->Level
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
1060 pdata
->Permissions
= cpu_to_le64(mode
);
1061 pdata
->PosixOpenFlags
= cpu_to_le32(posix_flags
);
1062 pdata
->OpenFlags
= cpu_to_le32(*pOplock
);
1063 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
1064 pSMB
->DataOffset
= cpu_to_le16(offset
);
1065 pSMB
->SetupCount
= 1;
1066 pSMB
->Reserved3
= 0;
1067 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
1068 byte_count
= 3 /* pad */ + params
+ count
;
1070 pSMB
->DataCount
= cpu_to_le16(count
);
1071 pSMB
->ParameterCount
= cpu_to_le16(params
);
1072 pSMB
->TotalDataCount
= pSMB
->DataCount
;
1073 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1074 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_OPEN
);
1075 pSMB
->Reserved4
= 0;
1076 inc_rfc1001_len(pSMB
, byte_count
);
1077 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1078 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1079 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1081 cifs_dbg(FYI
, "Posix create returned %d\n", rc
);
1082 goto psx_create_err
;
1085 cifs_dbg(FYI
, "copying inode info\n");
1086 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
1088 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)) {
1089 rc
= -EIO
; /* bad smb */
1090 goto psx_create_err
;
1093 /* copy return information to pRetData */
1094 psx_rsp
= (OPEN_PSX_RSP
*)((char *) &pSMBr
->hdr
.Protocol
1095 + le16_to_cpu(pSMBr
->t2
.DataOffset
));
1097 *pOplock
= le16_to_cpu(psx_rsp
->OplockFlags
);
1099 *netfid
= psx_rsp
->Fid
; /* cifs fid stays in le */
1100 /* Let caller know file was created so we can set the mode. */
1101 /* Do we care about the CreateAction in any other cases? */
1102 if (cpu_to_le32(FILE_CREATE
) == psx_rsp
->CreateAction
)
1103 *pOplock
|= CIFS_CREATE_ACTION
;
1104 /* check to make sure response data is there */
1105 if (psx_rsp
->ReturnedLevel
!= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
)) {
1106 pRetData
->Type
= cpu_to_le32(-1); /* unknown */
1107 cifs_dbg(NOISY
, "unknown type\n");
1109 if (get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)
1110 + sizeof(FILE_UNIX_BASIC_INFO
)) {
1111 cifs_dbg(VFS
, "Open response data too small\n");
1112 pRetData
->Type
= cpu_to_le32(-1);
1113 goto psx_create_err
;
1115 memcpy((char *) pRetData
,
1116 (char *)psx_rsp
+ sizeof(OPEN_PSX_RSP
),
1117 sizeof(FILE_UNIX_BASIC_INFO
));
1121 cifs_buf_release(pSMB
);
1123 if (posix_flags
& SMB_O_DIRECTORY
)
1124 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixmkdirs
);
1126 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixopens
);
1134 static __u16
convert_disposition(int disposition
)
1138 switch (disposition
) {
1139 case FILE_SUPERSEDE
:
1140 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1143 ofun
= SMBOPEN_OAPPEND
;
1146 ofun
= SMBOPEN_OCREATE
;
1149 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OAPPEND
;
1151 case FILE_OVERWRITE
:
1152 ofun
= SMBOPEN_OTRUNC
;
1154 case FILE_OVERWRITE_IF
:
1155 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1158 cifs_dbg(FYI
, "unknown disposition %d\n", disposition
);
1159 ofun
= SMBOPEN_OAPPEND
; /* regular open */
1165 access_flags_to_smbopen_mode(const int access_flags
)
1167 int masked_flags
= access_flags
& (GENERIC_READ
| GENERIC_WRITE
);
1169 if (masked_flags
== GENERIC_READ
)
1170 return SMBOPEN_READ
;
1171 else if (masked_flags
== GENERIC_WRITE
)
1172 return SMBOPEN_WRITE
;
1174 /* just go for read/write */
1175 return SMBOPEN_READWRITE
;
1179 SMBLegacyOpen(const unsigned int xid
, struct cifs_tcon
*tcon
,
1180 const char *fileName
, const int openDisposition
,
1181 const int access_flags
, const int create_options
, __u16
*netfid
,
1182 int *pOplock
, FILE_ALL_INFO
*pfile_info
,
1183 const struct nls_table
*nls_codepage
, int remap
)
1186 OPENX_REQ
*pSMB
= NULL
;
1187 OPENX_RSP
*pSMBr
= NULL
;
1193 rc
= smb_init(SMB_COM_OPEN_ANDX
, 15, tcon
, (void **) &pSMB
,
1198 pSMB
->AndXCommand
= 0xFF; /* none */
1200 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1201 count
= 1; /* account for one byte pad to word boundary */
1203 cifsConvertToUTF16((__le16
*) (pSMB
->fileName
+ 1),
1204 fileName
, PATH_MAX
, nls_codepage
, remap
);
1205 name_len
++; /* trailing null */
1207 } else { /* BB improve check for buffer overruns BB */
1208 count
= 0; /* no pad */
1209 name_len
= strnlen(fileName
, PATH_MAX
);
1210 name_len
++; /* trailing null */
1211 strncpy(pSMB
->fileName
, fileName
, name_len
);
1213 if (*pOplock
& REQ_OPLOCK
)
1214 pSMB
->OpenFlags
= cpu_to_le16(REQ_OPLOCK
);
1215 else if (*pOplock
& REQ_BATCHOPLOCK
)
1216 pSMB
->OpenFlags
= cpu_to_le16(REQ_BATCHOPLOCK
);
1218 pSMB
->OpenFlags
|= cpu_to_le16(REQ_MORE_INFO
);
1219 pSMB
->Mode
= cpu_to_le16(access_flags_to_smbopen_mode(access_flags
));
1220 pSMB
->Mode
|= cpu_to_le16(0x40); /* deny none */
1221 /* set file as system file if special file such
1222 as fifo and server expecting SFU style and
1223 no Unix extensions */
1225 if (create_options
& CREATE_OPTION_SPECIAL
)
1226 pSMB
->FileAttributes
= cpu_to_le16(ATTR_SYSTEM
);
1227 else /* BB FIXME BB */
1228 pSMB
->FileAttributes
= cpu_to_le16(0/*ATTR_NORMAL*/);
1230 if (create_options
& CREATE_OPTION_READONLY
)
1231 pSMB
->FileAttributes
|= cpu_to_le16(ATTR_READONLY
);
1234 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1235 CREATE_OPTIONS_MASK); */
1236 /* BB FIXME END BB */
1238 pSMB
->Sattr
= cpu_to_le16(ATTR_HIDDEN
| ATTR_SYSTEM
| ATTR_DIRECTORY
);
1239 pSMB
->OpenFunction
= cpu_to_le16(convert_disposition(openDisposition
));
1241 inc_rfc1001_len(pSMB
, count
);
1243 pSMB
->ByteCount
= cpu_to_le16(count
);
1244 /* long_op set to 1 to allow for oplock break timeouts */
1245 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1246 (struct smb_hdr
*)pSMBr
, &bytes_returned
, 0);
1247 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1249 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1251 /* BB verify if wct == 15 */
1253 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1255 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
1256 /* Let caller know file was created so we can set the mode. */
1257 /* Do we care about the CreateAction in any other cases? */
1259 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1260 *pOplock |= CIFS_CREATE_ACTION; */
1264 pfile_info
->CreationTime
= 0; /* BB convert CreateTime*/
1265 pfile_info
->LastAccessTime
= 0; /* BB fixme */
1266 pfile_info
->LastWriteTime
= 0; /* BB fixme */
1267 pfile_info
->ChangeTime
= 0; /* BB fixme */
1268 pfile_info
->Attributes
=
1269 cpu_to_le32(le16_to_cpu(pSMBr
->FileAttributes
));
1270 /* the file_info buf is endian converted by caller */
1271 pfile_info
->AllocationSize
=
1272 cpu_to_le64(le32_to_cpu(pSMBr
->EndOfFile
));
1273 pfile_info
->EndOfFile
= pfile_info
->AllocationSize
;
1274 pfile_info
->NumberOfLinks
= cpu_to_le32(1);
1275 pfile_info
->DeletePending
= 0;
1279 cifs_buf_release(pSMB
);
1286 CIFSSMBOpen(const unsigned int xid
, struct cifs_tcon
*tcon
,
1287 const char *fileName
, const int openDisposition
,
1288 const int access_flags
, const int create_options
, __u16
*netfid
,
1289 int *pOplock
, FILE_ALL_INFO
*pfile_info
,
1290 const struct nls_table
*nls_codepage
, int remap
)
1293 OPEN_REQ
*pSMB
= NULL
;
1294 OPEN_RSP
*pSMBr
= NULL
;
1300 rc
= smb_init(SMB_COM_NT_CREATE_ANDX
, 24, tcon
, (void **) &pSMB
,
1305 pSMB
->AndXCommand
= 0xFF; /* none */
1307 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1308 count
= 1; /* account for one byte pad to word boundary */
1310 cifsConvertToUTF16((__le16
*) (pSMB
->fileName
+ 1),
1311 fileName
, PATH_MAX
, nls_codepage
, remap
);
1312 name_len
++; /* trailing null */
1314 pSMB
->NameLength
= cpu_to_le16(name_len
);
1315 } else { /* BB improve check for buffer overruns BB */
1316 count
= 0; /* no pad */
1317 name_len
= strnlen(fileName
, PATH_MAX
);
1318 name_len
++; /* trailing null */
1319 pSMB
->NameLength
= cpu_to_le16(name_len
);
1320 strncpy(pSMB
->fileName
, fileName
, name_len
);
1322 if (*pOplock
& REQ_OPLOCK
)
1323 pSMB
->OpenFlags
= cpu_to_le32(REQ_OPLOCK
);
1324 else if (*pOplock
& REQ_BATCHOPLOCK
)
1325 pSMB
->OpenFlags
= cpu_to_le32(REQ_BATCHOPLOCK
);
1326 pSMB
->DesiredAccess
= cpu_to_le32(access_flags
);
1327 pSMB
->AllocationSize
= 0;
1328 /* set file as system file if special file such
1329 as fifo and server expecting SFU style and
1330 no Unix extensions */
1331 if (create_options
& CREATE_OPTION_SPECIAL
)
1332 pSMB
->FileAttributes
= cpu_to_le32(ATTR_SYSTEM
);
1334 pSMB
->FileAttributes
= cpu_to_le32(ATTR_NORMAL
);
1336 /* XP does not handle ATTR_POSIX_SEMANTICS */
1337 /* but it helps speed up case sensitive checks for other
1338 servers such as Samba */
1339 if (tcon
->ses
->capabilities
& CAP_UNIX
)
1340 pSMB
->FileAttributes
|= cpu_to_le32(ATTR_POSIX_SEMANTICS
);
1342 if (create_options
& CREATE_OPTION_READONLY
)
1343 pSMB
->FileAttributes
|= cpu_to_le32(ATTR_READONLY
);
1345 pSMB
->ShareAccess
= cpu_to_le32(FILE_SHARE_ALL
);
1346 pSMB
->CreateDisposition
= cpu_to_le32(openDisposition
);
1347 pSMB
->CreateOptions
= cpu_to_le32(create_options
& CREATE_OPTIONS_MASK
);
1348 /* BB Expirement with various impersonation levels and verify */
1349 pSMB
->ImpersonationLevel
= cpu_to_le32(SECURITY_IMPERSONATION
);
1350 pSMB
->SecurityFlags
=
1351 SECURITY_CONTEXT_TRACKING
| SECURITY_EFFECTIVE_ONLY
;
1354 inc_rfc1001_len(pSMB
, count
);
1356 pSMB
->ByteCount
= cpu_to_le16(count
);
1357 /* long_op set to 1 to allow for oplock break timeouts */
1358 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1359 (struct smb_hdr
*)pSMBr
, &bytes_returned
, 0);
1360 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1362 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1364 *pOplock
= pSMBr
->OplockLevel
; /* 1 byte no need to le_to_cpu */
1365 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
1366 /* Let caller know file was created so we can set the mode. */
1367 /* Do we care about the CreateAction in any other cases? */
1368 if (cpu_to_le32(FILE_CREATE
) == pSMBr
->CreateAction
)
1369 *pOplock
|= CIFS_CREATE_ACTION
;
1371 memcpy((char *)pfile_info
, (char *)&pSMBr
->CreationTime
,
1372 36 /* CreationTime to Attributes */);
1373 /* the file_info buf is endian converted by caller */
1374 pfile_info
->AllocationSize
= pSMBr
->AllocationSize
;
1375 pfile_info
->EndOfFile
= pSMBr
->EndOfFile
;
1376 pfile_info
->NumberOfLinks
= cpu_to_le32(1);
1377 pfile_info
->DeletePending
= 0;
1381 cifs_buf_release(pSMB
);
1388 * Discard any remaining data in the current SMB. To do this, we borrow the
1392 cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1394 unsigned int rfclen
= get_rfc1002_length(server
->smallbuf
);
1395 int remaining
= rfclen
+ 4 - server
->total_read
;
1396 struct cifs_readdata
*rdata
= mid
->callback_data
;
1398 while (remaining
> 0) {
1401 length
= cifs_read_from_socket(server
, server
->bigbuf
,
1402 min_t(unsigned int, remaining
,
1403 CIFSMaxBufSize
+ MAX_HEADER_SIZE(server
)));
1406 server
->total_read
+= length
;
1407 remaining
-= length
;
1410 dequeue_mid(mid
, rdata
->result
);
1415 cifs_readv_receive(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1418 unsigned int data_offset
, data_len
;
1419 struct cifs_readdata
*rdata
= mid
->callback_data
;
1420 char *buf
= server
->smallbuf
;
1421 unsigned int buflen
= get_rfc1002_length(buf
) + 4;
1423 cifs_dbg(FYI
, "%s: mid=%llu offset=%llu bytes=%u\n",
1424 __func__
, mid
->mid
, rdata
->offset
, rdata
->bytes
);
1427 * read the rest of READ_RSP header (sans Data array), or whatever we
1428 * can if there's not enough data. At this point, we've read down to
1431 len
= min_t(unsigned int, buflen
, server
->vals
->read_rsp_size
) -
1432 HEADER_SIZE(server
) + 1;
1434 rdata
->iov
.iov_base
= buf
+ HEADER_SIZE(server
) - 1;
1435 rdata
->iov
.iov_len
= len
;
1437 length
= cifs_readv_from_socket(server
, &rdata
->iov
, 1, len
);
1440 server
->total_read
+= length
;
1442 /* Was the SMB read successful? */
1443 rdata
->result
= server
->ops
->map_error(buf
, false);
1444 if (rdata
->result
!= 0) {
1445 cifs_dbg(FYI
, "%s: server returned error %d\n",
1446 __func__
, rdata
->result
);
1447 return cifs_readv_discard(server
, mid
);
1450 /* Is there enough to get to the rest of the READ_RSP header? */
1451 if (server
->total_read
< server
->vals
->read_rsp_size
) {
1452 cifs_dbg(FYI
, "%s: server returned short header. got=%u expected=%zu\n",
1453 __func__
, server
->total_read
,
1454 server
->vals
->read_rsp_size
);
1455 rdata
->result
= -EIO
;
1456 return cifs_readv_discard(server
, mid
);
1459 data_offset
= server
->ops
->read_data_offset(buf
) + 4;
1460 if (data_offset
< server
->total_read
) {
1462 * win2k8 sometimes sends an offset of 0 when the read
1463 * is beyond the EOF. Treat it as if the data starts just after
1466 cifs_dbg(FYI
, "%s: data offset (%u) inside read response header\n",
1467 __func__
, data_offset
);
1468 data_offset
= server
->total_read
;
1469 } else if (data_offset
> MAX_CIFS_SMALL_BUFFER_SIZE
) {
1470 /* data_offset is beyond the end of smallbuf */
1471 cifs_dbg(FYI
, "%s: data offset (%u) beyond end of smallbuf\n",
1472 __func__
, data_offset
);
1473 rdata
->result
= -EIO
;
1474 return cifs_readv_discard(server
, mid
);
1477 cifs_dbg(FYI
, "%s: total_read=%u data_offset=%u\n",
1478 __func__
, server
->total_read
, data_offset
);
1480 len
= data_offset
- server
->total_read
;
1482 /* read any junk before data into the rest of smallbuf */
1483 rdata
->iov
.iov_base
= buf
+ server
->total_read
;
1484 rdata
->iov
.iov_len
= len
;
1485 length
= cifs_readv_from_socket(server
, &rdata
->iov
, 1, len
);
1488 server
->total_read
+= length
;
1491 /* set up first iov for signature check */
1492 rdata
->iov
.iov_base
= buf
;
1493 rdata
->iov
.iov_len
= server
->total_read
;
1494 cifs_dbg(FYI
, "0: iov_base=%p iov_len=%zu\n",
1495 rdata
->iov
.iov_base
, rdata
->iov
.iov_len
);
1497 /* how much data is in the response? */
1498 data_len
= server
->ops
->read_data_length(buf
);
1499 if (data_offset
+ data_len
> buflen
) {
1500 /* data_len is corrupt -- discard frame */
1501 rdata
->result
= -EIO
;
1502 return cifs_readv_discard(server
, mid
);
1505 length
= rdata
->read_into_pages(server
, rdata
, data_len
);
1509 server
->total_read
+= length
;
1510 rdata
->bytes
= length
;
1512 cifs_dbg(FYI
, "total_read=%u buflen=%u remaining=%u\n",
1513 server
->total_read
, buflen
, data_len
);
1515 /* discard anything left over */
1516 if (server
->total_read
< buflen
)
1517 return cifs_readv_discard(server
, mid
);
1519 dequeue_mid(mid
, false);
1524 cifs_readv_callback(struct mid_q_entry
*mid
)
1526 struct cifs_readdata
*rdata
= mid
->callback_data
;
1527 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1528 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
1529 struct smb_rqst rqst
= { .rq_iov
= &rdata
->iov
,
1531 .rq_pages
= rdata
->pages
,
1532 .rq_npages
= rdata
->nr_pages
,
1533 .rq_pagesz
= rdata
->pagesz
,
1534 .rq_tailsz
= rdata
->tailsz
};
1536 cifs_dbg(FYI
, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1537 __func__
, mid
->mid
, mid
->mid_state
, rdata
->result
,
1540 switch (mid
->mid_state
) {
1541 case MID_RESPONSE_RECEIVED
:
1542 /* result already set, check signature */
1543 if (server
->sec_mode
&
1544 (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
)) {
1547 rc
= cifs_verify_signature(&rqst
, server
,
1548 mid
->sequence_number
);
1550 cifs_dbg(VFS
, "SMB signature verification returned error = %d\n",
1553 /* FIXME: should this be counted toward the initiating task? */
1554 task_io_account_read(rdata
->bytes
);
1555 cifs_stats_bytes_read(tcon
, rdata
->bytes
);
1557 case MID_REQUEST_SUBMITTED
:
1558 case MID_RETRY_NEEDED
:
1559 rdata
->result
= -EAGAIN
;
1562 rdata
->result
= -EIO
;
1565 queue_work(cifsiod_wq
, &rdata
->work
);
1566 DeleteMidQEntry(mid
);
1567 add_credits(server
, 1, 0);
1570 /* cifs_async_readv - send an async write, and set up mid to handle result */
1572 cifs_async_readv(struct cifs_readdata
*rdata
)
1575 READ_REQ
*smb
= NULL
;
1577 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1578 struct smb_rqst rqst
= { .rq_iov
= &rdata
->iov
,
1581 cifs_dbg(FYI
, "%s: offset=%llu bytes=%u\n",
1582 __func__
, rdata
->offset
, rdata
->bytes
);
1584 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1587 wct
= 10; /* old style read */
1588 if ((rdata
->offset
>> 32) > 0) {
1589 /* can not handle this big offset for old */
1594 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **)&smb
);
1598 smb
->hdr
.Pid
= cpu_to_le16((__u16
)rdata
->pid
);
1599 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(rdata
->pid
>> 16));
1601 smb
->AndXCommand
= 0xFF; /* none */
1602 smb
->Fid
= rdata
->cfile
->fid
.netfid
;
1603 smb
->OffsetLow
= cpu_to_le32(rdata
->offset
& 0xFFFFFFFF);
1605 smb
->OffsetHigh
= cpu_to_le32(rdata
->offset
>> 32);
1607 smb
->MaxCount
= cpu_to_le16(rdata
->bytes
& 0xFFFF);
1608 smb
->MaxCountHigh
= cpu_to_le32(rdata
->bytes
>> 16);
1612 /* old style read */
1613 struct smb_com_readx_req
*smbr
=
1614 (struct smb_com_readx_req
*)smb
;
1615 smbr
->ByteCount
= 0;
1618 /* 4 for RFC1001 length + 1 for BCC */
1619 rdata
->iov
.iov_base
= smb
;
1620 rdata
->iov
.iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4;
1622 kref_get(&rdata
->refcount
);
1623 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, cifs_readv_receive
,
1624 cifs_readv_callback
, rdata
, 0);
1627 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1629 kref_put(&rdata
->refcount
, cifs_readdata_release
);
1631 cifs_small_buf_release(smb
);
1636 CIFSSMBRead(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1637 unsigned int *nbytes
, char **buf
, int *pbuf_type
)
1640 READ_REQ
*pSMB
= NULL
;
1641 READ_RSP
*pSMBr
= NULL
;
1642 char *pReadData
= NULL
;
1644 int resp_buf_type
= 0;
1646 __u32 pid
= io_parms
->pid
;
1647 __u16 netfid
= io_parms
->netfid
;
1648 __u64 offset
= io_parms
->offset
;
1649 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1650 unsigned int count
= io_parms
->length
;
1652 cifs_dbg(FYI
, "Reading %d bytes on fid %d\n", count
, netfid
);
1653 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1656 wct
= 10; /* old style read */
1657 if ((offset
>> 32) > 0) {
1658 /* can not handle this big offset for old */
1664 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **) &pSMB
);
1668 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1669 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1671 /* tcon and ses pointer are checked in smb_init */
1672 if (tcon
->ses
->server
== NULL
)
1673 return -ECONNABORTED
;
1675 pSMB
->AndXCommand
= 0xFF; /* none */
1677 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1679 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1681 pSMB
->Remaining
= 0;
1682 pSMB
->MaxCount
= cpu_to_le16(count
& 0xFFFF);
1683 pSMB
->MaxCountHigh
= cpu_to_le32(count
>> 16);
1685 pSMB
->ByteCount
= 0; /* no need to do le conversion since 0 */
1687 /* old style read */
1688 struct smb_com_readx_req
*pSMBW
=
1689 (struct smb_com_readx_req
*)pSMB
;
1690 pSMBW
->ByteCount
= 0;
1693 iov
[0].iov_base
= (char *)pSMB
;
1694 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
1695 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
1696 &resp_buf_type
, CIFS_LOG_ERROR
);
1697 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1698 pSMBr
= (READ_RSP
*)iov
[0].iov_base
;
1700 cifs_dbg(VFS
, "Send error in read = %d\n", rc
);
1702 int data_length
= le16_to_cpu(pSMBr
->DataLengthHigh
);
1703 data_length
= data_length
<< 16;
1704 data_length
+= le16_to_cpu(pSMBr
->DataLength
);
1705 *nbytes
= data_length
;
1707 /*check that DataLength would not go beyond end of SMB */
1708 if ((data_length
> CIFSMaxBufSize
)
1709 || (data_length
> count
)) {
1710 cifs_dbg(FYI
, "bad length %d for count %d\n",
1711 data_length
, count
);
1715 pReadData
= (char *) (&pSMBr
->hdr
.Protocol
) +
1716 le16_to_cpu(pSMBr
->DataOffset
);
1717 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1718 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1720 }*/ /* can not use copy_to_user when using page cache*/
1722 memcpy(*buf
, pReadData
, data_length
);
1726 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1728 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1729 cifs_small_buf_release(iov
[0].iov_base
);
1730 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1731 cifs_buf_release(iov
[0].iov_base
);
1732 } else if (resp_buf_type
!= CIFS_NO_BUFFER
) {
1733 /* return buffer to caller to free */
1734 *buf
= iov
[0].iov_base
;
1735 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1736 *pbuf_type
= CIFS_SMALL_BUFFER
;
1737 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1738 *pbuf_type
= CIFS_LARGE_BUFFER
;
1739 } /* else no valid buffer on return - leave as null */
1741 /* Note: On -EAGAIN error only caller can retry on handle based calls
1742 since file handle passed in no longer valid */
1748 CIFSSMBWrite(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1749 unsigned int *nbytes
, const char *buf
,
1750 const char __user
*ubuf
, const int long_op
)
1753 WRITE_REQ
*pSMB
= NULL
;
1754 WRITE_RSP
*pSMBr
= NULL
;
1755 int bytes_returned
, wct
;
1758 __u32 pid
= io_parms
->pid
;
1759 __u16 netfid
= io_parms
->netfid
;
1760 __u64 offset
= io_parms
->offset
;
1761 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1762 unsigned int count
= io_parms
->length
;
1766 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1767 if (tcon
->ses
== NULL
)
1768 return -ECONNABORTED
;
1770 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1774 if ((offset
>> 32) > 0) {
1775 /* can not handle big offset for old srv */
1780 rc
= smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
,
1785 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1786 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1788 /* tcon and ses pointer are checked in smb_init */
1789 if (tcon
->ses
->server
== NULL
)
1790 return -ECONNABORTED
;
1792 pSMB
->AndXCommand
= 0xFF; /* none */
1794 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1796 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1798 pSMB
->Reserved
= 0xFFFFFFFF;
1799 pSMB
->WriteMode
= 0;
1800 pSMB
->Remaining
= 0;
1802 /* Can increase buffer size if buffer is big enough in some cases ie we
1803 can send more if LARGE_WRITE_X capability returned by the server and if
1804 our buffer is big enough or if we convert to iovecs on socket writes
1805 and eliminate the copy to the CIFS buffer */
1806 if (tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
) {
1807 bytes_sent
= min_t(const unsigned int, CIFSMaxBufSize
, count
);
1809 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
)
1813 if (bytes_sent
> count
)
1816 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1818 memcpy(pSMB
->Data
, buf
, bytes_sent
);
1820 if (copy_from_user(pSMB
->Data
, ubuf
, bytes_sent
)) {
1821 cifs_buf_release(pSMB
);
1824 } else if (count
!= 0) {
1826 cifs_buf_release(pSMB
);
1828 } /* else setting file size with write of zero bytes */
1830 byte_count
= bytes_sent
+ 1; /* pad */
1831 else /* wct == 12 */
1832 byte_count
= bytes_sent
+ 5; /* bigger pad, smaller smb hdr */
1834 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
& 0xFFFF);
1835 pSMB
->DataLengthHigh
= cpu_to_le16(bytes_sent
>> 16);
1836 inc_rfc1001_len(pSMB
, byte_count
);
1839 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1840 else { /* old style write has byte count 4 bytes earlier
1842 struct smb_com_writex_req
*pSMBW
=
1843 (struct smb_com_writex_req
*)pSMB
;
1844 pSMBW
->ByteCount
= cpu_to_le16(byte_count
);
1847 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1848 (struct smb_hdr
*) pSMBr
, &bytes_returned
, long_op
);
1849 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
1851 cifs_dbg(FYI
, "Send error in write = %d\n", rc
);
1853 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
1854 *nbytes
= (*nbytes
) << 16;
1855 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
1858 * Mask off high 16 bits when bytes written as returned by the
1859 * server is greater than bytes requested by the client. Some
1860 * OS/2 servers are known to set incorrect CountHigh values.
1862 if (*nbytes
> count
)
1866 cifs_buf_release(pSMB
);
1868 /* Note: On -EAGAIN error only caller can retry on handle based calls
1869 since file handle passed in no longer valid */
1875 cifs_writedata_release(struct kref
*refcount
)
1877 struct cifs_writedata
*wdata
= container_of(refcount
,
1878 struct cifs_writedata
, refcount
);
1881 cifsFileInfo_put(wdata
->cfile
);
1887 * Write failed with a retryable error. Resend the write request. It's also
1888 * possible that the page was redirtied so re-clean the page.
1891 cifs_writev_requeue(struct cifs_writedata
*wdata
)
1894 struct inode
*inode
= wdata
->cfile
->dentry
->d_inode
;
1895 struct TCP_Server_Info
*server
;
1897 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
1898 lock_page(wdata
->pages
[i
]);
1899 clear_page_dirty_for_io(wdata
->pages
[i
]);
1903 server
= tlink_tcon(wdata
->cfile
->tlink
)->ses
->server
;
1904 rc
= server
->ops
->async_writev(wdata
);
1905 } while (rc
== -EAGAIN
);
1907 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
1908 unlock_page(wdata
->pages
[i
]);
1910 SetPageError(wdata
->pages
[i
]);
1911 end_page_writeback(wdata
->pages
[i
]);
1912 page_cache_release(wdata
->pages
[i
]);
1916 mapping_set_error(inode
->i_mapping
, rc
);
1917 kref_put(&wdata
->refcount
, cifs_writedata_release
);
1921 cifs_writev_complete(struct work_struct
*work
)
1923 struct cifs_writedata
*wdata
= container_of(work
,
1924 struct cifs_writedata
, work
);
1925 struct inode
*inode
= wdata
->cfile
->dentry
->d_inode
;
1928 if (wdata
->result
== 0) {
1929 spin_lock(&inode
->i_lock
);
1930 cifs_update_eof(CIFS_I(inode
), wdata
->offset
, wdata
->bytes
);
1931 spin_unlock(&inode
->i_lock
);
1932 cifs_stats_bytes_written(tlink_tcon(wdata
->cfile
->tlink
),
1934 } else if (wdata
->sync_mode
== WB_SYNC_ALL
&& wdata
->result
== -EAGAIN
)
1935 return cifs_writev_requeue(wdata
);
1937 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
1938 struct page
*page
= wdata
->pages
[i
];
1939 if (wdata
->result
== -EAGAIN
)
1940 __set_page_dirty_nobuffers(page
);
1941 else if (wdata
->result
< 0)
1943 end_page_writeback(page
);
1944 page_cache_release(page
);
1946 if (wdata
->result
!= -EAGAIN
)
1947 mapping_set_error(inode
->i_mapping
, wdata
->result
);
1948 kref_put(&wdata
->refcount
, cifs_writedata_release
);
1951 struct cifs_writedata
*
1952 cifs_writedata_alloc(unsigned int nr_pages
, work_func_t complete
)
1954 struct cifs_writedata
*wdata
;
1956 /* this would overflow */
1957 if (nr_pages
== 0) {
1958 cifs_dbg(VFS
, "%s: called with nr_pages == 0!\n", __func__
);
1962 /* writedata + number of page pointers */
1963 wdata
= kzalloc(sizeof(*wdata
) +
1964 sizeof(struct page
*) * (nr_pages
- 1), GFP_NOFS
);
1965 if (wdata
!= NULL
) {
1966 kref_init(&wdata
->refcount
);
1967 INIT_LIST_HEAD(&wdata
->list
);
1968 init_completion(&wdata
->done
);
1969 INIT_WORK(&wdata
->work
, complete
);
1975 * Check the mid_state and signature on received buffer (if any), and queue the
1976 * workqueue completion task.
1979 cifs_writev_callback(struct mid_q_entry
*mid
)
1981 struct cifs_writedata
*wdata
= mid
->callback_data
;
1982 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
1983 unsigned int written
;
1984 WRITE_RSP
*smb
= (WRITE_RSP
*)mid
->resp_buf
;
1986 switch (mid
->mid_state
) {
1987 case MID_RESPONSE_RECEIVED
:
1988 wdata
->result
= cifs_check_receive(mid
, tcon
->ses
->server
, 0);
1989 if (wdata
->result
!= 0)
1992 written
= le16_to_cpu(smb
->CountHigh
);
1994 written
+= le16_to_cpu(smb
->Count
);
1996 * Mask off high 16 bits when bytes written as returned
1997 * by the server is greater than bytes requested by the
1998 * client. OS/2 servers are known to set incorrect
2001 if (written
> wdata
->bytes
)
2004 if (written
< wdata
->bytes
)
2005 wdata
->result
= -ENOSPC
;
2007 wdata
->bytes
= written
;
2009 case MID_REQUEST_SUBMITTED
:
2010 case MID_RETRY_NEEDED
:
2011 wdata
->result
= -EAGAIN
;
2014 wdata
->result
= -EIO
;
2018 queue_work(cifsiod_wq
, &wdata
->work
);
2019 DeleteMidQEntry(mid
);
2020 add_credits(tcon
->ses
->server
, 1, 0);
2023 /* cifs_async_writev - send an async write, and set up mid to handle result */
2025 cifs_async_writev(struct cifs_writedata
*wdata
)
2028 WRITE_REQ
*smb
= NULL
;
2030 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2032 struct smb_rqst rqst
= { };
2034 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2038 if (wdata
->offset
>> 32 > 0) {
2039 /* can not handle big offset for old srv */
2044 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **)&smb
);
2046 goto async_writev_out
;
2048 smb
->hdr
.Pid
= cpu_to_le16((__u16
)wdata
->pid
);
2049 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(wdata
->pid
>> 16));
2051 smb
->AndXCommand
= 0xFF; /* none */
2052 smb
->Fid
= wdata
->cfile
->fid
.netfid
;
2053 smb
->OffsetLow
= cpu_to_le32(wdata
->offset
& 0xFFFFFFFF);
2055 smb
->OffsetHigh
= cpu_to_le32(wdata
->offset
>> 32);
2056 smb
->Reserved
= 0xFFFFFFFF;
2061 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2063 /* 4 for RFC1001 length + 1 for BCC */
2064 iov
.iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4 + 1;
2069 rqst
.rq_pages
= wdata
->pages
;
2070 rqst
.rq_npages
= wdata
->nr_pages
;
2071 rqst
.rq_pagesz
= wdata
->pagesz
;
2072 rqst
.rq_tailsz
= wdata
->tailsz
;
2074 cifs_dbg(FYI
, "async write at %llu %u bytes\n",
2075 wdata
->offset
, wdata
->bytes
);
2077 smb
->DataLengthLow
= cpu_to_le16(wdata
->bytes
& 0xFFFF);
2078 smb
->DataLengthHigh
= cpu_to_le16(wdata
->bytes
>> 16);
2081 inc_rfc1001_len(&smb
->hdr
, wdata
->bytes
+ 1);
2082 put_bcc(wdata
->bytes
+ 1, &smb
->hdr
);
2085 struct smb_com_writex_req
*smbw
=
2086 (struct smb_com_writex_req
*)smb
;
2087 inc_rfc1001_len(&smbw
->hdr
, wdata
->bytes
+ 5);
2088 put_bcc(wdata
->bytes
+ 5, &smbw
->hdr
);
2089 iov
.iov_len
+= 4; /* pad bigger by four bytes */
2092 kref_get(&wdata
->refcount
);
2093 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, NULL
,
2094 cifs_writev_callback
, wdata
, 0);
2097 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2099 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2102 cifs_small_buf_release(smb
);
2107 CIFSSMBWrite2(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
2108 unsigned int *nbytes
, struct kvec
*iov
, int n_vec
)
2111 WRITE_REQ
*pSMB
= NULL
;
2114 int resp_buf_type
= 0;
2115 __u32 pid
= io_parms
->pid
;
2116 __u16 netfid
= io_parms
->netfid
;
2117 __u64 offset
= io_parms
->offset
;
2118 struct cifs_tcon
*tcon
= io_parms
->tcon
;
2119 unsigned int count
= io_parms
->length
;
2123 cifs_dbg(FYI
, "write2 at %lld %d bytes\n", (long long)offset
, count
);
2125 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2129 if ((offset
>> 32) > 0) {
2130 /* can not handle big offset for old srv */
2134 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
);
2138 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
2139 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
2141 /* tcon and ses pointer are checked in smb_init */
2142 if (tcon
->ses
->server
== NULL
)
2143 return -ECONNABORTED
;
2145 pSMB
->AndXCommand
= 0xFF; /* none */
2147 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
2149 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
2150 pSMB
->Reserved
= 0xFFFFFFFF;
2151 pSMB
->WriteMode
= 0;
2152 pSMB
->Remaining
= 0;
2155 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2157 pSMB
->DataLengthLow
= cpu_to_le16(count
& 0xFFFF);
2158 pSMB
->DataLengthHigh
= cpu_to_le16(count
>> 16);
2159 /* header + 1 byte pad */
2160 smb_hdr_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 1;
2162 inc_rfc1001_len(pSMB
, count
+ 1);
2163 else /* wct == 12 */
2164 inc_rfc1001_len(pSMB
, count
+ 5); /* smb data starts later */
2166 pSMB
->ByteCount
= cpu_to_le16(count
+ 1);
2167 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2168 struct smb_com_writex_req
*pSMBW
=
2169 (struct smb_com_writex_req
*)pSMB
;
2170 pSMBW
->ByteCount
= cpu_to_le16(count
+ 5);
2172 iov
[0].iov_base
= pSMB
;
2174 iov
[0].iov_len
= smb_hdr_len
+ 4;
2175 else /* wct == 12 pad bigger by four bytes */
2176 iov
[0].iov_len
= smb_hdr_len
+ 8;
2179 rc
= SendReceive2(xid
, tcon
->ses
, iov
, n_vec
+ 1, &resp_buf_type
, 0);
2180 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2182 cifs_dbg(FYI
, "Send error Write2 = %d\n", rc
);
2183 } else if (resp_buf_type
== 0) {
2184 /* presumably this can not happen, but best to be safe */
2187 WRITE_RSP
*pSMBr
= (WRITE_RSP
*)iov
[0].iov_base
;
2188 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2189 *nbytes
= (*nbytes
) << 16;
2190 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2193 * Mask off high 16 bits when bytes written as returned by the
2194 * server is greater than bytes requested by the client. OS/2
2195 * servers are known to set incorrect CountHigh values.
2197 if (*nbytes
> count
)
2201 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2202 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
2203 cifs_small_buf_release(iov
[0].iov_base
);
2204 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
2205 cifs_buf_release(iov
[0].iov_base
);
2207 /* Note: On -EAGAIN error only caller can retry on handle based calls
2208 since file handle passed in no longer valid */
2213 int cifs_lockv(const unsigned int xid
, struct cifs_tcon
*tcon
,
2214 const __u16 netfid
, const __u8 lock_type
, const __u32 num_unlock
,
2215 const __u32 num_lock
, LOCKING_ANDX_RANGE
*buf
)
2218 LOCK_REQ
*pSMB
= NULL
;
2223 cifs_dbg(FYI
, "cifs_lockv num lock %d num unlock %d\n",
2224 num_lock
, num_unlock
);
2226 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2231 pSMB
->NumberOfLocks
= cpu_to_le16(num_lock
);
2232 pSMB
->NumberOfUnlocks
= cpu_to_le16(num_unlock
);
2233 pSMB
->LockType
= lock_type
;
2234 pSMB
->AndXCommand
= 0xFF; /* none */
2235 pSMB
->Fid
= netfid
; /* netfid stays le */
2237 count
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2238 inc_rfc1001_len(pSMB
, count
);
2239 pSMB
->ByteCount
= cpu_to_le16(count
);
2241 iov
[0].iov_base
= (char *)pSMB
;
2242 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4 -
2243 (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2244 iov
[1].iov_base
= (char *)buf
;
2245 iov
[1].iov_len
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2247 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2248 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 2, &resp_buf_type
, CIFS_NO_RESP
);
2250 cifs_dbg(FYI
, "Send error in cifs_lockv = %d\n", rc
);
2256 CIFSSMBLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2257 const __u16 smb_file_id
, const __u32 netpid
, const __u64 len
,
2258 const __u64 offset
, const __u32 numUnlock
,
2259 const __u32 numLock
, const __u8 lockType
,
2260 const bool waitFlag
, const __u8 oplock_level
)
2263 LOCK_REQ
*pSMB
= NULL
;
2264 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2269 cifs_dbg(FYI
, "CIFSSMBLock timeout %d numLock %d\n",
2270 (int)waitFlag
, numLock
);
2271 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2276 if (lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
2277 /* no response expected */
2278 flags
= CIFS_ASYNC_OP
| CIFS_OBREAK_OP
;
2280 } else if (waitFlag
) {
2281 flags
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2282 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
2287 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
2288 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
2289 pSMB
->LockType
= lockType
;
2290 pSMB
->OplockLevel
= oplock_level
;
2291 pSMB
->AndXCommand
= 0xFF; /* none */
2292 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
2294 if ((numLock
!= 0) || (numUnlock
!= 0)) {
2295 pSMB
->Locks
[0].Pid
= cpu_to_le16(netpid
);
2296 /* BB where to store pid high? */
2297 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
2298 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
2299 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
2300 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
2301 count
= sizeof(LOCKING_ANDX_RANGE
);
2306 inc_rfc1001_len(pSMB
, count
);
2307 pSMB
->ByteCount
= cpu_to_le16(count
);
2310 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2311 (struct smb_hdr
*) pSMB
, &bytes_returned
);
2312 cifs_small_buf_release(pSMB
);
2314 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)pSMB
, flags
);
2315 /* SMB buffer freed by function above */
2317 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2319 cifs_dbg(FYI
, "Send error in Lock = %d\n", rc
);
2321 /* Note: On -EAGAIN error only caller can retry on handle based calls
2322 since file handle passed in no longer valid */
2327 CIFSSMBPosixLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2328 const __u16 smb_file_id
, const __u32 netpid
,
2329 const loff_t start_offset
, const __u64 len
,
2330 struct file_lock
*pLockData
, const __u16 lock_type
,
2331 const bool waitFlag
)
2333 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2334 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2335 struct cifs_posix_lock
*parm_data
;
2338 int bytes_returned
= 0;
2339 int resp_buf_type
= 0;
2340 __u16 params
, param_offset
, offset
, byte_count
, count
;
2343 cifs_dbg(FYI
, "Posix Lock\n");
2345 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
2350 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)pSMB
;
2353 pSMB
->MaxSetupCount
= 0;
2356 pSMB
->Reserved2
= 0;
2357 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2358 offset
= param_offset
+ params
;
2360 count
= sizeof(struct cifs_posix_lock
);
2361 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2362 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2363 pSMB
->SetupCount
= 1;
2364 pSMB
->Reserved3
= 0;
2366 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
2368 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2369 byte_count
= 3 /* pad */ + params
+ count
;
2370 pSMB
->DataCount
= cpu_to_le16(count
);
2371 pSMB
->ParameterCount
= cpu_to_le16(params
);
2372 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2373 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2374 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2375 parm_data
= (struct cifs_posix_lock
*)
2376 (((char *) &pSMB
->hdr
.Protocol
) + offset
);
2378 parm_data
->lock_type
= cpu_to_le16(lock_type
);
2380 timeout
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2381 parm_data
->lock_flags
= cpu_to_le16(1);
2382 pSMB
->Timeout
= cpu_to_le32(-1);
2386 parm_data
->pid
= cpu_to_le32(netpid
);
2387 parm_data
->start
= cpu_to_le64(start_offset
);
2388 parm_data
->length
= cpu_to_le64(len
); /* normalize negative numbers */
2390 pSMB
->DataOffset
= cpu_to_le16(offset
);
2391 pSMB
->Fid
= smb_file_id
;
2392 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_LOCK
);
2393 pSMB
->Reserved4
= 0;
2394 inc_rfc1001_len(pSMB
, byte_count
);
2395 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2397 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2398 (struct smb_hdr
*) pSMBr
, &bytes_returned
);
2400 iov
[0].iov_base
= (char *)pSMB
;
2401 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
2402 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
2403 &resp_buf_type
, timeout
);
2404 pSMB
= NULL
; /* request buf already freed by SendReceive2. Do
2405 not try to free it twice below on exit */
2406 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)iov
[0].iov_base
;
2410 cifs_dbg(FYI
, "Send error in Posix Lock = %d\n", rc
);
2411 } else if (pLockData
) {
2412 /* lock structure can be returned on get */
2415 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2417 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(*parm_data
)) {
2418 rc
= -EIO
; /* bad smb */
2421 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
2422 data_count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2423 if (data_count
< sizeof(struct cifs_posix_lock
)) {
2427 parm_data
= (struct cifs_posix_lock
*)
2428 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2429 if (parm_data
->lock_type
== __constant_cpu_to_le16(CIFS_UNLCK
))
2430 pLockData
->fl_type
= F_UNLCK
;
2432 if (parm_data
->lock_type
==
2433 __constant_cpu_to_le16(CIFS_RDLCK
))
2434 pLockData
->fl_type
= F_RDLCK
;
2435 else if (parm_data
->lock_type
==
2436 __constant_cpu_to_le16(CIFS_WRLCK
))
2437 pLockData
->fl_type
= F_WRLCK
;
2439 pLockData
->fl_start
= le64_to_cpu(parm_data
->start
);
2440 pLockData
->fl_end
= pLockData
->fl_start
+
2441 le64_to_cpu(parm_data
->length
) - 1;
2442 pLockData
->fl_pid
= le32_to_cpu(parm_data
->pid
);
2448 cifs_small_buf_release(pSMB
);
2450 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
2451 cifs_small_buf_release(iov
[0].iov_base
);
2452 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
2453 cifs_buf_release(iov
[0].iov_base
);
2455 /* Note: On -EAGAIN error only caller can retry on handle based calls
2456 since file handle passed in no longer valid */
2463 CIFSSMBClose(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2466 CLOSE_REQ
*pSMB
= NULL
;
2467 cifs_dbg(FYI
, "In CIFSSMBClose\n");
2469 /* do not retry on dead session on close */
2470 rc
= small_smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
);
2476 pSMB
->FileID
= (__u16
) smb_file_id
;
2477 pSMB
->LastWriteTime
= 0xFFFFFFFF;
2478 pSMB
->ByteCount
= 0;
2479 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2480 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_closes
);
2483 /* EINTR is expected when user ctl-c to kill app */
2484 cifs_dbg(VFS
, "Send error in Close = %d\n", rc
);
2488 /* Since session is dead, file will be closed on server already */
2496 CIFSSMBFlush(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2499 FLUSH_REQ
*pSMB
= NULL
;
2500 cifs_dbg(FYI
, "In CIFSSMBFlush\n");
2502 rc
= small_smb_init(SMB_COM_FLUSH
, 1, tcon
, (void **) &pSMB
);
2506 pSMB
->FileID
= (__u16
) smb_file_id
;
2507 pSMB
->ByteCount
= 0;
2508 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2509 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_flushes
);
2511 cifs_dbg(VFS
, "Send error in Flush = %d\n", rc
);
2517 CIFSSMBRename(const unsigned int xid
, struct cifs_tcon
*tcon
,
2518 const char *from_name
, const char *to_name
,
2519 struct cifs_sb_info
*cifs_sb
)
2522 RENAME_REQ
*pSMB
= NULL
;
2523 RENAME_RSP
*pSMBr
= NULL
;
2525 int name_len
, name_len2
;
2527 int remap
= cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
;
2529 cifs_dbg(FYI
, "In CIFSSMBRename\n");
2531 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
2536 pSMB
->BufferFormat
= 0x04;
2537 pSMB
->SearchAttributes
=
2538 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2541 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2542 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2543 from_name
, PATH_MAX
,
2544 cifs_sb
->local_nls
, remap
);
2545 name_len
++; /* trailing null */
2547 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2548 /* protocol requires ASCII signature byte on Unicode string */
2549 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2551 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2552 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2554 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2555 name_len2
*= 2; /* convert to bytes */
2556 } else { /* BB improve the check for buffer overruns BB */
2557 name_len
= strnlen(from_name
, PATH_MAX
);
2558 name_len
++; /* trailing null */
2559 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
2560 name_len2
= strnlen(to_name
, PATH_MAX
);
2561 name_len2
++; /* trailing null */
2562 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2563 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
2564 name_len2
++; /* trailing null */
2565 name_len2
++; /* signature byte */
2568 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2569 inc_rfc1001_len(pSMB
, count
);
2570 pSMB
->ByteCount
= cpu_to_le16(count
);
2572 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2573 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2574 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_renames
);
2576 cifs_dbg(FYI
, "Send error in rename = %d\n", rc
);
2578 cifs_buf_release(pSMB
);
2586 int CIFSSMBRenameOpenFile(const unsigned int xid
, struct cifs_tcon
*pTcon
,
2587 int netfid
, const char *target_name
,
2588 const struct nls_table
*nls_codepage
, int remap
)
2590 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2591 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2592 struct set_file_rename
*rename_info
;
2594 char dummy_string
[30];
2596 int bytes_returned
= 0;
2598 __u16 params
, param_offset
, offset
, count
, byte_count
;
2600 cifs_dbg(FYI
, "Rename to File by handle\n");
2601 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
2607 pSMB
->MaxSetupCount
= 0;
2611 pSMB
->Reserved2
= 0;
2612 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2613 offset
= param_offset
+ params
;
2615 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2616 rename_info
= (struct set_file_rename
*) data_offset
;
2617 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2618 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2619 pSMB
->SetupCount
= 1;
2620 pSMB
->Reserved3
= 0;
2621 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2622 byte_count
= 3 /* pad */ + params
;
2623 pSMB
->ParameterCount
= cpu_to_le16(params
);
2624 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2625 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2626 pSMB
->DataOffset
= cpu_to_le16(offset
);
2627 /* construct random name ".cifs_tmp<inodenum><mid>" */
2628 rename_info
->overwrite
= cpu_to_le32(1);
2629 rename_info
->root_fid
= 0;
2630 /* unicode only call */
2631 if (target_name
== NULL
) {
2632 sprintf(dummy_string
, "cifs%x", pSMB
->hdr
.Mid
);
2634 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2635 dummy_string
, 24, nls_codepage
, remap
);
2638 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2639 target_name
, PATH_MAX
, nls_codepage
,
2642 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
2643 count
= 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str
);
2644 byte_count
+= count
;
2645 pSMB
->DataCount
= cpu_to_le16(count
);
2646 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2648 pSMB
->InformationLevel
=
2649 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
2650 pSMB
->Reserved4
= 0;
2651 inc_rfc1001_len(pSMB
, byte_count
);
2652 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2653 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
2654 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2655 cifs_stats_inc(&pTcon
->stats
.cifs_stats
.num_t2renames
);
2657 cifs_dbg(FYI
, "Send error in Rename (by file handle) = %d\n",
2660 cifs_buf_release(pSMB
);
2662 /* Note: On -EAGAIN error only caller can retry on handle based calls
2663 since file handle passed in no longer valid */
2669 CIFSSMBCopy(const unsigned int xid
, struct cifs_tcon
*tcon
,
2670 const char *fromName
, const __u16 target_tid
, const char *toName
,
2671 const int flags
, const struct nls_table
*nls_codepage
, int remap
)
2674 COPY_REQ
*pSMB
= NULL
;
2675 COPY_RSP
*pSMBr
= NULL
;
2677 int name_len
, name_len2
;
2680 cifs_dbg(FYI
, "In CIFSSMBCopy\n");
2682 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
2687 pSMB
->BufferFormat
= 0x04;
2688 pSMB
->Tid2
= target_tid
;
2690 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
2692 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2693 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2694 fromName
, PATH_MAX
, nls_codepage
,
2696 name_len
++; /* trailing null */
2698 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2699 /* protocol requires ASCII signature byte on Unicode string */
2700 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2702 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2703 toName
, PATH_MAX
, nls_codepage
, remap
);
2704 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2705 name_len2
*= 2; /* convert to bytes */
2706 } else { /* BB improve the check for buffer overruns BB */
2707 name_len
= strnlen(fromName
, PATH_MAX
);
2708 name_len
++; /* trailing null */
2709 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
2710 name_len2
= strnlen(toName
, PATH_MAX
);
2711 name_len2
++; /* trailing null */
2712 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2713 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
2714 name_len2
++; /* trailing null */
2715 name_len2
++; /* signature byte */
2718 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2719 inc_rfc1001_len(pSMB
, count
);
2720 pSMB
->ByteCount
= cpu_to_le16(count
);
2722 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2723 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2725 cifs_dbg(FYI
, "Send error in copy = %d with %d files copied\n",
2726 rc
, le16_to_cpu(pSMBr
->CopyCount
));
2728 cifs_buf_release(pSMB
);
2737 CIFSUnixCreateSymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2738 const char *fromName
, const char *toName
,
2739 const struct nls_table
*nls_codepage
)
2741 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2742 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2745 int name_len_target
;
2747 int bytes_returned
= 0;
2748 __u16 params
, param_offset
, offset
, byte_count
;
2750 cifs_dbg(FYI
, "In Symlink Unix style\n");
2752 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2757 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2759 cifs_strtoUTF16((__le16
*) pSMB
->FileName
, fromName
,
2760 /* find define for this maxpathcomponent */
2761 PATH_MAX
, nls_codepage
);
2762 name_len
++; /* trailing null */
2765 } else { /* BB improve the check for buffer overruns BB */
2766 name_len
= strnlen(fromName
, PATH_MAX
);
2767 name_len
++; /* trailing null */
2768 strncpy(pSMB
->FileName
, fromName
, name_len
);
2770 params
= 6 + name_len
;
2771 pSMB
->MaxSetupCount
= 0;
2775 pSMB
->Reserved2
= 0;
2776 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2777 InformationLevel
) - 4;
2778 offset
= param_offset
+ params
;
2780 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2781 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2783 cifs_strtoUTF16((__le16
*) data_offset
, toName
, PATH_MAX
2784 /* find define for this maxpathcomponent */
2786 name_len_target
++; /* trailing null */
2787 name_len_target
*= 2;
2788 } else { /* BB improve the check for buffer overruns BB */
2789 name_len_target
= strnlen(toName
, PATH_MAX
);
2790 name_len_target
++; /* trailing null */
2791 strncpy(data_offset
, toName
, name_len_target
);
2794 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2795 /* BB find exact max on data count below from sess */
2796 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2797 pSMB
->SetupCount
= 1;
2798 pSMB
->Reserved3
= 0;
2799 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2800 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2801 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2802 pSMB
->ParameterCount
= cpu_to_le16(params
);
2803 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2804 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2805 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2806 pSMB
->DataOffset
= cpu_to_le16(offset
);
2807 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
2808 pSMB
->Reserved4
= 0;
2809 inc_rfc1001_len(pSMB
, byte_count
);
2810 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2811 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2812 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2813 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_symlinks
);
2815 cifs_dbg(FYI
, "Send error in SetPathInfo create symlink = %d\n",
2818 cifs_buf_release(pSMB
);
2821 goto createSymLinkRetry
;
2827 CIFSUnixCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2828 const char *fromName
, const char *toName
,
2829 const struct nls_table
*nls_codepage
, int remap
)
2831 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2832 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2835 int name_len_target
;
2837 int bytes_returned
= 0;
2838 __u16 params
, param_offset
, offset
, byte_count
;
2840 cifs_dbg(FYI
, "In Create Hard link Unix style\n");
2841 createHardLinkRetry
:
2842 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2847 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2848 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->FileName
, toName
,
2849 PATH_MAX
, nls_codepage
, remap
);
2850 name_len
++; /* trailing null */
2853 } else { /* BB improve the check for buffer overruns BB */
2854 name_len
= strnlen(toName
, PATH_MAX
);
2855 name_len
++; /* trailing null */
2856 strncpy(pSMB
->FileName
, toName
, name_len
);
2858 params
= 6 + name_len
;
2859 pSMB
->MaxSetupCount
= 0;
2863 pSMB
->Reserved2
= 0;
2864 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2865 InformationLevel
) - 4;
2866 offset
= param_offset
+ params
;
2868 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2869 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2871 cifsConvertToUTF16((__le16
*) data_offset
, fromName
,
2872 PATH_MAX
, nls_codepage
, remap
);
2873 name_len_target
++; /* trailing null */
2874 name_len_target
*= 2;
2875 } else { /* BB improve the check for buffer overruns BB */
2876 name_len_target
= strnlen(fromName
, PATH_MAX
);
2877 name_len_target
++; /* trailing null */
2878 strncpy(data_offset
, fromName
, name_len_target
);
2881 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2882 /* BB find exact max on data count below from sess*/
2883 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2884 pSMB
->SetupCount
= 1;
2885 pSMB
->Reserved3
= 0;
2886 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2887 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2888 pSMB
->ParameterCount
= cpu_to_le16(params
);
2889 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2890 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2891 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2892 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2893 pSMB
->DataOffset
= cpu_to_le16(offset
);
2894 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
2895 pSMB
->Reserved4
= 0;
2896 inc_rfc1001_len(pSMB
, byte_count
);
2897 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2898 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2899 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2900 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
2902 cifs_dbg(FYI
, "Send error in SetPathInfo (hard link) = %d\n",
2905 cifs_buf_release(pSMB
);
2907 goto createHardLinkRetry
;
2913 CIFSCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2914 const char *from_name
, const char *to_name
,
2915 struct cifs_sb_info
*cifs_sb
)
2918 NT_RENAME_REQ
*pSMB
= NULL
;
2919 RENAME_RSP
*pSMBr
= NULL
;
2921 int name_len
, name_len2
;
2923 int remap
= cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
;
2925 cifs_dbg(FYI
, "In CIFSCreateHardLink\n");
2926 winCreateHardLinkRetry
:
2928 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
2933 pSMB
->SearchAttributes
=
2934 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2936 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
2937 pSMB
->ClusterCount
= 0;
2939 pSMB
->BufferFormat
= 0x04;
2941 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2943 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, from_name
,
2944 PATH_MAX
, cifs_sb
->local_nls
, remap
);
2945 name_len
++; /* trailing null */
2948 /* protocol specifies ASCII buffer format (0x04) for unicode */
2949 pSMB
->OldFileName
[name_len
] = 0x04;
2950 pSMB
->OldFileName
[name_len
+ 1] = 0x00; /* pad */
2952 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2953 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2955 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2956 name_len2
*= 2; /* convert to bytes */
2957 } else { /* BB improve the check for buffer overruns BB */
2958 name_len
= strnlen(from_name
, PATH_MAX
);
2959 name_len
++; /* trailing null */
2960 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
2961 name_len2
= strnlen(to_name
, PATH_MAX
);
2962 name_len2
++; /* trailing null */
2963 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2964 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
2965 name_len2
++; /* trailing null */
2966 name_len2
++; /* signature byte */
2969 count
= 1 /* string type byte */ + name_len
+ name_len2
;
2970 inc_rfc1001_len(pSMB
, count
);
2971 pSMB
->ByteCount
= cpu_to_le16(count
);
2973 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2974 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2975 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
2977 cifs_dbg(FYI
, "Send error in hard link (NT rename) = %d\n", rc
);
2979 cifs_buf_release(pSMB
);
2981 goto winCreateHardLinkRetry
;
2987 CIFSSMBUnixQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2988 const unsigned char *searchName
, char **symlinkinfo
,
2989 const struct nls_table
*nls_codepage
)
2991 /* SMB_QUERY_FILE_UNIX_LINK */
2992 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
2993 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
2997 __u16 params
, byte_count
;
3000 cifs_dbg(FYI
, "In QPathSymLinkInfo (Unix) for path %s\n", searchName
);
3003 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3008 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3010 cifs_strtoUTF16((__le16
*) pSMB
->FileName
, searchName
,
3011 PATH_MAX
, nls_codepage
);
3012 name_len
++; /* trailing null */
3014 } else { /* BB improve the check for buffer overruns BB */
3015 name_len
= strnlen(searchName
, PATH_MAX
);
3016 name_len
++; /* trailing null */
3017 strncpy(pSMB
->FileName
, searchName
, name_len
);
3020 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3021 pSMB
->TotalDataCount
= 0;
3022 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3023 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3024 pSMB
->MaxSetupCount
= 0;
3028 pSMB
->Reserved2
= 0;
3029 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3030 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3031 pSMB
->DataCount
= 0;
3032 pSMB
->DataOffset
= 0;
3033 pSMB
->SetupCount
= 1;
3034 pSMB
->Reserved3
= 0;
3035 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3036 byte_count
= params
+ 1 /* pad */ ;
3037 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3038 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3039 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
3040 pSMB
->Reserved4
= 0;
3041 inc_rfc1001_len(pSMB
, byte_count
);
3042 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3044 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3045 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3047 cifs_dbg(FYI
, "Send error in QuerySymLinkInfo = %d\n", rc
);
3049 /* decode response */
3051 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3052 /* BB also check enough total bytes returned */
3053 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3057 u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3059 data_start
= ((char *) &pSMBr
->hdr
.Protocol
) +
3060 le16_to_cpu(pSMBr
->t2
.DataOffset
);
3062 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3067 /* BB FIXME investigate remapping reserved chars here */
3068 *symlinkinfo
= cifs_strndup_from_utf16(data_start
,
3069 count
, is_unicode
, nls_codepage
);
3074 cifs_buf_release(pSMB
);
3076 goto querySymLinkRetry
;
3080 #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
3082 * Recent Windows versions now create symlinks more frequently
3083 * and they use the "reparse point" mechanism below. We can of course
3084 * do symlinks nicely to Samba and other servers which support the
3085 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3086 * "MF" symlinks optionally, but for recent Windows we really need to
3087 * reenable the code below and fix the cifs_symlink callers to handle this.
3088 * In the interim this code has been moved to its own config option so
3089 * it is not compiled in by default until callers fixed up and more tested.
3092 CIFSSMBQueryReparseLinkInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
3093 const unsigned char *searchName
,
3094 char *symlinkinfo
, const int buflen
, __u16 fid
,
3095 const struct nls_table
*nls_codepage
)
3099 struct smb_com_transaction_ioctl_req
*pSMB
;
3100 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3102 cifs_dbg(FYI
, "In Windows reparse style QueryLink for path %s\n",
3104 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3109 pSMB
->TotalParameterCount
= 0 ;
3110 pSMB
->TotalDataCount
= 0;
3111 pSMB
->MaxParameterCount
= cpu_to_le32(2);
3112 /* BB find exact data count max from sess structure BB */
3113 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3114 pSMB
->MaxSetupCount
= 4;
3116 pSMB
->ParameterOffset
= 0;
3117 pSMB
->DataCount
= 0;
3118 pSMB
->DataOffset
= 0;
3119 pSMB
->SetupCount
= 4;
3120 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3121 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3122 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
3123 pSMB
->IsFsctl
= 1; /* FSCTL */
3124 pSMB
->IsRootFlag
= 0;
3125 pSMB
->Fid
= fid
; /* file handle always le */
3126 pSMB
->ByteCount
= 0;
3128 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3129 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3131 cifs_dbg(FYI
, "Send error in QueryReparseLinkInfo = %d\n", rc
);
3132 } else { /* decode response */
3133 __u32 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3134 __u32 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3135 if (get_bcc(&pSMBr
->hdr
) < 2 || data_offset
> 512) {
3136 /* BB also check enough total bytes returned */
3137 rc
= -EIO
; /* bad smb */
3140 if (data_count
&& (data_count
< 2048)) {
3141 char *end_of_smb
= 2 /* sizeof byte count */ +
3142 get_bcc(&pSMBr
->hdr
) + (char *)&pSMBr
->ByteCount
;
3144 struct reparse_data
*reparse_buf
=
3145 (struct reparse_data
*)
3146 ((char *)&pSMBr
->hdr
.Protocol
3148 if ((char *)reparse_buf
>= end_of_smb
) {
3152 if ((reparse_buf
->LinkNamesBuf
+
3153 reparse_buf
->TargetNameOffset
+
3154 reparse_buf
->TargetNameLen
) > end_of_smb
) {
3155 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3160 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3161 cifs_from_ucs2(symlinkinfo
, (__le16
*)
3162 (reparse_buf
->LinkNamesBuf
+
3163 reparse_buf
->TargetNameOffset
),
3165 reparse_buf
->TargetNameLen
,
3167 } else { /* ASCII names */
3168 strncpy(symlinkinfo
,
3169 reparse_buf
->LinkNamesBuf
+
3170 reparse_buf
->TargetNameOffset
,
3171 min_t(const int, buflen
,
3172 reparse_buf
->TargetNameLen
));
3176 cifs_dbg(FYI
, "Invalid return data count on get reparse info ioctl\n");
3178 symlinkinfo
[buflen
] = 0; /* just in case so the caller
3179 does not go off the end of the buffer */
3180 cifs_dbg(FYI
, "readlink result - %s\n", symlinkinfo
);
3184 cifs_buf_release(pSMB
);
3186 /* Note: On -EAGAIN error only caller can retry on handle based calls
3187 since file handle passed in no longer valid */
3191 #endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
3193 #ifdef CONFIG_CIFS_POSIX
3195 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3196 static void cifs_convert_ace(posix_acl_xattr_entry
*ace
,
3197 struct cifs_posix_ace
*cifs_ace
)
3199 /* u8 cifs fields do not need le conversion */
3200 ace
->e_perm
= cpu_to_le16(cifs_ace
->cifs_e_perm
);
3201 ace
->e_tag
= cpu_to_le16(cifs_ace
->cifs_e_tag
);
3202 ace
->e_id
= cpu_to_le32(le64_to_cpu(cifs_ace
->cifs_uid
));
3204 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3205 ace->e_perm, ace->e_tag, ace->e_id);
3211 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3212 static int cifs_copy_posix_acl(char *trgt
, char *src
, const int buflen
,
3213 const int acl_type
, const int size_of_data_area
)
3218 struct cifs_posix_ace
*pACE
;
3219 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)src
;
3220 posix_acl_xattr_header
*local_acl
= (posix_acl_xattr_header
*)trgt
;
3222 if (le16_to_cpu(cifs_acl
->version
) != CIFS_ACL_VERSION
)
3225 if (acl_type
& ACL_TYPE_ACCESS
) {
3226 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3227 pACE
= &cifs_acl
->ace_array
[0];
3228 size
= sizeof(struct cifs_posix_acl
);
3229 size
+= sizeof(struct cifs_posix_ace
) * count
;
3230 /* check if we would go beyond end of SMB */
3231 if (size_of_data_area
< size
) {
3232 cifs_dbg(FYI
, "bad CIFS POSIX ACL size %d vs. %d\n",
3233 size_of_data_area
, size
);
3236 } else if (acl_type
& ACL_TYPE_DEFAULT
) {
3237 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3238 size
= sizeof(struct cifs_posix_acl
);
3239 size
+= sizeof(struct cifs_posix_ace
) * count
;
3240 /* skip past access ACEs to get to default ACEs */
3241 pACE
= &cifs_acl
->ace_array
[count
];
3242 count
= le16_to_cpu(cifs_acl
->default_entry_count
);
3243 size
+= sizeof(struct cifs_posix_ace
) * count
;
3244 /* check if we would go beyond end of SMB */
3245 if (size_of_data_area
< size
)
3252 size
= posix_acl_xattr_size(count
);
3253 if ((buflen
== 0) || (local_acl
== NULL
)) {
3254 /* used to query ACL EA size */
3255 } else if (size
> buflen
) {
3257 } else /* buffer big enough */ {
3258 local_acl
->a_version
= cpu_to_le32(POSIX_ACL_XATTR_VERSION
);
3259 for (i
= 0; i
< count
; i
++) {
3260 cifs_convert_ace(&local_acl
->a_entries
[i
], pACE
);
3267 static __u16
convert_ace_to_cifs_ace(struct cifs_posix_ace
*cifs_ace
,
3268 const posix_acl_xattr_entry
*local_ace
)
3270 __u16 rc
= 0; /* 0 = ACL converted ok */
3272 cifs_ace
->cifs_e_perm
= le16_to_cpu(local_ace
->e_perm
);
3273 cifs_ace
->cifs_e_tag
= le16_to_cpu(local_ace
->e_tag
);
3274 /* BB is there a better way to handle the large uid? */
3275 if (local_ace
->e_id
== cpu_to_le32(-1)) {
3276 /* Probably no need to le convert -1 on any arch but can not hurt */
3277 cifs_ace
->cifs_uid
= cpu_to_le64(-1);
3279 cifs_ace
->cifs_uid
= cpu_to_le64(le32_to_cpu(local_ace
->e_id
));
3281 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3282 ace->e_perm, ace->e_tag, ace->e_id);
3287 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3288 static __u16
ACL_to_cifs_posix(char *parm_data
, const char *pACL
,
3289 const int buflen
, const int acl_type
)
3292 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)parm_data
;
3293 posix_acl_xattr_header
*local_acl
= (posix_acl_xattr_header
*)pACL
;
3297 if ((buflen
== 0) || (pACL
== NULL
) || (cifs_acl
== NULL
))
3300 count
= posix_acl_xattr_count((size_t)buflen
);
3301 cifs_dbg(FYI
, "setting acl with %d entries from buf of length %d and version of %d\n",
3302 count
, buflen
, le32_to_cpu(local_acl
->a_version
));
3303 if (le32_to_cpu(local_acl
->a_version
) != 2) {
3304 cifs_dbg(FYI
, "unknown POSIX ACL version %d\n",
3305 le32_to_cpu(local_acl
->a_version
));
3308 cifs_acl
->version
= cpu_to_le16(1);
3309 if (acl_type
== ACL_TYPE_ACCESS
)
3310 cifs_acl
->access_entry_count
= cpu_to_le16(count
);
3311 else if (acl_type
== ACL_TYPE_DEFAULT
)
3312 cifs_acl
->default_entry_count
= cpu_to_le16(count
);
3314 cifs_dbg(FYI
, "unknown ACL type %d\n", acl_type
);
3317 for (i
= 0; i
< count
; i
++) {
3318 rc
= convert_ace_to_cifs_ace(&cifs_acl
->ace_array
[i
],
3319 &local_acl
->a_entries
[i
]);
3321 /* ACE not converted */
3326 rc
= (__u16
)(count
* sizeof(struct cifs_posix_ace
));
3327 rc
+= sizeof(struct cifs_posix_acl
);
3328 /* BB add check to make sure ACL does not overflow SMB */
3334 CIFSSMBGetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3335 const unsigned char *searchName
,
3336 char *acl_inf
, const int buflen
, const int acl_type
,
3337 const struct nls_table
*nls_codepage
, int remap
)
3339 /* SMB_QUERY_POSIX_ACL */
3340 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3341 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3345 __u16 params
, byte_count
;
3347 cifs_dbg(FYI
, "In GetPosixACL (Unix) for path %s\n", searchName
);
3350 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3355 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3357 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3358 searchName
, PATH_MAX
, nls_codepage
,
3360 name_len
++; /* trailing null */
3362 pSMB
->FileName
[name_len
] = 0;
3363 pSMB
->FileName
[name_len
+1] = 0;
3364 } else { /* BB improve the check for buffer overruns BB */
3365 name_len
= strnlen(searchName
, PATH_MAX
);
3366 name_len
++; /* trailing null */
3367 strncpy(pSMB
->FileName
, searchName
, name_len
);
3370 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3371 pSMB
->TotalDataCount
= 0;
3372 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3373 /* BB find exact max data count below from sess structure BB */
3374 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3375 pSMB
->MaxSetupCount
= 0;
3379 pSMB
->Reserved2
= 0;
3380 pSMB
->ParameterOffset
= cpu_to_le16(
3381 offsetof(struct smb_com_transaction2_qpi_req
,
3382 InformationLevel
) - 4);
3383 pSMB
->DataCount
= 0;
3384 pSMB
->DataOffset
= 0;
3385 pSMB
->SetupCount
= 1;
3386 pSMB
->Reserved3
= 0;
3387 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3388 byte_count
= params
+ 1 /* pad */ ;
3389 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3390 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3391 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_ACL
);
3392 pSMB
->Reserved4
= 0;
3393 inc_rfc1001_len(pSMB
, byte_count
);
3394 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3396 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3397 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3398 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3400 cifs_dbg(FYI
, "Send error in Query POSIX ACL = %d\n", rc
);
3402 /* decode response */
3404 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3405 /* BB also check enough total bytes returned */
3406 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3407 rc
= -EIO
; /* bad smb */
3409 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3410 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3411 rc
= cifs_copy_posix_acl(acl_inf
,
3412 (char *)&pSMBr
->hdr
.Protocol
+data_offset
,
3413 buflen
, acl_type
, count
);
3416 cifs_buf_release(pSMB
);
3423 CIFSSMBSetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3424 const unsigned char *fileName
,
3425 const char *local_acl
, const int buflen
,
3427 const struct nls_table
*nls_codepage
, int remap
)
3429 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3430 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3434 int bytes_returned
= 0;
3435 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
3437 cifs_dbg(FYI
, "In SetPosixACL (Unix) for path %s\n", fileName
);
3439 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3443 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3445 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
3446 PATH_MAX
, nls_codepage
, remap
);
3447 name_len
++; /* trailing null */
3449 } else { /* BB improve the check for buffer overruns BB */
3450 name_len
= strnlen(fileName
, PATH_MAX
);
3451 name_len
++; /* trailing null */
3452 strncpy(pSMB
->FileName
, fileName
, name_len
);
3454 params
= 6 + name_len
;
3455 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3456 /* BB find max SMB size from sess */
3457 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3458 pSMB
->MaxSetupCount
= 0;
3462 pSMB
->Reserved2
= 0;
3463 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3464 InformationLevel
) - 4;
3465 offset
= param_offset
+ params
;
3466 parm_data
= ((char *) &pSMB
->hdr
.Protocol
) + offset
;
3467 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3469 /* convert to on the wire format for POSIX ACL */
3470 data_count
= ACL_to_cifs_posix(parm_data
, local_acl
, buflen
, acl_type
);
3472 if (data_count
== 0) {
3474 goto setACLerrorExit
;
3476 pSMB
->DataOffset
= cpu_to_le16(offset
);
3477 pSMB
->SetupCount
= 1;
3478 pSMB
->Reserved3
= 0;
3479 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3480 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_ACL
);
3481 byte_count
= 3 /* pad */ + params
+ data_count
;
3482 pSMB
->DataCount
= cpu_to_le16(data_count
);
3483 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3484 pSMB
->ParameterCount
= cpu_to_le16(params
);
3485 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3486 pSMB
->Reserved4
= 0;
3487 inc_rfc1001_len(pSMB
, byte_count
);
3488 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3489 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3490 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3492 cifs_dbg(FYI
, "Set POSIX ACL returned %d\n", rc
);
3495 cifs_buf_release(pSMB
);
3501 /* BB fix tabs in this function FIXME BB */
3503 CIFSGetExtAttr(const unsigned int xid
, struct cifs_tcon
*tcon
,
3504 const int netfid
, __u64
*pExtAttrBits
, __u64
*pMask
)
3507 struct smb_t2_qfi_req
*pSMB
= NULL
;
3508 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3510 __u16 params
, byte_count
;
3512 cifs_dbg(FYI
, "In GetExtAttr\n");
3517 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3522 params
= 2 /* level */ + 2 /* fid */;
3523 pSMB
->t2
.TotalDataCount
= 0;
3524 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3525 /* BB find exact max data count below from sess structure BB */
3526 pSMB
->t2
.MaxDataCount
= cpu_to_le16(4000);
3527 pSMB
->t2
.MaxSetupCount
= 0;
3528 pSMB
->t2
.Reserved
= 0;
3530 pSMB
->t2
.Timeout
= 0;
3531 pSMB
->t2
.Reserved2
= 0;
3532 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3534 pSMB
->t2
.DataCount
= 0;
3535 pSMB
->t2
.DataOffset
= 0;
3536 pSMB
->t2
.SetupCount
= 1;
3537 pSMB
->t2
.Reserved3
= 0;
3538 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3539 byte_count
= params
+ 1 /* pad */ ;
3540 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3541 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3542 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_ATTR_FLAGS
);
3545 inc_rfc1001_len(pSMB
, byte_count
);
3546 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3548 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3549 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3551 cifs_dbg(FYI
, "error %d in GetExtAttr\n", rc
);
3553 /* decode response */
3554 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3555 /* BB also check enough total bytes returned */
3556 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3557 /* If rc should we check for EOPNOSUPP and
3558 disable the srvino flag? or in caller? */
3559 rc
= -EIO
; /* bad smb */
3561 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3562 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3563 struct file_chattr_info
*pfinfo
;
3564 /* BB Do we need a cast or hash here ? */
3566 cifs_dbg(FYI
, "Illegal size ret in GetExtAttr\n");
3570 pfinfo
= (struct file_chattr_info
*)
3571 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
3572 *pExtAttrBits
= le64_to_cpu(pfinfo
->mode
);
3573 *pMask
= le64_to_cpu(pfinfo
->mask
);
3577 cifs_buf_release(pSMB
);
3579 goto GetExtAttrRetry
;
3583 #endif /* CONFIG_POSIX */
3585 #ifdef CONFIG_CIFS_ACL
3587 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3588 * all NT TRANSACTS that we init here have total parm and data under about 400
3589 * bytes (to fit in small cifs buffer size), which is the case so far, it
3590 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3591 * returned setup area) and MaxParameterCount (returned parms size) must be set
3595 smb_init_nttransact(const __u16 sub_command
, const int setup_count
,
3596 const int parm_len
, struct cifs_tcon
*tcon
,
3601 struct smb_com_ntransact_req
*pSMB
;
3603 rc
= small_smb_init(SMB_COM_NT_TRANSACT
, 19 + setup_count
, tcon
,
3607 *ret_buf
= (void *)pSMB
;
3609 pSMB
->TotalParameterCount
= cpu_to_le32(parm_len
);
3610 pSMB
->TotalDataCount
= 0;
3611 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3612 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3613 pSMB
->DataCount
= pSMB
->TotalDataCount
;
3614 temp_offset
= offsetof(struct smb_com_ntransact_req
, Parms
) +
3615 (setup_count
* 2) - 4 /* for rfc1001 length itself */;
3616 pSMB
->ParameterOffset
= cpu_to_le32(temp_offset
);
3617 pSMB
->DataOffset
= cpu_to_le32(temp_offset
+ parm_len
);
3618 pSMB
->SetupCount
= setup_count
; /* no need to le convert byte fields */
3619 pSMB
->SubCommand
= cpu_to_le16(sub_command
);
3624 validate_ntransact(char *buf
, char **ppparm
, char **ppdata
,
3625 __u32
*pparmlen
, __u32
*pdatalen
)
3628 __u32 data_count
, data_offset
, parm_count
, parm_offset
;
3629 struct smb_com_ntransact_rsp
*pSMBr
;
3638 pSMBr
= (struct smb_com_ntransact_rsp
*)buf
;
3640 bcc
= get_bcc(&pSMBr
->hdr
);
3641 end_of_smb
= 2 /* sizeof byte count */ + bcc
+
3642 (char *)&pSMBr
->ByteCount
;
3644 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3645 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3646 parm_offset
= le32_to_cpu(pSMBr
->ParameterOffset
);
3647 parm_count
= le32_to_cpu(pSMBr
->ParameterCount
);
3649 *ppparm
= (char *)&pSMBr
->hdr
.Protocol
+ parm_offset
;
3650 *ppdata
= (char *)&pSMBr
->hdr
.Protocol
+ data_offset
;
3652 /* should we also check that parm and data areas do not overlap? */
3653 if (*ppparm
> end_of_smb
) {
3654 cifs_dbg(FYI
, "parms start after end of smb\n");
3656 } else if (parm_count
+ *ppparm
> end_of_smb
) {
3657 cifs_dbg(FYI
, "parm end after end of smb\n");
3659 } else if (*ppdata
> end_of_smb
) {
3660 cifs_dbg(FYI
, "data starts after end of smb\n");
3662 } else if (data_count
+ *ppdata
> end_of_smb
) {
3663 cifs_dbg(FYI
, "data %p + count %d (%p) past smb end %p start %p\n",
3664 *ppdata
, data_count
, (data_count
+ *ppdata
),
3667 } else if (parm_count
+ data_count
> bcc
) {
3668 cifs_dbg(FYI
, "parm count and data count larger than SMB\n");
3671 *pdatalen
= data_count
;
3672 *pparmlen
= parm_count
;
3676 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3678 CIFSSMBGetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3679 struct cifs_ntsd
**acl_inf
, __u32
*pbuflen
)
3683 QUERY_SEC_DESC_REQ
*pSMB
;
3686 cifs_dbg(FYI
, "GetCifsACL\n");
3691 rc
= smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC
, 0,
3692 8 /* parm len */, tcon
, (void **) &pSMB
);
3696 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3697 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3698 pSMB
->MaxSetupCount
= 0;
3699 pSMB
->Fid
= fid
; /* file handle always le */
3700 pSMB
->AclFlags
= cpu_to_le32(CIFS_ACL_OWNER
| CIFS_ACL_GROUP
|
3702 pSMB
->ByteCount
= cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3703 inc_rfc1001_len(pSMB
, 11);
3704 iov
[0].iov_base
= (char *)pSMB
;
3705 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
3707 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovec */, &buf_type
,
3709 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3711 cifs_dbg(FYI
, "Send error in QuerySecDesc = %d\n", rc
);
3712 } else { /* decode response */
3716 struct smb_com_ntransact_rsp
*pSMBr
;
3719 /* validate_nttransact */
3720 rc
= validate_ntransact(iov
[0].iov_base
, (char **)&parm
,
3721 &pdata
, &parm_len
, pbuflen
);
3724 pSMBr
= (struct smb_com_ntransact_rsp
*)iov
[0].iov_base
;
3726 cifs_dbg(FYI
, "smb %p parm %p data %p\n",
3727 pSMBr
, parm
, *acl_inf
);
3729 if (le32_to_cpu(pSMBr
->ParameterCount
) != 4) {
3730 rc
= -EIO
; /* bad smb */
3735 /* BB check that data area is minimum length and as big as acl_len */
3737 acl_len
= le32_to_cpu(*parm
);
3738 if (acl_len
!= *pbuflen
) {
3739 cifs_dbg(VFS
, "acl length %d does not match %d\n",
3741 if (*pbuflen
> acl_len
)
3745 /* check if buffer is big enough for the acl
3746 header followed by the smallest SID */
3747 if ((*pbuflen
< sizeof(struct cifs_ntsd
) + 8) ||
3748 (*pbuflen
>= 64 * 1024)) {
3749 cifs_dbg(VFS
, "bad acl length %d\n", *pbuflen
);
3753 *acl_inf
= kmemdup(pdata
, *pbuflen
, GFP_KERNEL
);
3754 if (*acl_inf
== NULL
) {
3761 if (buf_type
== CIFS_SMALL_BUFFER
)
3762 cifs_small_buf_release(iov
[0].iov_base
);
3763 else if (buf_type
== CIFS_LARGE_BUFFER
)
3764 cifs_buf_release(iov
[0].iov_base
);
3765 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3770 CIFSSMBSetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3771 struct cifs_ntsd
*pntsd
, __u32 acllen
, int aclflag
)
3773 __u16 byte_count
, param_count
, data_count
, param_offset
, data_offset
;
3775 int bytes_returned
= 0;
3776 SET_SEC_DESC_REQ
*pSMB
= NULL
;
3780 rc
= smb_init(SMB_COM_NT_TRANSACT
, 19, tcon
, (void **) &pSMB
, &pSMBr
);
3784 pSMB
->MaxSetupCount
= 0;
3788 param_offset
= offsetof(struct smb_com_transaction_ssec_req
, Fid
) - 4;
3789 data_count
= acllen
;
3790 data_offset
= param_offset
+ param_count
;
3791 byte_count
= 3 /* pad */ + param_count
;
3793 pSMB
->DataCount
= cpu_to_le32(data_count
);
3794 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3795 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3796 pSMB
->MaxDataCount
= cpu_to_le32(16384);
3797 pSMB
->ParameterCount
= cpu_to_le32(param_count
);
3798 pSMB
->ParameterOffset
= cpu_to_le32(param_offset
);
3799 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3800 pSMB
->DataOffset
= cpu_to_le32(data_offset
);
3801 pSMB
->SetupCount
= 0;
3802 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC
);
3803 pSMB
->ByteCount
= cpu_to_le16(byte_count
+data_count
);
3805 pSMB
->Fid
= fid
; /* file handle always le */
3806 pSMB
->Reserved2
= 0;
3807 pSMB
->AclFlags
= cpu_to_le32(aclflag
);
3809 if (pntsd
&& acllen
) {
3810 memcpy((char *)pSMBr
+ offsetof(struct smb_hdr
, Protocol
) +
3811 data_offset
, pntsd
, acllen
);
3812 inc_rfc1001_len(pSMB
, byte_count
+ data_count
);
3814 inc_rfc1001_len(pSMB
, byte_count
);
3816 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3817 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3819 cifs_dbg(FYI
, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3820 bytes_returned
, rc
);
3822 cifs_dbg(FYI
, "Set CIFS ACL returned %d\n", rc
);
3823 cifs_buf_release(pSMB
);
3826 goto setCifsAclRetry
;
3831 #endif /* CONFIG_CIFS_ACL */
3833 /* Legacy Query Path Information call for lookup to old servers such
3836 SMBQueryInformation(const unsigned int xid
, struct cifs_tcon
*tcon
,
3837 const char *search_name
, FILE_ALL_INFO
*data
,
3838 const struct nls_table
*nls_codepage
, int remap
)
3840 QUERY_INFORMATION_REQ
*pSMB
;
3841 QUERY_INFORMATION_RSP
*pSMBr
;
3846 cifs_dbg(FYI
, "In SMBQPath path %s\n", search_name
);
3848 rc
= smb_init(SMB_COM_QUERY_INFORMATION
, 0, tcon
, (void **) &pSMB
,
3853 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3855 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3856 search_name
, PATH_MAX
, nls_codepage
,
3858 name_len
++; /* trailing null */
3861 name_len
= strnlen(search_name
, PATH_MAX
);
3862 name_len
++; /* trailing null */
3863 strncpy(pSMB
->FileName
, search_name
, name_len
);
3865 pSMB
->BufferFormat
= 0x04;
3866 name_len
++; /* account for buffer type byte */
3867 inc_rfc1001_len(pSMB
, (__u16
)name_len
);
3868 pSMB
->ByteCount
= cpu_to_le16(name_len
);
3870 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3871 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3873 cifs_dbg(FYI
, "Send error in QueryInfo = %d\n", rc
);
3876 __u32 time
= le32_to_cpu(pSMBr
->last_write_time
);
3878 /* decode response */
3879 /* BB FIXME - add time zone adjustment BB */
3880 memset(data
, 0, sizeof(FILE_ALL_INFO
));
3883 /* decode time fields */
3884 data
->ChangeTime
= cpu_to_le64(cifs_UnixTimeToNT(ts
));
3885 data
->LastWriteTime
= data
->ChangeTime
;
3886 data
->LastAccessTime
= 0;
3887 data
->AllocationSize
=
3888 cpu_to_le64(le32_to_cpu(pSMBr
->size
));
3889 data
->EndOfFile
= data
->AllocationSize
;
3891 cpu_to_le32(le16_to_cpu(pSMBr
->attr
));
3893 rc
= -EIO
; /* bad buffer passed in */
3895 cifs_buf_release(pSMB
);
3904 CIFSSMBQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
3905 u16 netfid
, FILE_ALL_INFO
*pFindData
)
3907 struct smb_t2_qfi_req
*pSMB
= NULL
;
3908 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3911 __u16 params
, byte_count
;
3914 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3919 params
= 2 /* level */ + 2 /* fid */;
3920 pSMB
->t2
.TotalDataCount
= 0;
3921 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3922 /* BB find exact max data count below from sess structure BB */
3923 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3924 pSMB
->t2
.MaxSetupCount
= 0;
3925 pSMB
->t2
.Reserved
= 0;
3927 pSMB
->t2
.Timeout
= 0;
3928 pSMB
->t2
.Reserved2
= 0;
3929 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3931 pSMB
->t2
.DataCount
= 0;
3932 pSMB
->t2
.DataOffset
= 0;
3933 pSMB
->t2
.SetupCount
= 1;
3934 pSMB
->t2
.Reserved3
= 0;
3935 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3936 byte_count
= params
+ 1 /* pad */ ;
3937 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3938 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3939 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
3942 inc_rfc1001_len(pSMB
, byte_count
);
3944 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3945 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3947 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
3948 } else { /* decode response */
3949 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3951 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
3953 else if (get_bcc(&pSMBr
->hdr
) < 40)
3954 rc
= -EIO
; /* bad smb */
3955 else if (pFindData
) {
3956 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3957 memcpy((char *) pFindData
,
3958 (char *) &pSMBr
->hdr
.Protocol
+
3959 data_offset
, sizeof(FILE_ALL_INFO
));
3963 cifs_buf_release(pSMB
);
3965 goto QFileInfoRetry
;
3971 CIFSSMBQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
3972 const char *search_name
, FILE_ALL_INFO
*data
,
3973 int legacy
/* old style infolevel */,
3974 const struct nls_table
*nls_codepage
, int remap
)
3976 /* level 263 SMB_QUERY_FILE_ALL_INFO */
3977 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3978 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3982 __u16 params
, byte_count
;
3984 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3986 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3991 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3993 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, search_name
,
3994 PATH_MAX
, nls_codepage
, remap
);
3995 name_len
++; /* trailing null */
3997 } else { /* BB improve the check for buffer overruns BB */
3998 name_len
= strnlen(search_name
, PATH_MAX
);
3999 name_len
++; /* trailing null */
4000 strncpy(pSMB
->FileName
, search_name
, name_len
);
4003 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4004 pSMB
->TotalDataCount
= 0;
4005 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4006 /* BB find exact max SMB PDU from sess structure BB */
4007 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4008 pSMB
->MaxSetupCount
= 0;
4012 pSMB
->Reserved2
= 0;
4013 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4014 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4015 pSMB
->DataCount
= 0;
4016 pSMB
->DataOffset
= 0;
4017 pSMB
->SetupCount
= 1;
4018 pSMB
->Reserved3
= 0;
4019 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4020 byte_count
= params
+ 1 /* pad */ ;
4021 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4022 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4024 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
4026 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4027 pSMB
->Reserved4
= 0;
4028 inc_rfc1001_len(pSMB
, byte_count
);
4029 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4031 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4032 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4034 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4035 } else { /* decode response */
4036 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4038 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4040 else if (!legacy
&& get_bcc(&pSMBr
->hdr
) < 40)
4041 rc
= -EIO
; /* bad smb */
4042 else if (legacy
&& get_bcc(&pSMBr
->hdr
) < 24)
4043 rc
= -EIO
; /* 24 or 26 expected but we do not read
4047 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4050 * On legacy responses we do not read the last field,
4051 * EAsize, fortunately since it varies by subdialect and
4052 * also note it differs on Set vs Get, ie two bytes or 4
4053 * bytes depending but we don't care here.
4056 size
= sizeof(FILE_INFO_STANDARD
);
4058 size
= sizeof(FILE_ALL_INFO
);
4059 memcpy((char *) data
, (char *) &pSMBr
->hdr
.Protocol
+
4064 cifs_buf_release(pSMB
);
4066 goto QPathInfoRetry
;
4072 CIFSSMBUnixQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4073 u16 netfid
, FILE_UNIX_BASIC_INFO
*pFindData
)
4075 struct smb_t2_qfi_req
*pSMB
= NULL
;
4076 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4079 __u16 params
, byte_count
;
4082 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4087 params
= 2 /* level */ + 2 /* fid */;
4088 pSMB
->t2
.TotalDataCount
= 0;
4089 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4090 /* BB find exact max data count below from sess structure BB */
4091 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4092 pSMB
->t2
.MaxSetupCount
= 0;
4093 pSMB
->t2
.Reserved
= 0;
4095 pSMB
->t2
.Timeout
= 0;
4096 pSMB
->t2
.Reserved2
= 0;
4097 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4099 pSMB
->t2
.DataCount
= 0;
4100 pSMB
->t2
.DataOffset
= 0;
4101 pSMB
->t2
.SetupCount
= 1;
4102 pSMB
->t2
.Reserved3
= 0;
4103 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4104 byte_count
= params
+ 1 /* pad */ ;
4105 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4106 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4107 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4110 inc_rfc1001_len(pSMB
, byte_count
);
4112 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4113 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4115 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4116 } else { /* decode response */
4117 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4119 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4120 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4121 rc
= -EIO
; /* bad smb */
4123 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4124 memcpy((char *) pFindData
,
4125 (char *) &pSMBr
->hdr
.Protocol
+
4127 sizeof(FILE_UNIX_BASIC_INFO
));
4131 cifs_buf_release(pSMB
);
4133 goto UnixQFileInfoRetry
;
4139 CIFSSMBUnixQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4140 const unsigned char *searchName
,
4141 FILE_UNIX_BASIC_INFO
*pFindData
,
4142 const struct nls_table
*nls_codepage
, int remap
)
4144 /* SMB_QUERY_FILE_UNIX_BASIC */
4145 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4146 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4148 int bytes_returned
= 0;
4150 __u16 params
, byte_count
;
4152 cifs_dbg(FYI
, "In QPathInfo (Unix) the path %s\n", searchName
);
4154 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4159 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4161 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4162 PATH_MAX
, nls_codepage
, remap
);
4163 name_len
++; /* trailing null */
4165 } else { /* BB improve the check for buffer overruns BB */
4166 name_len
= strnlen(searchName
, PATH_MAX
);
4167 name_len
++; /* trailing null */
4168 strncpy(pSMB
->FileName
, searchName
, name_len
);
4171 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4172 pSMB
->TotalDataCount
= 0;
4173 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4174 /* BB find exact max SMB PDU from sess structure BB */
4175 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4176 pSMB
->MaxSetupCount
= 0;
4180 pSMB
->Reserved2
= 0;
4181 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4182 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4183 pSMB
->DataCount
= 0;
4184 pSMB
->DataOffset
= 0;
4185 pSMB
->SetupCount
= 1;
4186 pSMB
->Reserved3
= 0;
4187 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4188 byte_count
= params
+ 1 /* pad */ ;
4189 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4190 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4191 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4192 pSMB
->Reserved4
= 0;
4193 inc_rfc1001_len(pSMB
, byte_count
);
4194 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4196 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4197 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4199 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4200 } else { /* decode response */
4201 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4203 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4204 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4205 rc
= -EIO
; /* bad smb */
4207 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4208 memcpy((char *) pFindData
,
4209 (char *) &pSMBr
->hdr
.Protocol
+
4211 sizeof(FILE_UNIX_BASIC_INFO
));
4214 cifs_buf_release(pSMB
);
4216 goto UnixQPathInfoRetry
;
4221 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4223 CIFSFindFirst(const unsigned int xid
, struct cifs_tcon
*tcon
,
4224 const char *searchName
, struct cifs_sb_info
*cifs_sb
,
4225 __u16
*pnetfid
, __u16 search_flags
,
4226 struct cifs_search_info
*psrch_inf
, bool msearch
)
4228 /* level 257 SMB_ */
4229 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
4230 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
4231 T2_FFIRST_RSP_PARMS
*parms
;
4233 int bytes_returned
= 0;
4234 int name_len
, remap
;
4235 __u16 params
, byte_count
;
4236 struct nls_table
*nls_codepage
;
4238 cifs_dbg(FYI
, "In FindFirst for %s\n", searchName
);
4241 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4246 nls_codepage
= cifs_sb
->local_nls
;
4247 remap
= cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
;
4249 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4251 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4252 PATH_MAX
, nls_codepage
, remap
);
4253 /* We can not add the asterik earlier in case
4254 it got remapped to 0xF03A as if it were part of the
4255 directory name instead of a wildcard */
4258 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4259 pSMB
->FileName
[name_len
+1] = 0;
4260 pSMB
->FileName
[name_len
+2] = '*';
4261 pSMB
->FileName
[name_len
+3] = 0;
4262 name_len
+= 4; /* now the trailing null */
4263 /* null terminate just in case */
4264 pSMB
->FileName
[name_len
] = 0;
4265 pSMB
->FileName
[name_len
+1] = 0;
4268 } else { /* BB add check for overrun of SMB buf BB */
4269 name_len
= strnlen(searchName
, PATH_MAX
);
4270 /* BB fix here and in unicode clause above ie
4271 if (name_len > buffersize-header)
4272 free buffer exit; BB */
4273 strncpy(pSMB
->FileName
, searchName
, name_len
);
4275 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4276 pSMB
->FileName
[name_len
+1] = '*';
4277 pSMB
->FileName
[name_len
+2] = 0;
4282 params
= 12 + name_len
/* includes null */ ;
4283 pSMB
->TotalDataCount
= 0; /* no EAs */
4284 pSMB
->MaxParameterCount
= cpu_to_le16(10);
4285 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4286 pSMB
->MaxSetupCount
= 0;
4290 pSMB
->Reserved2
= 0;
4291 byte_count
= params
+ 1 /* pad */ ;
4292 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4293 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4294 pSMB
->ParameterOffset
= cpu_to_le16(
4295 offsetof(struct smb_com_transaction2_ffirst_req
, SearchAttributes
)
4297 pSMB
->DataCount
= 0;
4298 pSMB
->DataOffset
= 0;
4299 pSMB
->SetupCount
= 1; /* one byte, no need to make endian neutral */
4300 pSMB
->Reserved3
= 0;
4301 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
4302 pSMB
->SearchAttributes
=
4303 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
4305 pSMB
->SearchCount
= cpu_to_le16(CIFSMaxBufSize
/sizeof(FILE_UNIX_INFO
));
4306 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4307 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4309 /* BB what should we set StorageType to? Does it matter? BB */
4310 pSMB
->SearchStorageType
= 0;
4311 inc_rfc1001_len(pSMB
, byte_count
);
4312 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4314 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4315 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4316 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_ffirst
);
4318 if (rc
) {/* BB add logic to retry regular search if Unix search
4319 rejected unexpectedly by server */
4320 /* BB Add code to handle unsupported level rc */
4321 cifs_dbg(FYI
, "Error in FindFirst = %d\n", rc
);
4323 cifs_buf_release(pSMB
);
4325 /* BB eventually could optimize out free and realloc of buf */
4328 goto findFirstRetry
;
4329 } else { /* decode response */
4330 /* BB remember to free buffer if error BB */
4331 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4335 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4336 psrch_inf
->unicode
= true;
4338 psrch_inf
->unicode
= false;
4340 psrch_inf
->ntwrk_buf_start
= (char *)pSMBr
;
4341 psrch_inf
->smallBuf
= 0;
4342 psrch_inf
->srch_entries_start
=
4343 (char *) &pSMBr
->hdr
.Protocol
+
4344 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4345 parms
= (T2_FFIRST_RSP_PARMS
*)((char *) &pSMBr
->hdr
.Protocol
+
4346 le16_to_cpu(pSMBr
->t2
.ParameterOffset
));
4348 if (parms
->EndofSearch
)
4349 psrch_inf
->endOfSearch
= true;
4351 psrch_inf
->endOfSearch
= false;
4353 psrch_inf
->entries_in_buffer
=
4354 le16_to_cpu(parms
->SearchCount
);
4355 psrch_inf
->index_of_last_entry
= 2 /* skip . and .. */ +
4356 psrch_inf
->entries_in_buffer
;
4357 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4358 if (CIFSMaxBufSize
< lnoff
) {
4359 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4360 psrch_inf
->last_entry
= NULL
;
4364 psrch_inf
->last_entry
= psrch_inf
->srch_entries_start
+
4368 *pnetfid
= parms
->SearchHandle
;
4370 cifs_buf_release(pSMB
);
4377 int CIFSFindNext(const unsigned int xid
, struct cifs_tcon
*tcon
,
4378 __u16 searchHandle
, __u16 search_flags
,
4379 struct cifs_search_info
*psrch_inf
)
4381 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
4382 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
4383 T2_FNEXT_RSP_PARMS
*parms
;
4384 char *response_data
;
4387 unsigned int name_len
;
4388 __u16 params
, byte_count
;
4390 cifs_dbg(FYI
, "In FindNext\n");
4392 if (psrch_inf
->endOfSearch
)
4395 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4400 params
= 14; /* includes 2 bytes of null string, converted to LE below*/
4402 pSMB
->TotalDataCount
= 0; /* no EAs */
4403 pSMB
->MaxParameterCount
= cpu_to_le16(8);
4404 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4405 pSMB
->MaxSetupCount
= 0;
4409 pSMB
->Reserved2
= 0;
4410 pSMB
->ParameterOffset
= cpu_to_le16(
4411 offsetof(struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
4412 pSMB
->DataCount
= 0;
4413 pSMB
->DataOffset
= 0;
4414 pSMB
->SetupCount
= 1;
4415 pSMB
->Reserved3
= 0;
4416 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
4417 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
4419 cpu_to_le16(CIFSMaxBufSize
/ sizeof(FILE_UNIX_INFO
));
4420 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4421 pSMB
->ResumeKey
= psrch_inf
->resume_key
;
4422 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4424 name_len
= psrch_inf
->resume_name_len
;
4426 if (name_len
< PATH_MAX
) {
4427 memcpy(pSMB
->ResumeFileName
, psrch_inf
->presume_name
, name_len
);
4428 byte_count
+= name_len
;
4429 /* 14 byte parm len above enough for 2 byte null terminator */
4430 pSMB
->ResumeFileName
[name_len
] = 0;
4431 pSMB
->ResumeFileName
[name_len
+1] = 0;
4434 goto FNext2_err_exit
;
4436 byte_count
= params
+ 1 /* pad */ ;
4437 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4438 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4439 inc_rfc1001_len(pSMB
, byte_count
);
4440 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4442 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4443 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4444 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fnext
);
4447 psrch_inf
->endOfSearch
= true;
4448 cifs_buf_release(pSMB
);
4449 rc
= 0; /* search probably was closed at end of search*/
4451 cifs_dbg(FYI
, "FindNext returned = %d\n", rc
);
4452 } else { /* decode response */
4453 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4458 /* BB fixme add lock for file (srch_info) struct here */
4459 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4460 psrch_inf
->unicode
= true;
4462 psrch_inf
->unicode
= false;
4463 response_data
= (char *) &pSMBr
->hdr
.Protocol
+
4464 le16_to_cpu(pSMBr
->t2
.ParameterOffset
);
4465 parms
= (T2_FNEXT_RSP_PARMS
*)response_data
;
4466 response_data
= (char *)&pSMBr
->hdr
.Protocol
+
4467 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4468 if (psrch_inf
->smallBuf
)
4469 cifs_small_buf_release(
4470 psrch_inf
->ntwrk_buf_start
);
4472 cifs_buf_release(psrch_inf
->ntwrk_buf_start
);
4473 psrch_inf
->srch_entries_start
= response_data
;
4474 psrch_inf
->ntwrk_buf_start
= (char *)pSMB
;
4475 psrch_inf
->smallBuf
= 0;
4476 if (parms
->EndofSearch
)
4477 psrch_inf
->endOfSearch
= true;
4479 psrch_inf
->endOfSearch
= false;
4480 psrch_inf
->entries_in_buffer
=
4481 le16_to_cpu(parms
->SearchCount
);
4482 psrch_inf
->index_of_last_entry
+=
4483 psrch_inf
->entries_in_buffer
;
4484 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4485 if (CIFSMaxBufSize
< lnoff
) {
4486 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4487 psrch_inf
->last_entry
= NULL
;
4490 psrch_inf
->last_entry
=
4491 psrch_inf
->srch_entries_start
+ lnoff
;
4493 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4494 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4496 /* BB fixme add unlock here */
4501 /* BB On error, should we leave previous search buf (and count and
4502 last entry fields) intact or free the previous one? */
4504 /* Note: On -EAGAIN error only caller can retry on handle based calls
4505 since file handle passed in no longer valid */
4508 cifs_buf_release(pSMB
);
4513 CIFSFindClose(const unsigned int xid
, struct cifs_tcon
*tcon
,
4514 const __u16 searchHandle
)
4517 FINDCLOSE_REQ
*pSMB
= NULL
;
4519 cifs_dbg(FYI
, "In CIFSSMBFindClose\n");
4520 rc
= small_smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **)&pSMB
);
4522 /* no sense returning error if session restarted
4523 as file handle has been closed */
4529 pSMB
->FileID
= searchHandle
;
4530 pSMB
->ByteCount
= 0;
4531 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
4533 cifs_dbg(VFS
, "Send error in FindClose = %d\n", rc
);
4535 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fclose
);
4537 /* Since session is dead, search handle closed on server already */
4545 CIFSGetSrvInodeNumber(const unsigned int xid
, struct cifs_tcon
*tcon
,
4546 const char *search_name
, __u64
*inode_number
,
4547 const struct nls_table
*nls_codepage
, int remap
)
4550 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4551 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4552 int name_len
, bytes_returned
;
4553 __u16 params
, byte_count
;
4555 cifs_dbg(FYI
, "In GetSrvInodeNum for %s\n", search_name
);
4559 GetInodeNumberRetry
:
4560 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4565 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4567 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4568 search_name
, PATH_MAX
, nls_codepage
,
4570 name_len
++; /* trailing null */
4572 } else { /* BB improve the check for buffer overruns BB */
4573 name_len
= strnlen(search_name
, PATH_MAX
);
4574 name_len
++; /* trailing null */
4575 strncpy(pSMB
->FileName
, search_name
, name_len
);
4578 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
4579 pSMB
->TotalDataCount
= 0;
4580 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4581 /* BB find exact max data count below from sess structure BB */
4582 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4583 pSMB
->MaxSetupCount
= 0;
4587 pSMB
->Reserved2
= 0;
4588 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4589 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4590 pSMB
->DataCount
= 0;
4591 pSMB
->DataOffset
= 0;
4592 pSMB
->SetupCount
= 1;
4593 pSMB
->Reserved3
= 0;
4594 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4595 byte_count
= params
+ 1 /* pad */ ;
4596 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4597 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4598 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO
);
4599 pSMB
->Reserved4
= 0;
4600 inc_rfc1001_len(pSMB
, byte_count
);
4601 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4603 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4604 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4606 cifs_dbg(FYI
, "error %d in QueryInternalInfo\n", rc
);
4608 /* decode response */
4609 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4610 /* BB also check enough total bytes returned */
4611 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
4612 /* If rc should we check for EOPNOSUPP and
4613 disable the srvino flag? or in caller? */
4614 rc
= -EIO
; /* bad smb */
4616 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4617 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
4618 struct file_internal_info
*pfinfo
;
4619 /* BB Do we need a cast or hash here ? */
4621 cifs_dbg(FYI
, "Illegal size ret in QryIntrnlInf\n");
4623 goto GetInodeNumOut
;
4625 pfinfo
= (struct file_internal_info
*)
4626 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
4627 *inode_number
= le64_to_cpu(pfinfo
->UniqueId
);
4631 cifs_buf_release(pSMB
);
4633 goto GetInodeNumberRetry
;
4637 /* parses DFS refferal V3 structure
4638 * caller is responsible for freeing target_nodes
4641 * on failure - errno
4644 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
,
4645 unsigned int *num_of_nodes
,
4646 struct dfs_info3_param
**target_nodes
,
4647 const struct nls_table
*nls_codepage
, int remap
,
4648 const char *searchName
)
4653 struct dfs_referral_level_3
*ref
;
4655 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4659 *num_of_nodes
= le16_to_cpu(pSMBr
->NumberOfReferrals
);
4661 if (*num_of_nodes
< 1) {
4662 cifs_dbg(VFS
, "num_referrals: must be at least > 0, but we get num_referrals = %d\n",
4665 goto parse_DFS_referrals_exit
;
4668 ref
= (struct dfs_referral_level_3
*) &(pSMBr
->referrals
);
4669 if (ref
->VersionNumber
!= cpu_to_le16(3)) {
4670 cifs_dbg(VFS
, "Referrals of V%d version are not supported, should be V3\n",
4671 le16_to_cpu(ref
->VersionNumber
));
4673 goto parse_DFS_referrals_exit
;
4676 /* get the upper boundary of the resp buffer */
4677 data_end
= (char *)(&(pSMBr
->PathConsumed
)) +
4678 le16_to_cpu(pSMBr
->t2
.DataCount
);
4680 cifs_dbg(FYI
, "num_referrals: %d dfs flags: 0x%x ...\n",
4681 *num_of_nodes
, le32_to_cpu(pSMBr
->DFSFlags
));
4683 *target_nodes
= kcalloc(*num_of_nodes
, sizeof(struct dfs_info3_param
),
4685 if (*target_nodes
== NULL
) {
4687 goto parse_DFS_referrals_exit
;
4690 /* collect necessary data from referrals */
4691 for (i
= 0; i
< *num_of_nodes
; i
++) {
4694 struct dfs_info3_param
*node
= (*target_nodes
)+i
;
4696 node
->flags
= le32_to_cpu(pSMBr
->DFSFlags
);
4698 __le16
*tmp
= kmalloc(strlen(searchName
)*2 + 2,
4702 goto parse_DFS_referrals_exit
;
4704 cifsConvertToUTF16((__le16
*) tmp
, searchName
,
4705 PATH_MAX
, nls_codepage
, remap
);
4706 node
->path_consumed
= cifs_utf16_bytes(tmp
,
4707 le16_to_cpu(pSMBr
->PathConsumed
),
4711 node
->path_consumed
= le16_to_cpu(pSMBr
->PathConsumed
);
4713 node
->server_type
= le16_to_cpu(ref
->ServerType
);
4714 node
->ref_flag
= le16_to_cpu(ref
->ReferralEntryFlags
);
4717 temp
= (char *)ref
+ le16_to_cpu(ref
->DfsPathOffset
);
4718 max_len
= data_end
- temp
;
4719 node
->path_name
= cifs_strndup_from_utf16(temp
, max_len
,
4720 is_unicode
, nls_codepage
);
4721 if (!node
->path_name
) {
4723 goto parse_DFS_referrals_exit
;
4726 /* copy link target UNC */
4727 temp
= (char *)ref
+ le16_to_cpu(ref
->NetworkAddressOffset
);
4728 max_len
= data_end
- temp
;
4729 node
->node_name
= cifs_strndup_from_utf16(temp
, max_len
,
4730 is_unicode
, nls_codepage
);
4731 if (!node
->node_name
) {
4733 goto parse_DFS_referrals_exit
;
4739 parse_DFS_referrals_exit
:
4741 free_dfs_info_array(*target_nodes
, *num_of_nodes
);
4742 *target_nodes
= NULL
;
4749 CIFSGetDFSRefer(const unsigned int xid
, struct cifs_ses
*ses
,
4750 const char *search_name
, struct dfs_info3_param
**target_nodes
,
4751 unsigned int *num_of_nodes
,
4752 const struct nls_table
*nls_codepage
, int remap
)
4754 /* TRANS2_GET_DFS_REFERRAL */
4755 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
4756 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
4760 __u16 params
, byte_count
;
4762 *target_nodes
= NULL
;
4764 cifs_dbg(FYI
, "In GetDFSRefer the path %s\n", search_name
);
4768 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, NULL
, (void **) &pSMB
,
4773 /* server pointer checked in called function,
4774 but should never be null here anyway */
4775 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
4776 pSMB
->hdr
.Tid
= ses
->ipc_tid
;
4777 pSMB
->hdr
.Uid
= ses
->Suid
;
4778 if (ses
->capabilities
& CAP_STATUS32
)
4779 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
4780 if (ses
->capabilities
& CAP_DFS
)
4781 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
4783 if (ses
->capabilities
& CAP_UNICODE
) {
4784 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
4786 cifsConvertToUTF16((__le16
*) pSMB
->RequestFileName
,
4787 search_name
, PATH_MAX
, nls_codepage
,
4789 name_len
++; /* trailing null */
4791 } else { /* BB improve the check for buffer overruns BB */
4792 name_len
= strnlen(search_name
, PATH_MAX
);
4793 name_len
++; /* trailing null */
4794 strncpy(pSMB
->RequestFileName
, search_name
, name_len
);
4798 if (ses
->server
->sec_mode
&
4799 (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
))
4800 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
4803 pSMB
->hdr
.Uid
= ses
->Suid
;
4805 params
= 2 /* level */ + name_len
/*includes null */ ;
4806 pSMB
->TotalDataCount
= 0;
4807 pSMB
->DataCount
= 0;
4808 pSMB
->DataOffset
= 0;
4809 pSMB
->MaxParameterCount
= 0;
4810 /* BB find exact max SMB PDU from sess structure BB */
4811 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4812 pSMB
->MaxSetupCount
= 0;
4816 pSMB
->Reserved2
= 0;
4817 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4818 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
4819 pSMB
->SetupCount
= 1;
4820 pSMB
->Reserved3
= 0;
4821 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
4822 byte_count
= params
+ 3 /* pad */ ;
4823 pSMB
->ParameterCount
= cpu_to_le16(params
);
4824 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4825 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
4826 inc_rfc1001_len(pSMB
, byte_count
);
4827 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4829 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
4830 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4832 cifs_dbg(FYI
, "Send error in GetDFSRefer = %d\n", rc
);
4835 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4837 /* BB Also check if enough total bytes returned? */
4838 if (rc
|| get_bcc(&pSMBr
->hdr
) < 17) {
4839 rc
= -EIO
; /* bad smb */
4843 cifs_dbg(FYI
, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4844 get_bcc(&pSMBr
->hdr
), le16_to_cpu(pSMBr
->t2
.DataOffset
));
4846 /* parse returned result into more usable form */
4847 rc
= parse_DFS_referrals(pSMBr
, num_of_nodes
,
4848 target_nodes
, nls_codepage
, remap
,
4852 cifs_buf_release(pSMB
);
4860 /* Query File System Info such as free space to old servers such as Win 9x */
4862 SMBOldQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4863 struct kstatfs
*FSData
)
4865 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4866 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4867 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4868 FILE_SYSTEM_ALLOC_INFO
*response_data
;
4870 int bytes_returned
= 0;
4871 __u16 params
, byte_count
;
4873 cifs_dbg(FYI
, "OldQFSInfo\n");
4875 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4880 params
= 2; /* level */
4881 pSMB
->TotalDataCount
= 0;
4882 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4883 pSMB
->MaxDataCount
= cpu_to_le16(1000);
4884 pSMB
->MaxSetupCount
= 0;
4888 pSMB
->Reserved2
= 0;
4889 byte_count
= params
+ 1 /* pad */ ;
4890 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4891 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4892 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4893 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
4894 pSMB
->DataCount
= 0;
4895 pSMB
->DataOffset
= 0;
4896 pSMB
->SetupCount
= 1;
4897 pSMB
->Reserved3
= 0;
4898 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
4899 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_ALLOCATION
);
4900 inc_rfc1001_len(pSMB
, byte_count
);
4901 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4903 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4904 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4906 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
4907 } else { /* decode response */
4908 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4910 if (rc
|| get_bcc(&pSMBr
->hdr
) < 18)
4911 rc
= -EIO
; /* bad smb */
4913 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4914 cifs_dbg(FYI
, "qfsinf resp BCC: %d Offset %d\n",
4915 get_bcc(&pSMBr
->hdr
), data_offset
);
4917 response_data
= (FILE_SYSTEM_ALLOC_INFO
*)
4918 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
4920 le16_to_cpu(response_data
->BytesPerSector
) *
4921 le32_to_cpu(response_data
->
4922 SectorsPerAllocationUnit
);
4924 le32_to_cpu(response_data
->TotalAllocationUnits
);
4925 FSData
->f_bfree
= FSData
->f_bavail
=
4926 le32_to_cpu(response_data
->FreeAllocationUnits
);
4927 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
4928 (unsigned long long)FSData
->f_blocks
,
4929 (unsigned long long)FSData
->f_bfree
,
4933 cifs_buf_release(pSMB
);
4936 goto oldQFSInfoRetry
;
4942 CIFSSMBQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4943 struct kstatfs
*FSData
)
4945 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4946 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4947 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4948 FILE_SYSTEM_INFO
*response_data
;
4950 int bytes_returned
= 0;
4951 __u16 params
, byte_count
;
4953 cifs_dbg(FYI
, "In QFSInfo\n");
4955 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4960 params
= 2; /* level */
4961 pSMB
->TotalDataCount
= 0;
4962 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4963 pSMB
->MaxDataCount
= cpu_to_le16(1000);
4964 pSMB
->MaxSetupCount
= 0;
4968 pSMB
->Reserved2
= 0;
4969 byte_count
= params
+ 1 /* pad */ ;
4970 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4971 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4972 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4973 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
4974 pSMB
->DataCount
= 0;
4975 pSMB
->DataOffset
= 0;
4976 pSMB
->SetupCount
= 1;
4977 pSMB
->Reserved3
= 0;
4978 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
4979 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
4980 inc_rfc1001_len(pSMB
, byte_count
);
4981 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4983 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4984 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4986 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
4987 } else { /* decode response */
4988 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4990 if (rc
|| get_bcc(&pSMBr
->hdr
) < 24)
4991 rc
= -EIO
; /* bad smb */
4993 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4997 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5000 le32_to_cpu(response_data
->BytesPerSector
) *
5001 le32_to_cpu(response_data
->
5002 SectorsPerAllocationUnit
);
5004 le64_to_cpu(response_data
->TotalAllocationUnits
);
5005 FSData
->f_bfree
= FSData
->f_bavail
=
5006 le64_to_cpu(response_data
->FreeAllocationUnits
);
5007 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5008 (unsigned long long)FSData
->f_blocks
,
5009 (unsigned long long)FSData
->f_bfree
,
5013 cifs_buf_release(pSMB
);
5022 CIFSSMBQFSAttributeInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5024 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5025 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5026 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5027 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
5029 int bytes_returned
= 0;
5030 __u16 params
, byte_count
;
5032 cifs_dbg(FYI
, "In QFSAttributeInfo\n");
5034 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5039 params
= 2; /* level */
5040 pSMB
->TotalDataCount
= 0;
5041 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5042 /* BB find exact max SMB PDU from sess structure BB */
5043 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5044 pSMB
->MaxSetupCount
= 0;
5048 pSMB
->Reserved2
= 0;
5049 byte_count
= params
+ 1 /* pad */ ;
5050 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5051 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5052 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5053 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5054 pSMB
->DataCount
= 0;
5055 pSMB
->DataOffset
= 0;
5056 pSMB
->SetupCount
= 1;
5057 pSMB
->Reserved3
= 0;
5058 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5059 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
5060 inc_rfc1001_len(pSMB
, byte_count
);
5061 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5063 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5064 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5066 cifs_dbg(VFS
, "Send error in QFSAttributeInfo = %d\n", rc
);
5067 } else { /* decode response */
5068 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5070 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5071 /* BB also check if enough bytes returned */
5072 rc
= -EIO
; /* bad smb */
5074 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5076 (FILE_SYSTEM_ATTRIBUTE_INFO
5077 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5079 memcpy(&tcon
->fsAttrInfo
, response_data
,
5080 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO
));
5083 cifs_buf_release(pSMB
);
5086 goto QFSAttributeRetry
;
5092 CIFSSMBQFSDeviceInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5094 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5095 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5096 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5097 FILE_SYSTEM_DEVICE_INFO
*response_data
;
5099 int bytes_returned
= 0;
5100 __u16 params
, byte_count
;
5102 cifs_dbg(FYI
, "In QFSDeviceInfo\n");
5104 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5109 params
= 2; /* level */
5110 pSMB
->TotalDataCount
= 0;
5111 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5112 /* BB find exact max SMB PDU from sess structure BB */
5113 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5114 pSMB
->MaxSetupCount
= 0;
5118 pSMB
->Reserved2
= 0;
5119 byte_count
= params
+ 1 /* pad */ ;
5120 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5121 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5122 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5123 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5125 pSMB
->DataCount
= 0;
5126 pSMB
->DataOffset
= 0;
5127 pSMB
->SetupCount
= 1;
5128 pSMB
->Reserved3
= 0;
5129 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5130 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
5131 inc_rfc1001_len(pSMB
, byte_count
);
5132 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5134 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5135 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5137 cifs_dbg(FYI
, "Send error in QFSDeviceInfo = %d\n", rc
);
5138 } else { /* decode response */
5139 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5141 if (rc
|| get_bcc(&pSMBr
->hdr
) <
5142 sizeof(FILE_SYSTEM_DEVICE_INFO
))
5143 rc
= -EIO
; /* bad smb */
5145 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5147 (FILE_SYSTEM_DEVICE_INFO
*)
5148 (((char *) &pSMBr
->hdr
.Protocol
) +
5150 memcpy(&tcon
->fsDevInfo
, response_data
,
5151 sizeof(FILE_SYSTEM_DEVICE_INFO
));
5154 cifs_buf_release(pSMB
);
5157 goto QFSDeviceRetry
;
5163 CIFSSMBQFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5165 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5166 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5167 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5168 FILE_SYSTEM_UNIX_INFO
*response_data
;
5170 int bytes_returned
= 0;
5171 __u16 params
, byte_count
;
5173 cifs_dbg(FYI
, "In QFSUnixInfo\n");
5175 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5176 (void **) &pSMB
, (void **) &pSMBr
);
5180 params
= 2; /* level */
5181 pSMB
->TotalDataCount
= 0;
5182 pSMB
->DataCount
= 0;
5183 pSMB
->DataOffset
= 0;
5184 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5185 /* BB find exact max SMB PDU from sess structure BB */
5186 pSMB
->MaxDataCount
= cpu_to_le16(100);
5187 pSMB
->MaxSetupCount
= 0;
5191 pSMB
->Reserved2
= 0;
5192 byte_count
= params
+ 1 /* pad */ ;
5193 pSMB
->ParameterCount
= cpu_to_le16(params
);
5194 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5195 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5196 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5197 pSMB
->SetupCount
= 1;
5198 pSMB
->Reserved3
= 0;
5199 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5200 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
5201 inc_rfc1001_len(pSMB
, byte_count
);
5202 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5204 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5205 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5207 cifs_dbg(VFS
, "Send error in QFSUnixInfo = %d\n", rc
);
5208 } else { /* decode response */
5209 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5211 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5212 rc
= -EIO
; /* bad smb */
5214 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5216 (FILE_SYSTEM_UNIX_INFO
5217 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5219 memcpy(&tcon
->fsUnixInfo
, response_data
,
5220 sizeof(FILE_SYSTEM_UNIX_INFO
));
5223 cifs_buf_release(pSMB
);
5233 CIFSSMBSetFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
, __u64 cap
)
5235 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5236 TRANSACTION2_SETFSI_REQ
*pSMB
= NULL
;
5237 TRANSACTION2_SETFSI_RSP
*pSMBr
= NULL
;
5239 int bytes_returned
= 0;
5240 __u16 params
, param_offset
, offset
, byte_count
;
5242 cifs_dbg(FYI
, "In SETFSUnixInfo\n");
5244 /* BB switch to small buf init to save memory */
5245 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5246 (void **) &pSMB
, (void **) &pSMBr
);
5250 params
= 4; /* 2 bytes zero followed by info level. */
5251 pSMB
->MaxSetupCount
= 0;
5255 pSMB
->Reserved2
= 0;
5256 param_offset
= offsetof(struct smb_com_transaction2_setfsi_req
, FileNum
)
5258 offset
= param_offset
+ params
;
5260 pSMB
->MaxParameterCount
= cpu_to_le16(4);
5261 /* BB find exact max SMB PDU from sess structure BB */
5262 pSMB
->MaxDataCount
= cpu_to_le16(100);
5263 pSMB
->SetupCount
= 1;
5264 pSMB
->Reserved3
= 0;
5265 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FS_INFORMATION
);
5266 byte_count
= 1 /* pad */ + params
+ 12;
5268 pSMB
->DataCount
= cpu_to_le16(12);
5269 pSMB
->ParameterCount
= cpu_to_le16(params
);
5270 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5271 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5272 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5273 pSMB
->DataOffset
= cpu_to_le16(offset
);
5277 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_CIFS_UNIX_INFO
);
5280 pSMB
->ClientUnixMajor
= cpu_to_le16(CIFS_UNIX_MAJOR_VERSION
);
5281 pSMB
->ClientUnixMinor
= cpu_to_le16(CIFS_UNIX_MINOR_VERSION
);
5282 pSMB
->ClientUnixCap
= cpu_to_le64(cap
);
5284 inc_rfc1001_len(pSMB
, byte_count
);
5285 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5287 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5288 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5290 cifs_dbg(VFS
, "Send error in SETFSUnixInfo = %d\n", rc
);
5291 } else { /* decode response */
5292 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5294 rc
= -EIO
; /* bad smb */
5296 cifs_buf_release(pSMB
);
5299 goto SETFSUnixRetry
;
5307 CIFSSMBQFSPosixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5308 struct kstatfs
*FSData
)
5310 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5311 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5312 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5313 FILE_SYSTEM_POSIX_INFO
*response_data
;
5315 int bytes_returned
= 0;
5316 __u16 params
, byte_count
;
5318 cifs_dbg(FYI
, "In QFSPosixInfo\n");
5320 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5325 params
= 2; /* level */
5326 pSMB
->TotalDataCount
= 0;
5327 pSMB
->DataCount
= 0;
5328 pSMB
->DataOffset
= 0;
5329 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5330 /* BB find exact max SMB PDU from sess structure BB */
5331 pSMB
->MaxDataCount
= cpu_to_le16(100);
5332 pSMB
->MaxSetupCount
= 0;
5336 pSMB
->Reserved2
= 0;
5337 byte_count
= params
+ 1 /* pad */ ;
5338 pSMB
->ParameterCount
= cpu_to_le16(params
);
5339 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5340 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5341 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5342 pSMB
->SetupCount
= 1;
5343 pSMB
->Reserved3
= 0;
5344 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5345 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_FS_INFO
);
5346 inc_rfc1001_len(pSMB
, byte_count
);
5347 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5349 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5350 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5352 cifs_dbg(FYI
, "Send error in QFSUnixInfo = %d\n", rc
);
5353 } else { /* decode response */
5354 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5356 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5357 rc
= -EIO
; /* bad smb */
5359 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5361 (FILE_SYSTEM_POSIX_INFO
5362 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5365 le32_to_cpu(response_data
->BlockSize
);
5367 le64_to_cpu(response_data
->TotalBlocks
);
5369 le64_to_cpu(response_data
->BlocksAvail
);
5370 if (response_data
->UserBlocksAvail
== cpu_to_le64(-1)) {
5371 FSData
->f_bavail
= FSData
->f_bfree
;
5374 le64_to_cpu(response_data
->UserBlocksAvail
);
5376 if (response_data
->TotalFileNodes
!= cpu_to_le64(-1))
5378 le64_to_cpu(response_data
->TotalFileNodes
);
5379 if (response_data
->FreeFileNodes
!= cpu_to_le64(-1))
5381 le64_to_cpu(response_data
->FreeFileNodes
);
5384 cifs_buf_release(pSMB
);
5394 * We can not use write of zero bytes trick to set file size due to need for
5395 * large file support. Also note that this SetPathInfo is preferred to
5396 * SetFileInfo based method in next routine which is only needed to work around
5397 * a sharing violation bugin Samba which this routine can run into.
5400 CIFSSMBSetEOF(const unsigned int xid
, struct cifs_tcon
*tcon
,
5401 const char *file_name
, __u64 size
, struct cifs_sb_info
*cifs_sb
,
5402 bool set_allocation
)
5404 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5405 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5406 struct file_end_of_file_info
*parm_data
;
5409 int bytes_returned
= 0;
5410 int remap
= cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
;
5412 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
5414 cifs_dbg(FYI
, "In SetEOF\n");
5416 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5421 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5423 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5424 PATH_MAX
, cifs_sb
->local_nls
, remap
);
5425 name_len
++; /* trailing null */
5427 } else { /* BB improve the check for buffer overruns BB */
5428 name_len
= strnlen(file_name
, PATH_MAX
);
5429 name_len
++; /* trailing null */
5430 strncpy(pSMB
->FileName
, file_name
, name_len
);
5432 params
= 6 + name_len
;
5433 data_count
= sizeof(struct file_end_of_file_info
);
5434 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5435 pSMB
->MaxDataCount
= cpu_to_le16(4100);
5436 pSMB
->MaxSetupCount
= 0;
5440 pSMB
->Reserved2
= 0;
5441 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5442 InformationLevel
) - 4;
5443 offset
= param_offset
+ params
;
5444 if (set_allocation
) {
5445 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5446 pSMB
->InformationLevel
=
5447 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5449 pSMB
->InformationLevel
=
5450 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5451 } else /* Set File Size */ {
5452 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5453 pSMB
->InformationLevel
=
5454 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5456 pSMB
->InformationLevel
=
5457 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5461 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
5463 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5464 pSMB
->DataOffset
= cpu_to_le16(offset
);
5465 pSMB
->SetupCount
= 1;
5466 pSMB
->Reserved3
= 0;
5467 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5468 byte_count
= 3 /* pad */ + params
+ data_count
;
5469 pSMB
->DataCount
= cpu_to_le16(data_count
);
5470 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5471 pSMB
->ParameterCount
= cpu_to_le16(params
);
5472 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5473 pSMB
->Reserved4
= 0;
5474 inc_rfc1001_len(pSMB
, byte_count
);
5475 parm_data
->FileSize
= cpu_to_le64(size
);
5476 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5477 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5478 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5480 cifs_dbg(FYI
, "SetPathInfo (file size) returned %d\n", rc
);
5482 cifs_buf_release(pSMB
);
5491 CIFSSMBSetFileSize(const unsigned int xid
, struct cifs_tcon
*tcon
,
5492 struct cifsFileInfo
*cfile
, __u64 size
, bool set_allocation
)
5494 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5495 struct file_end_of_file_info
*parm_data
;
5497 __u16 params
, param_offset
, offset
, byte_count
, count
;
5499 cifs_dbg(FYI
, "SetFileSize (via SetFileInfo) %lld\n",
5501 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5506 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)cfile
->pid
);
5507 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(cfile
->pid
>> 16));
5510 pSMB
->MaxSetupCount
= 0;
5514 pSMB
->Reserved2
= 0;
5515 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5516 offset
= param_offset
+ params
;
5518 count
= sizeof(struct file_end_of_file_info
);
5519 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5520 /* BB find exact max SMB PDU from sess structure BB */
5521 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5522 pSMB
->SetupCount
= 1;
5523 pSMB
->Reserved3
= 0;
5524 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5525 byte_count
= 3 /* pad */ + params
+ count
;
5526 pSMB
->DataCount
= cpu_to_le16(count
);
5527 pSMB
->ParameterCount
= cpu_to_le16(params
);
5528 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5529 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5530 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5532 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
)
5534 pSMB
->DataOffset
= cpu_to_le16(offset
);
5535 parm_data
->FileSize
= cpu_to_le64(size
);
5536 pSMB
->Fid
= cfile
->fid
.netfid
;
5537 if (set_allocation
) {
5538 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5539 pSMB
->InformationLevel
=
5540 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5542 pSMB
->InformationLevel
=
5543 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5544 } else /* Set File Size */ {
5545 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5546 pSMB
->InformationLevel
=
5547 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5549 pSMB
->InformationLevel
=
5550 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5552 pSMB
->Reserved4
= 0;
5553 inc_rfc1001_len(pSMB
, byte_count
);
5554 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5555 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5557 cifs_dbg(FYI
, "Send error in SetFileInfo (SetFileSize) = %d\n",
5561 /* Note: On -EAGAIN error only caller can retry on handle based calls
5562 since file handle passed in no longer valid */
5567 /* Some legacy servers such as NT4 require that the file times be set on
5568 an open handle, rather than by pathname - this is awkward due to
5569 potential access conflicts on the open, but it is unavoidable for these
5570 old servers since the only other choice is to go from 100 nanosecond DCE
5571 time and resort to the original setpathinfo level which takes the ancient
5572 DOS time format with 2 second granularity */
5574 CIFSSMBSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5575 const FILE_BASIC_INFO
*data
, __u16 fid
, __u32 pid_of_opener
)
5577 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5580 __u16 params
, param_offset
, offset
, byte_count
, count
;
5582 cifs_dbg(FYI
, "Set Times (via SetFileInfo)\n");
5583 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5588 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5589 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5592 pSMB
->MaxSetupCount
= 0;
5596 pSMB
->Reserved2
= 0;
5597 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5598 offset
= param_offset
+ params
;
5600 data_offset
= (char *)pSMB
+
5601 offsetof(struct smb_hdr
, Protocol
) + offset
;
5603 count
= sizeof(FILE_BASIC_INFO
);
5604 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5605 /* BB find max SMB PDU from sess */
5606 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5607 pSMB
->SetupCount
= 1;
5608 pSMB
->Reserved3
= 0;
5609 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5610 byte_count
= 3 /* pad */ + params
+ count
;
5611 pSMB
->DataCount
= cpu_to_le16(count
);
5612 pSMB
->ParameterCount
= cpu_to_le16(params
);
5613 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5614 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5615 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5616 pSMB
->DataOffset
= cpu_to_le16(offset
);
5618 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5619 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5621 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5622 pSMB
->Reserved4
= 0;
5623 inc_rfc1001_len(pSMB
, byte_count
);
5624 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5625 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5626 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5628 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5631 /* Note: On -EAGAIN error only caller can retry on handle based calls
5632 since file handle passed in no longer valid */
5638 CIFSSMBSetFileDisposition(const unsigned int xid
, struct cifs_tcon
*tcon
,
5639 bool delete_file
, __u16 fid
, __u32 pid_of_opener
)
5641 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5644 __u16 params
, param_offset
, offset
, byte_count
, count
;
5646 cifs_dbg(FYI
, "Set File Disposition (via SetFileInfo)\n");
5647 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5652 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5653 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5656 pSMB
->MaxSetupCount
= 0;
5660 pSMB
->Reserved2
= 0;
5661 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5662 offset
= param_offset
+ params
;
5664 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5667 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5668 /* BB find max SMB PDU from sess */
5669 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5670 pSMB
->SetupCount
= 1;
5671 pSMB
->Reserved3
= 0;
5672 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5673 byte_count
= 3 /* pad */ + params
+ count
;
5674 pSMB
->DataCount
= cpu_to_le16(count
);
5675 pSMB
->ParameterCount
= cpu_to_le16(params
);
5676 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5677 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5678 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5679 pSMB
->DataOffset
= cpu_to_le16(offset
);
5681 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO
);
5682 pSMB
->Reserved4
= 0;
5683 inc_rfc1001_len(pSMB
, byte_count
);
5684 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5685 *data_offset
= delete_file
? 1 : 0;
5686 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5688 cifs_dbg(FYI
, "Send error in SetFileDisposition = %d\n", rc
);
5694 CIFSSMBSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5695 const char *fileName
, const FILE_BASIC_INFO
*data
,
5696 const struct nls_table
*nls_codepage
, int remap
)
5698 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5699 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5702 int bytes_returned
= 0;
5704 __u16 params
, param_offset
, offset
, byte_count
, count
;
5706 cifs_dbg(FYI
, "In SetTimes\n");
5709 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5714 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5716 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5717 PATH_MAX
, nls_codepage
, remap
);
5718 name_len
++; /* trailing null */
5720 } else { /* BB improve the check for buffer overruns BB */
5721 name_len
= strnlen(fileName
, PATH_MAX
);
5722 name_len
++; /* trailing null */
5723 strncpy(pSMB
->FileName
, fileName
, name_len
);
5726 params
= 6 + name_len
;
5727 count
= sizeof(FILE_BASIC_INFO
);
5728 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5729 /* BB find max SMB PDU from sess structure BB */
5730 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5731 pSMB
->MaxSetupCount
= 0;
5735 pSMB
->Reserved2
= 0;
5736 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5737 InformationLevel
) - 4;
5738 offset
= param_offset
+ params
;
5739 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5740 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5741 pSMB
->DataOffset
= cpu_to_le16(offset
);
5742 pSMB
->SetupCount
= 1;
5743 pSMB
->Reserved3
= 0;
5744 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5745 byte_count
= 3 /* pad */ + params
+ count
;
5747 pSMB
->DataCount
= cpu_to_le16(count
);
5748 pSMB
->ParameterCount
= cpu_to_le16(params
);
5749 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5750 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5751 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5752 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5754 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5755 pSMB
->Reserved4
= 0;
5756 inc_rfc1001_len(pSMB
, byte_count
);
5757 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5758 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5759 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5760 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5762 cifs_dbg(FYI
, "SetPathInfo (times) returned %d\n", rc
);
5764 cifs_buf_release(pSMB
);
5772 /* Can not be used to set time stamps yet (due to old DOS time format) */
5773 /* Can be used to set attributes */
5774 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5775 handling it anyway and NT4 was what we thought it would be needed for
5776 Do not delete it until we prove whether needed for Win9x though */
5778 CIFSSMBSetAttrLegacy(unsigned int xid
, struct cifs_tcon
*tcon
, char *fileName
,
5779 __u16 dos_attrs
, const struct nls_table
*nls_codepage
)
5781 SETATTR_REQ
*pSMB
= NULL
;
5782 SETATTR_RSP
*pSMBr
= NULL
;
5787 cifs_dbg(FYI
, "In SetAttrLegacy\n");
5790 rc
= smb_init(SMB_COM_SETATTR
, 8, tcon
, (void **) &pSMB
,
5795 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5797 ConvertToUTF16((__le16
*) pSMB
->fileName
, fileName
,
5798 PATH_MAX
, nls_codepage
);
5799 name_len
++; /* trailing null */
5801 } else { /* BB improve the check for buffer overruns BB */
5802 name_len
= strnlen(fileName
, PATH_MAX
);
5803 name_len
++; /* trailing null */
5804 strncpy(pSMB
->fileName
, fileName
, name_len
);
5806 pSMB
->attr
= cpu_to_le16(dos_attrs
);
5807 pSMB
->BufferFormat
= 0x04;
5808 inc_rfc1001_len(pSMB
, name_len
+ 1);
5809 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
5810 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5811 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5813 cifs_dbg(FYI
, "Error in LegacySetAttr = %d\n", rc
);
5815 cifs_buf_release(pSMB
);
5818 goto SetAttrLgcyRetry
;
5822 #endif /* temporarily unneeded SetAttr legacy function */
5825 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO
*data_offset
,
5826 const struct cifs_unix_set_info_args
*args
)
5828 u64 uid
= NO_CHANGE_64
, gid
= NO_CHANGE_64
;
5829 u64 mode
= args
->mode
;
5831 if (uid_valid(args
->uid
))
5832 uid
= from_kuid(&init_user_ns
, args
->uid
);
5833 if (gid_valid(args
->gid
))
5834 gid
= from_kgid(&init_user_ns
, args
->gid
);
5837 * Samba server ignores set of file size to zero due to bugs in some
5838 * older clients, but we should be precise - we use SetFileSize to
5839 * set file size and do not want to truncate file size to zero
5840 * accidentally as happened on one Samba server beta by putting
5841 * zero instead of -1 here
5843 data_offset
->EndOfFile
= cpu_to_le64(NO_CHANGE_64
);
5844 data_offset
->NumOfBytes
= cpu_to_le64(NO_CHANGE_64
);
5845 data_offset
->LastStatusChange
= cpu_to_le64(args
->ctime
);
5846 data_offset
->LastAccessTime
= cpu_to_le64(args
->atime
);
5847 data_offset
->LastModificationTime
= cpu_to_le64(args
->mtime
);
5848 data_offset
->Uid
= cpu_to_le64(uid
);
5849 data_offset
->Gid
= cpu_to_le64(gid
);
5850 /* better to leave device as zero when it is */
5851 data_offset
->DevMajor
= cpu_to_le64(MAJOR(args
->device
));
5852 data_offset
->DevMinor
= cpu_to_le64(MINOR(args
->device
));
5853 data_offset
->Permissions
= cpu_to_le64(mode
);
5856 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
5857 else if (S_ISDIR(mode
))
5858 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
5859 else if (S_ISLNK(mode
))
5860 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
5861 else if (S_ISCHR(mode
))
5862 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
5863 else if (S_ISBLK(mode
))
5864 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
5865 else if (S_ISFIFO(mode
))
5866 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
5867 else if (S_ISSOCK(mode
))
5868 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
5872 CIFSSMBUnixSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5873 const struct cifs_unix_set_info_args
*args
,
5874 u16 fid
, u32 pid_of_opener
)
5876 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5879 u16 params
, param_offset
, offset
, byte_count
, count
;
5881 cifs_dbg(FYI
, "Set Unix Info (via SetFileInfo)\n");
5882 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5887 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5888 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5891 pSMB
->MaxSetupCount
= 0;
5895 pSMB
->Reserved2
= 0;
5896 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5897 offset
= param_offset
+ params
;
5899 data_offset
= (char *)pSMB
+
5900 offsetof(struct smb_hdr
, Protocol
) + offset
;
5902 count
= sizeof(FILE_UNIX_BASIC_INFO
);
5904 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5905 /* BB find max SMB PDU from sess */
5906 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5907 pSMB
->SetupCount
= 1;
5908 pSMB
->Reserved3
= 0;
5909 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5910 byte_count
= 3 /* pad */ + params
+ count
;
5911 pSMB
->DataCount
= cpu_to_le16(count
);
5912 pSMB
->ParameterCount
= cpu_to_le16(params
);
5913 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5914 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5915 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5916 pSMB
->DataOffset
= cpu_to_le16(offset
);
5918 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
5919 pSMB
->Reserved4
= 0;
5920 inc_rfc1001_len(pSMB
, byte_count
);
5921 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5923 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO
*)data_offset
, args
);
5925 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5927 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5930 /* Note: On -EAGAIN error only caller can retry on handle based calls
5931 since file handle passed in no longer valid */
5937 CIFSSMBUnixSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5938 const char *file_name
,
5939 const struct cifs_unix_set_info_args
*args
,
5940 const struct nls_table
*nls_codepage
, int remap
)
5942 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5943 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5946 int bytes_returned
= 0;
5947 FILE_UNIX_BASIC_INFO
*data_offset
;
5948 __u16 params
, param_offset
, offset
, count
, byte_count
;
5950 cifs_dbg(FYI
, "In SetUID/GID/Mode\n");
5952 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5957 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5959 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5960 PATH_MAX
, nls_codepage
, remap
);
5961 name_len
++; /* trailing null */
5963 } else { /* BB improve the check for buffer overruns BB */
5964 name_len
= strnlen(file_name
, PATH_MAX
);
5965 name_len
++; /* trailing null */
5966 strncpy(pSMB
->FileName
, file_name
, name_len
);
5969 params
= 6 + name_len
;
5970 count
= sizeof(FILE_UNIX_BASIC_INFO
);
5971 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5972 /* BB find max SMB PDU from sess structure BB */
5973 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5974 pSMB
->MaxSetupCount
= 0;
5978 pSMB
->Reserved2
= 0;
5979 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5980 InformationLevel
) - 4;
5981 offset
= param_offset
+ params
;
5983 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
5985 memset(data_offset
, 0, count
);
5986 pSMB
->DataOffset
= cpu_to_le16(offset
);
5987 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5988 pSMB
->SetupCount
= 1;
5989 pSMB
->Reserved3
= 0;
5990 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5991 byte_count
= 3 /* pad */ + params
+ count
;
5992 pSMB
->ParameterCount
= cpu_to_le16(params
);
5993 pSMB
->DataCount
= cpu_to_le16(count
);
5994 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5995 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5996 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
5997 pSMB
->Reserved4
= 0;
5998 inc_rfc1001_len(pSMB
, byte_count
);
6000 cifs_fill_unix_set_info(data_offset
, args
);
6002 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6003 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6004 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6006 cifs_dbg(FYI
, "SetPathInfo (perms) returned %d\n", rc
);
6008 cifs_buf_release(pSMB
);
6014 #ifdef CONFIG_CIFS_XATTR
6016 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6017 * function used by listxattr and getxattr type calls. When ea_name is set,
6018 * it looks for that attribute name and stuffs that value into the EAData
6019 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6020 * buffer. In both cases, the return value is either the length of the
6021 * resulting data or a negative error code. If EAData is a NULL pointer then
6022 * the data isn't copied to it, but the length is returned.
6025 CIFSSMBQAllEAs(const unsigned int xid
, struct cifs_tcon
*tcon
,
6026 const unsigned char *searchName
, const unsigned char *ea_name
,
6027 char *EAData
, size_t buf_size
,
6028 const struct nls_table
*nls_codepage
, int remap
)
6030 /* BB assumes one setup word */
6031 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
6032 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
6036 struct fealist
*ea_response_data
;
6037 struct fea
*temp_fea
;
6040 __u16 params
, byte_count
, data_offset
;
6041 unsigned int ea_name_len
= ea_name
? strlen(ea_name
) : 0;
6043 cifs_dbg(FYI
, "In Query All EAs path %s\n", searchName
);
6045 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6050 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6052 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
6053 PATH_MAX
, nls_codepage
, remap
);
6054 list_len
++; /* trailing null */
6056 } else { /* BB improve the check for buffer overruns BB */
6057 list_len
= strnlen(searchName
, PATH_MAX
);
6058 list_len
++; /* trailing null */
6059 strncpy(pSMB
->FileName
, searchName
, list_len
);
6062 params
= 2 /* level */ + 4 /* reserved */ + list_len
/* includes NUL */;
6063 pSMB
->TotalDataCount
= 0;
6064 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6065 /* BB find exact max SMB PDU from sess structure BB */
6066 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
6067 pSMB
->MaxSetupCount
= 0;
6071 pSMB
->Reserved2
= 0;
6072 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
6073 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
6074 pSMB
->DataCount
= 0;
6075 pSMB
->DataOffset
= 0;
6076 pSMB
->SetupCount
= 1;
6077 pSMB
->Reserved3
= 0;
6078 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
6079 byte_count
= params
+ 1 /* pad */ ;
6080 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
6081 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6082 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
6083 pSMB
->Reserved4
= 0;
6084 inc_rfc1001_len(pSMB
, byte_count
);
6085 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6087 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6088 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6090 cifs_dbg(FYI
, "Send error in QueryAllEAs = %d\n", rc
);
6095 /* BB also check enough total bytes returned */
6096 /* BB we need to improve the validity checking
6097 of these trans2 responses */
6099 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
6100 if (rc
|| get_bcc(&pSMBr
->hdr
) < 4) {
6101 rc
= -EIO
; /* bad smb */
6105 /* check that length of list is not more than bcc */
6106 /* check that each entry does not go beyond length
6108 /* check that each element of each entry does not
6109 go beyond end of list */
6110 /* validate_trans2_offsets() */
6111 /* BB check if start of smb + data_offset > &bcc+ bcc */
6113 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
6114 ea_response_data
= (struct fealist
*)
6115 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
6117 list_len
= le32_to_cpu(ea_response_data
->list_len
);
6118 cifs_dbg(FYI
, "ea length %d\n", list_len
);
6119 if (list_len
<= 8) {
6120 cifs_dbg(FYI
, "empty EA list returned from server\n");
6124 /* make sure list_len doesn't go past end of SMB */
6125 end_of_smb
= (char *)pByteArea(&pSMBr
->hdr
) + get_bcc(&pSMBr
->hdr
);
6126 if ((char *)ea_response_data
+ list_len
> end_of_smb
) {
6127 cifs_dbg(FYI
, "EA list appears to go beyond SMB\n");
6132 /* account for ea list len */
6134 temp_fea
= ea_response_data
->list
;
6135 temp_ptr
= (char *)temp_fea
;
6136 while (list_len
> 0) {
6137 unsigned int name_len
;
6142 /* make sure we can read name_len and value_len */
6144 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6149 name_len
= temp_fea
->name_len
;
6150 value_len
= le16_to_cpu(temp_fea
->value_len
);
6151 list_len
-= name_len
+ 1 + value_len
;
6153 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6159 if (ea_name_len
== name_len
&&
6160 memcmp(ea_name
, temp_ptr
, name_len
) == 0) {
6161 temp_ptr
+= name_len
+ 1;
6165 if ((size_t)value_len
> buf_size
) {
6169 memcpy(EAData
, temp_ptr
, value_len
);
6173 /* account for prefix user. and trailing null */
6174 rc
+= (5 + 1 + name_len
);
6175 if (rc
< (int) buf_size
) {
6176 memcpy(EAData
, "user.", 5);
6178 memcpy(EAData
, temp_ptr
, name_len
);
6180 /* null terminate name */
6183 } else if (buf_size
== 0) {
6184 /* skip copy - calc size only */
6186 /* stop before overrun buffer */
6191 temp_ptr
+= name_len
+ 1 + value_len
;
6192 temp_fea
= (struct fea
*)temp_ptr
;
6195 /* didn't find the named attribute */
6200 cifs_buf_release(pSMB
);
6208 CIFSSMBSetEA(const unsigned int xid
, struct cifs_tcon
*tcon
,
6209 const char *fileName
, const char *ea_name
, const void *ea_value
,
6210 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
,
6213 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
6214 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
6215 struct fealist
*parm_data
;
6218 int bytes_returned
= 0;
6219 __u16 params
, param_offset
, byte_count
, offset
, count
;
6221 cifs_dbg(FYI
, "In SetEA\n");
6223 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6228 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6230 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
6231 PATH_MAX
, nls_codepage
, remap
);
6232 name_len
++; /* trailing null */
6234 } else { /* BB improve the check for buffer overruns BB */
6235 name_len
= strnlen(fileName
, PATH_MAX
);
6236 name_len
++; /* trailing null */
6237 strncpy(pSMB
->FileName
, fileName
, name_len
);
6240 params
= 6 + name_len
;
6242 /* done calculating parms using name_len of file name,
6243 now use name_len to calculate length of ea name
6244 we are going to create in the inode xattrs */
6245 if (ea_name
== NULL
)
6248 name_len
= strnlen(ea_name
, 255);
6250 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
;
6251 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6252 /* BB find max SMB PDU from sess */
6253 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6254 pSMB
->MaxSetupCount
= 0;
6258 pSMB
->Reserved2
= 0;
6259 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6260 InformationLevel
) - 4;
6261 offset
= param_offset
+ params
;
6262 pSMB
->InformationLevel
=
6263 cpu_to_le16(SMB_SET_FILE_EA
);
6266 (struct fealist
*) (((char *) &pSMB
->hdr
.Protocol
) +
6268 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6269 pSMB
->DataOffset
= cpu_to_le16(offset
);
6270 pSMB
->SetupCount
= 1;
6271 pSMB
->Reserved3
= 0;
6272 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6273 byte_count
= 3 /* pad */ + params
+ count
;
6274 pSMB
->DataCount
= cpu_to_le16(count
);
6275 parm_data
->list_len
= cpu_to_le32(count
);
6276 parm_data
->list
[0].EA_flags
= 0;
6277 /* we checked above that name len is less than 255 */
6278 parm_data
->list
[0].name_len
= (__u8
)name_len
;
6279 /* EA names are always ASCII */
6281 strncpy(parm_data
->list
[0].name
, ea_name
, name_len
);
6282 parm_data
->list
[0].name
[name_len
] = 0;
6283 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
6284 /* caller ensures that ea_value_len is less than 64K but
6285 we need to ensure that it fits within the smb */
6287 /*BB add length check to see if it would fit in
6288 negotiated SMB buffer size BB */
6289 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6291 memcpy(parm_data
->list
[0].name
+name_len
+1,
6292 ea_value
, ea_value_len
);
6294 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6295 pSMB
->ParameterCount
= cpu_to_le16(params
);
6296 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6297 pSMB
->Reserved4
= 0;
6298 inc_rfc1001_len(pSMB
, byte_count
);
6299 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6300 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6301 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6303 cifs_dbg(FYI
, "SetPathInfo (EA) returned %d\n", rc
);
6305 cifs_buf_release(pSMB
);
6314 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6316 * Years ago the kernel added a "dnotify" function for Samba server,
6317 * to allow network clients (such as Windows) to display updated
6318 * lists of files in directory listings automatically when
6319 * files are added by one user when another user has the
6320 * same directory open on their desktop. The Linux cifs kernel
6321 * client hooked into the kernel side of this interface for
6322 * the same reason, but ironically when the VFS moved from
6323 * "dnotify" to "inotify" it became harder to plug in Linux
6324 * network file system clients (the most obvious use case
6325 * for notify interfaces is when multiple users can update
6326 * the contents of the same directory - exactly what network
6327 * file systems can do) although the server (Samba) could
6328 * still use it. For the short term we leave the worker
6329 * function ifdeffed out (below) until inotify is fixed
6330 * in the VFS to make it easier to plug in network file
6331 * system clients. If inotify turns out to be permanently
6332 * incompatible for network fs clients, we could instead simply
6333 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6335 int CIFSSMBNotify(const unsigned int xid
, struct cifs_tcon
*tcon
,
6336 const int notify_subdirs
, const __u16 netfid
,
6337 __u32 filter
, struct file
*pfile
, int multishot
,
6338 const struct nls_table
*nls_codepage
)
6341 struct smb_com_transaction_change_notify_req
*pSMB
= NULL
;
6342 struct smb_com_ntransaction_change_notify_rsp
*pSMBr
= NULL
;
6343 struct dir_notify_req
*dnotify_req
;
6346 cifs_dbg(FYI
, "In CIFSSMBNotify for file handle %d\n", (int)netfid
);
6347 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
6352 pSMB
->TotalParameterCount
= 0 ;
6353 pSMB
->TotalDataCount
= 0;
6354 pSMB
->MaxParameterCount
= cpu_to_le32(2);
6355 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
6356 pSMB
->MaxSetupCount
= 4;
6358 pSMB
->ParameterOffset
= 0;
6359 pSMB
->DataCount
= 0;
6360 pSMB
->DataOffset
= 0;
6361 pSMB
->SetupCount
= 4; /* single byte does not need le conversion */
6362 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE
);
6363 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6365 pSMB
->WatchTree
= 1; /* one byte - no le conversion needed */
6366 pSMB
->Reserved2
= 0;
6367 pSMB
->CompletionFilter
= cpu_to_le32(filter
);
6368 pSMB
->Fid
= netfid
; /* file handle always le */
6369 pSMB
->ByteCount
= 0;
6371 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6372 (struct smb_hdr
*)pSMBr
, &bytes_returned
,
6375 cifs_dbg(FYI
, "Error in Notify = %d\n", rc
);
6377 /* Add file to outstanding requests */
6378 /* BB change to kmem cache alloc */
6379 dnotify_req
= kmalloc(
6380 sizeof(struct dir_notify_req
),
6383 dnotify_req
->Pid
= pSMB
->hdr
.Pid
;
6384 dnotify_req
->PidHigh
= pSMB
->hdr
.PidHigh
;
6385 dnotify_req
->Mid
= pSMB
->hdr
.Mid
;
6386 dnotify_req
->Tid
= pSMB
->hdr
.Tid
;
6387 dnotify_req
->Uid
= pSMB
->hdr
.Uid
;
6388 dnotify_req
->netfid
= netfid
;
6389 dnotify_req
->pfile
= pfile
;
6390 dnotify_req
->filter
= filter
;
6391 dnotify_req
->multishot
= multishot
;
6392 spin_lock(&GlobalMid_Lock
);
6393 list_add_tail(&dnotify_req
->lhead
,
6394 &GlobalDnotifyReqList
);
6395 spin_unlock(&GlobalMid_Lock
);
6399 cifs_buf_release(pSMB
);
6402 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */