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 discard_remaining_data(struct TCP_Server_Info
*server
)
1394 unsigned int rfclen
= get_rfc1002_length(server
->smallbuf
);
1395 int remaining
= rfclen
+ 4 - server
->total_read
;
1397 while (remaining
> 0) {
1400 length
= cifs_read_from_socket(server
, server
->bigbuf
,
1401 min_t(unsigned int, remaining
,
1402 CIFSMaxBufSize
+ MAX_HEADER_SIZE(server
)));
1405 server
->total_read
+= length
;
1406 remaining
-= length
;
1413 cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1416 struct cifs_readdata
*rdata
= mid
->callback_data
;
1418 length
= discard_remaining_data(server
);
1419 dequeue_mid(mid
, rdata
->result
);
1424 cifs_readv_receive(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1427 unsigned int data_offset
, data_len
;
1428 struct cifs_readdata
*rdata
= mid
->callback_data
;
1429 char *buf
= server
->smallbuf
;
1430 unsigned int buflen
= get_rfc1002_length(buf
) + 4;
1432 cifs_dbg(FYI
, "%s: mid=%llu offset=%llu bytes=%u\n",
1433 __func__
, mid
->mid
, rdata
->offset
, rdata
->bytes
);
1436 * read the rest of READ_RSP header (sans Data array), or whatever we
1437 * can if there's not enough data. At this point, we've read down to
1440 len
= min_t(unsigned int, buflen
, server
->vals
->read_rsp_size
) -
1441 HEADER_SIZE(server
) + 1;
1443 rdata
->iov
.iov_base
= buf
+ HEADER_SIZE(server
) - 1;
1444 rdata
->iov
.iov_len
= len
;
1446 length
= cifs_readv_from_socket(server
, &rdata
->iov
, 1, len
);
1449 server
->total_read
+= length
;
1451 if (server
->ops
->is_status_pending
&&
1452 server
->ops
->is_status_pending(buf
, server
, 0)) {
1453 discard_remaining_data(server
);
1457 /* Was the SMB read successful? */
1458 rdata
->result
= server
->ops
->map_error(buf
, false);
1459 if (rdata
->result
!= 0) {
1460 cifs_dbg(FYI
, "%s: server returned error %d\n",
1461 __func__
, rdata
->result
);
1462 return cifs_readv_discard(server
, mid
);
1465 /* Is there enough to get to the rest of the READ_RSP header? */
1466 if (server
->total_read
< server
->vals
->read_rsp_size
) {
1467 cifs_dbg(FYI
, "%s: server returned short header. got=%u expected=%zu\n",
1468 __func__
, server
->total_read
,
1469 server
->vals
->read_rsp_size
);
1470 rdata
->result
= -EIO
;
1471 return cifs_readv_discard(server
, mid
);
1474 data_offset
= server
->ops
->read_data_offset(buf
) + 4;
1475 if (data_offset
< server
->total_read
) {
1477 * win2k8 sometimes sends an offset of 0 when the read
1478 * is beyond the EOF. Treat it as if the data starts just after
1481 cifs_dbg(FYI
, "%s: data offset (%u) inside read response header\n",
1482 __func__
, data_offset
);
1483 data_offset
= server
->total_read
;
1484 } else if (data_offset
> MAX_CIFS_SMALL_BUFFER_SIZE
) {
1485 /* data_offset is beyond the end of smallbuf */
1486 cifs_dbg(FYI
, "%s: data offset (%u) beyond end of smallbuf\n",
1487 __func__
, data_offset
);
1488 rdata
->result
= -EIO
;
1489 return cifs_readv_discard(server
, mid
);
1492 cifs_dbg(FYI
, "%s: total_read=%u data_offset=%u\n",
1493 __func__
, server
->total_read
, data_offset
);
1495 len
= data_offset
- server
->total_read
;
1497 /* read any junk before data into the rest of smallbuf */
1498 rdata
->iov
.iov_base
= buf
+ server
->total_read
;
1499 rdata
->iov
.iov_len
= len
;
1500 length
= cifs_readv_from_socket(server
, &rdata
->iov
, 1, len
);
1503 server
->total_read
+= length
;
1506 /* set up first iov for signature check */
1507 rdata
->iov
.iov_base
= buf
;
1508 rdata
->iov
.iov_len
= server
->total_read
;
1509 cifs_dbg(FYI
, "0: iov_base=%p iov_len=%zu\n",
1510 rdata
->iov
.iov_base
, rdata
->iov
.iov_len
);
1512 /* how much data is in the response? */
1513 data_len
= server
->ops
->read_data_length(buf
);
1514 if (data_offset
+ data_len
> buflen
) {
1515 /* data_len is corrupt -- discard frame */
1516 rdata
->result
= -EIO
;
1517 return cifs_readv_discard(server
, mid
);
1520 length
= rdata
->read_into_pages(server
, rdata
, data_len
);
1524 server
->total_read
+= length
;
1525 rdata
->bytes
= length
;
1527 cifs_dbg(FYI
, "total_read=%u buflen=%u remaining=%u\n",
1528 server
->total_read
, buflen
, data_len
);
1530 /* discard anything left over */
1531 if (server
->total_read
< buflen
)
1532 return cifs_readv_discard(server
, mid
);
1534 dequeue_mid(mid
, false);
1539 cifs_readv_callback(struct mid_q_entry
*mid
)
1541 struct cifs_readdata
*rdata
= mid
->callback_data
;
1542 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1543 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
1544 struct smb_rqst rqst
= { .rq_iov
= &rdata
->iov
,
1546 .rq_pages
= rdata
->pages
,
1547 .rq_npages
= rdata
->nr_pages
,
1548 .rq_pagesz
= rdata
->pagesz
,
1549 .rq_tailsz
= rdata
->tailsz
};
1551 cifs_dbg(FYI
, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1552 __func__
, mid
->mid
, mid
->mid_state
, rdata
->result
,
1555 switch (mid
->mid_state
) {
1556 case MID_RESPONSE_RECEIVED
:
1557 /* result already set, check signature */
1558 if (server
->sec_mode
&
1559 (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
)) {
1562 rc
= cifs_verify_signature(&rqst
, server
,
1563 mid
->sequence_number
);
1565 cifs_dbg(VFS
, "SMB signature verification returned error = %d\n",
1568 /* FIXME: should this be counted toward the initiating task? */
1569 task_io_account_read(rdata
->bytes
);
1570 cifs_stats_bytes_read(tcon
, rdata
->bytes
);
1572 case MID_REQUEST_SUBMITTED
:
1573 case MID_RETRY_NEEDED
:
1574 rdata
->result
= -EAGAIN
;
1577 rdata
->result
= -EIO
;
1580 queue_work(cifsiod_wq
, &rdata
->work
);
1581 DeleteMidQEntry(mid
);
1582 add_credits(server
, 1, 0);
1585 /* cifs_async_readv - send an async write, and set up mid to handle result */
1587 cifs_async_readv(struct cifs_readdata
*rdata
)
1590 READ_REQ
*smb
= NULL
;
1592 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1593 struct smb_rqst rqst
= { .rq_iov
= &rdata
->iov
,
1596 cifs_dbg(FYI
, "%s: offset=%llu bytes=%u\n",
1597 __func__
, rdata
->offset
, rdata
->bytes
);
1599 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1602 wct
= 10; /* old style read */
1603 if ((rdata
->offset
>> 32) > 0) {
1604 /* can not handle this big offset for old */
1609 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **)&smb
);
1613 smb
->hdr
.Pid
= cpu_to_le16((__u16
)rdata
->pid
);
1614 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(rdata
->pid
>> 16));
1616 smb
->AndXCommand
= 0xFF; /* none */
1617 smb
->Fid
= rdata
->cfile
->fid
.netfid
;
1618 smb
->OffsetLow
= cpu_to_le32(rdata
->offset
& 0xFFFFFFFF);
1620 smb
->OffsetHigh
= cpu_to_le32(rdata
->offset
>> 32);
1622 smb
->MaxCount
= cpu_to_le16(rdata
->bytes
& 0xFFFF);
1623 smb
->MaxCountHigh
= cpu_to_le32(rdata
->bytes
>> 16);
1627 /* old style read */
1628 struct smb_com_readx_req
*smbr
=
1629 (struct smb_com_readx_req
*)smb
;
1630 smbr
->ByteCount
= 0;
1633 /* 4 for RFC1001 length + 1 for BCC */
1634 rdata
->iov
.iov_base
= smb
;
1635 rdata
->iov
.iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4;
1637 kref_get(&rdata
->refcount
);
1638 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, cifs_readv_receive
,
1639 cifs_readv_callback
, rdata
, 0);
1642 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1644 kref_put(&rdata
->refcount
, cifs_readdata_release
);
1646 cifs_small_buf_release(smb
);
1651 CIFSSMBRead(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1652 unsigned int *nbytes
, char **buf
, int *pbuf_type
)
1655 READ_REQ
*pSMB
= NULL
;
1656 READ_RSP
*pSMBr
= NULL
;
1657 char *pReadData
= NULL
;
1659 int resp_buf_type
= 0;
1661 __u32 pid
= io_parms
->pid
;
1662 __u16 netfid
= io_parms
->netfid
;
1663 __u64 offset
= io_parms
->offset
;
1664 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1665 unsigned int count
= io_parms
->length
;
1667 cifs_dbg(FYI
, "Reading %d bytes on fid %d\n", count
, netfid
);
1668 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1671 wct
= 10; /* old style read */
1672 if ((offset
>> 32) > 0) {
1673 /* can not handle this big offset for old */
1679 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **) &pSMB
);
1683 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1684 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1686 /* tcon and ses pointer are checked in smb_init */
1687 if (tcon
->ses
->server
== NULL
)
1688 return -ECONNABORTED
;
1690 pSMB
->AndXCommand
= 0xFF; /* none */
1692 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1694 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1696 pSMB
->Remaining
= 0;
1697 pSMB
->MaxCount
= cpu_to_le16(count
& 0xFFFF);
1698 pSMB
->MaxCountHigh
= cpu_to_le32(count
>> 16);
1700 pSMB
->ByteCount
= 0; /* no need to do le conversion since 0 */
1702 /* old style read */
1703 struct smb_com_readx_req
*pSMBW
=
1704 (struct smb_com_readx_req
*)pSMB
;
1705 pSMBW
->ByteCount
= 0;
1708 iov
[0].iov_base
= (char *)pSMB
;
1709 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
1710 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
1711 &resp_buf_type
, CIFS_LOG_ERROR
);
1712 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1713 pSMBr
= (READ_RSP
*)iov
[0].iov_base
;
1715 cifs_dbg(VFS
, "Send error in read = %d\n", rc
);
1717 int data_length
= le16_to_cpu(pSMBr
->DataLengthHigh
);
1718 data_length
= data_length
<< 16;
1719 data_length
+= le16_to_cpu(pSMBr
->DataLength
);
1720 *nbytes
= data_length
;
1722 /*check that DataLength would not go beyond end of SMB */
1723 if ((data_length
> CIFSMaxBufSize
)
1724 || (data_length
> count
)) {
1725 cifs_dbg(FYI
, "bad length %d for count %d\n",
1726 data_length
, count
);
1730 pReadData
= (char *) (&pSMBr
->hdr
.Protocol
) +
1731 le16_to_cpu(pSMBr
->DataOffset
);
1732 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1733 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1735 }*/ /* can not use copy_to_user when using page cache*/
1737 memcpy(*buf
, pReadData
, data_length
);
1741 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1743 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1744 cifs_small_buf_release(iov
[0].iov_base
);
1745 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1746 cifs_buf_release(iov
[0].iov_base
);
1747 } else if (resp_buf_type
!= CIFS_NO_BUFFER
) {
1748 /* return buffer to caller to free */
1749 *buf
= iov
[0].iov_base
;
1750 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1751 *pbuf_type
= CIFS_SMALL_BUFFER
;
1752 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1753 *pbuf_type
= CIFS_LARGE_BUFFER
;
1754 } /* else no valid buffer on return - leave as null */
1756 /* Note: On -EAGAIN error only caller can retry on handle based calls
1757 since file handle passed in no longer valid */
1763 CIFSSMBWrite(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1764 unsigned int *nbytes
, const char *buf
,
1765 const char __user
*ubuf
, const int long_op
)
1768 WRITE_REQ
*pSMB
= NULL
;
1769 WRITE_RSP
*pSMBr
= NULL
;
1770 int bytes_returned
, wct
;
1773 __u32 pid
= io_parms
->pid
;
1774 __u16 netfid
= io_parms
->netfid
;
1775 __u64 offset
= io_parms
->offset
;
1776 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1777 unsigned int count
= io_parms
->length
;
1781 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1782 if (tcon
->ses
== NULL
)
1783 return -ECONNABORTED
;
1785 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1789 if ((offset
>> 32) > 0) {
1790 /* can not handle big offset for old srv */
1795 rc
= smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
,
1800 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1801 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1803 /* tcon and ses pointer are checked in smb_init */
1804 if (tcon
->ses
->server
== NULL
)
1805 return -ECONNABORTED
;
1807 pSMB
->AndXCommand
= 0xFF; /* none */
1809 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1811 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1813 pSMB
->Reserved
= 0xFFFFFFFF;
1814 pSMB
->WriteMode
= 0;
1815 pSMB
->Remaining
= 0;
1817 /* Can increase buffer size if buffer is big enough in some cases ie we
1818 can send more if LARGE_WRITE_X capability returned by the server and if
1819 our buffer is big enough or if we convert to iovecs on socket writes
1820 and eliminate the copy to the CIFS buffer */
1821 if (tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
) {
1822 bytes_sent
= min_t(const unsigned int, CIFSMaxBufSize
, count
);
1824 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
)
1828 if (bytes_sent
> count
)
1831 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1833 memcpy(pSMB
->Data
, buf
, bytes_sent
);
1835 if (copy_from_user(pSMB
->Data
, ubuf
, bytes_sent
)) {
1836 cifs_buf_release(pSMB
);
1839 } else if (count
!= 0) {
1841 cifs_buf_release(pSMB
);
1843 } /* else setting file size with write of zero bytes */
1845 byte_count
= bytes_sent
+ 1; /* pad */
1846 else /* wct == 12 */
1847 byte_count
= bytes_sent
+ 5; /* bigger pad, smaller smb hdr */
1849 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
& 0xFFFF);
1850 pSMB
->DataLengthHigh
= cpu_to_le16(bytes_sent
>> 16);
1851 inc_rfc1001_len(pSMB
, byte_count
);
1854 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1855 else { /* old style write has byte count 4 bytes earlier
1857 struct smb_com_writex_req
*pSMBW
=
1858 (struct smb_com_writex_req
*)pSMB
;
1859 pSMBW
->ByteCount
= cpu_to_le16(byte_count
);
1862 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1863 (struct smb_hdr
*) pSMBr
, &bytes_returned
, long_op
);
1864 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
1866 cifs_dbg(FYI
, "Send error in write = %d\n", rc
);
1868 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
1869 *nbytes
= (*nbytes
) << 16;
1870 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
1873 * Mask off high 16 bits when bytes written as returned by the
1874 * server is greater than bytes requested by the client. Some
1875 * OS/2 servers are known to set incorrect CountHigh values.
1877 if (*nbytes
> count
)
1881 cifs_buf_release(pSMB
);
1883 /* Note: On -EAGAIN error only caller can retry on handle based calls
1884 since file handle passed in no longer valid */
1890 cifs_writedata_release(struct kref
*refcount
)
1892 struct cifs_writedata
*wdata
= container_of(refcount
,
1893 struct cifs_writedata
, refcount
);
1896 cifsFileInfo_put(wdata
->cfile
);
1902 * Write failed with a retryable error. Resend the write request. It's also
1903 * possible that the page was redirtied so re-clean the page.
1906 cifs_writev_requeue(struct cifs_writedata
*wdata
)
1909 struct inode
*inode
= wdata
->cfile
->dentry
->d_inode
;
1910 struct TCP_Server_Info
*server
;
1912 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
1913 lock_page(wdata
->pages
[i
]);
1914 clear_page_dirty_for_io(wdata
->pages
[i
]);
1918 server
= tlink_tcon(wdata
->cfile
->tlink
)->ses
->server
;
1919 rc
= server
->ops
->async_writev(wdata
);
1920 } while (rc
== -EAGAIN
);
1922 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
1923 unlock_page(wdata
->pages
[i
]);
1925 SetPageError(wdata
->pages
[i
]);
1926 end_page_writeback(wdata
->pages
[i
]);
1927 page_cache_release(wdata
->pages
[i
]);
1931 mapping_set_error(inode
->i_mapping
, rc
);
1932 kref_put(&wdata
->refcount
, cifs_writedata_release
);
1936 cifs_writev_complete(struct work_struct
*work
)
1938 struct cifs_writedata
*wdata
= container_of(work
,
1939 struct cifs_writedata
, work
);
1940 struct inode
*inode
= wdata
->cfile
->dentry
->d_inode
;
1943 if (wdata
->result
== 0) {
1944 spin_lock(&inode
->i_lock
);
1945 cifs_update_eof(CIFS_I(inode
), wdata
->offset
, wdata
->bytes
);
1946 spin_unlock(&inode
->i_lock
);
1947 cifs_stats_bytes_written(tlink_tcon(wdata
->cfile
->tlink
),
1949 } else if (wdata
->sync_mode
== WB_SYNC_ALL
&& wdata
->result
== -EAGAIN
)
1950 return cifs_writev_requeue(wdata
);
1952 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
1953 struct page
*page
= wdata
->pages
[i
];
1954 if (wdata
->result
== -EAGAIN
)
1955 __set_page_dirty_nobuffers(page
);
1956 else if (wdata
->result
< 0)
1958 end_page_writeback(page
);
1959 page_cache_release(page
);
1961 if (wdata
->result
!= -EAGAIN
)
1962 mapping_set_error(inode
->i_mapping
, wdata
->result
);
1963 kref_put(&wdata
->refcount
, cifs_writedata_release
);
1966 struct cifs_writedata
*
1967 cifs_writedata_alloc(unsigned int nr_pages
, work_func_t complete
)
1969 struct cifs_writedata
*wdata
;
1971 /* this would overflow */
1972 if (nr_pages
== 0) {
1973 cifs_dbg(VFS
, "%s: called with nr_pages == 0!\n", __func__
);
1977 /* writedata + number of page pointers */
1978 wdata
= kzalloc(sizeof(*wdata
) +
1979 sizeof(struct page
*) * (nr_pages
- 1), GFP_NOFS
);
1980 if (wdata
!= NULL
) {
1981 kref_init(&wdata
->refcount
);
1982 INIT_LIST_HEAD(&wdata
->list
);
1983 init_completion(&wdata
->done
);
1984 INIT_WORK(&wdata
->work
, complete
);
1990 * Check the mid_state and signature on received buffer (if any), and queue the
1991 * workqueue completion task.
1994 cifs_writev_callback(struct mid_q_entry
*mid
)
1996 struct cifs_writedata
*wdata
= mid
->callback_data
;
1997 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
1998 unsigned int written
;
1999 WRITE_RSP
*smb
= (WRITE_RSP
*)mid
->resp_buf
;
2001 switch (mid
->mid_state
) {
2002 case MID_RESPONSE_RECEIVED
:
2003 wdata
->result
= cifs_check_receive(mid
, tcon
->ses
->server
, 0);
2004 if (wdata
->result
!= 0)
2007 written
= le16_to_cpu(smb
->CountHigh
);
2009 written
+= le16_to_cpu(smb
->Count
);
2011 * Mask off high 16 bits when bytes written as returned
2012 * by the server is greater than bytes requested by the
2013 * client. OS/2 servers are known to set incorrect
2016 if (written
> wdata
->bytes
)
2019 if (written
< wdata
->bytes
)
2020 wdata
->result
= -ENOSPC
;
2022 wdata
->bytes
= written
;
2024 case MID_REQUEST_SUBMITTED
:
2025 case MID_RETRY_NEEDED
:
2026 wdata
->result
= -EAGAIN
;
2029 wdata
->result
= -EIO
;
2033 queue_work(cifsiod_wq
, &wdata
->work
);
2034 DeleteMidQEntry(mid
);
2035 add_credits(tcon
->ses
->server
, 1, 0);
2038 /* cifs_async_writev - send an async write, and set up mid to handle result */
2040 cifs_async_writev(struct cifs_writedata
*wdata
)
2043 WRITE_REQ
*smb
= NULL
;
2045 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2047 struct smb_rqst rqst
= { };
2049 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2053 if (wdata
->offset
>> 32 > 0) {
2054 /* can not handle big offset for old srv */
2059 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **)&smb
);
2061 goto async_writev_out
;
2063 smb
->hdr
.Pid
= cpu_to_le16((__u16
)wdata
->pid
);
2064 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(wdata
->pid
>> 16));
2066 smb
->AndXCommand
= 0xFF; /* none */
2067 smb
->Fid
= wdata
->cfile
->fid
.netfid
;
2068 smb
->OffsetLow
= cpu_to_le32(wdata
->offset
& 0xFFFFFFFF);
2070 smb
->OffsetHigh
= cpu_to_le32(wdata
->offset
>> 32);
2071 smb
->Reserved
= 0xFFFFFFFF;
2076 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2078 /* 4 for RFC1001 length + 1 for BCC */
2079 iov
.iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4 + 1;
2084 rqst
.rq_pages
= wdata
->pages
;
2085 rqst
.rq_npages
= wdata
->nr_pages
;
2086 rqst
.rq_pagesz
= wdata
->pagesz
;
2087 rqst
.rq_tailsz
= wdata
->tailsz
;
2089 cifs_dbg(FYI
, "async write at %llu %u bytes\n",
2090 wdata
->offset
, wdata
->bytes
);
2092 smb
->DataLengthLow
= cpu_to_le16(wdata
->bytes
& 0xFFFF);
2093 smb
->DataLengthHigh
= cpu_to_le16(wdata
->bytes
>> 16);
2096 inc_rfc1001_len(&smb
->hdr
, wdata
->bytes
+ 1);
2097 put_bcc(wdata
->bytes
+ 1, &smb
->hdr
);
2100 struct smb_com_writex_req
*smbw
=
2101 (struct smb_com_writex_req
*)smb
;
2102 inc_rfc1001_len(&smbw
->hdr
, wdata
->bytes
+ 5);
2103 put_bcc(wdata
->bytes
+ 5, &smbw
->hdr
);
2104 iov
.iov_len
+= 4; /* pad bigger by four bytes */
2107 kref_get(&wdata
->refcount
);
2108 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, NULL
,
2109 cifs_writev_callback
, wdata
, 0);
2112 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2114 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2117 cifs_small_buf_release(smb
);
2122 CIFSSMBWrite2(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
2123 unsigned int *nbytes
, struct kvec
*iov
, int n_vec
)
2126 WRITE_REQ
*pSMB
= NULL
;
2129 int resp_buf_type
= 0;
2130 __u32 pid
= io_parms
->pid
;
2131 __u16 netfid
= io_parms
->netfid
;
2132 __u64 offset
= io_parms
->offset
;
2133 struct cifs_tcon
*tcon
= io_parms
->tcon
;
2134 unsigned int count
= io_parms
->length
;
2138 cifs_dbg(FYI
, "write2 at %lld %d bytes\n", (long long)offset
, count
);
2140 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2144 if ((offset
>> 32) > 0) {
2145 /* can not handle big offset for old srv */
2149 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
);
2153 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
2154 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
2156 /* tcon and ses pointer are checked in smb_init */
2157 if (tcon
->ses
->server
== NULL
)
2158 return -ECONNABORTED
;
2160 pSMB
->AndXCommand
= 0xFF; /* none */
2162 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
2164 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
2165 pSMB
->Reserved
= 0xFFFFFFFF;
2166 pSMB
->WriteMode
= 0;
2167 pSMB
->Remaining
= 0;
2170 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2172 pSMB
->DataLengthLow
= cpu_to_le16(count
& 0xFFFF);
2173 pSMB
->DataLengthHigh
= cpu_to_le16(count
>> 16);
2174 /* header + 1 byte pad */
2175 smb_hdr_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 1;
2177 inc_rfc1001_len(pSMB
, count
+ 1);
2178 else /* wct == 12 */
2179 inc_rfc1001_len(pSMB
, count
+ 5); /* smb data starts later */
2181 pSMB
->ByteCount
= cpu_to_le16(count
+ 1);
2182 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2183 struct smb_com_writex_req
*pSMBW
=
2184 (struct smb_com_writex_req
*)pSMB
;
2185 pSMBW
->ByteCount
= cpu_to_le16(count
+ 5);
2187 iov
[0].iov_base
= pSMB
;
2189 iov
[0].iov_len
= smb_hdr_len
+ 4;
2190 else /* wct == 12 pad bigger by four bytes */
2191 iov
[0].iov_len
= smb_hdr_len
+ 8;
2194 rc
= SendReceive2(xid
, tcon
->ses
, iov
, n_vec
+ 1, &resp_buf_type
, 0);
2195 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2197 cifs_dbg(FYI
, "Send error Write2 = %d\n", rc
);
2198 } else if (resp_buf_type
== 0) {
2199 /* presumably this can not happen, but best to be safe */
2202 WRITE_RSP
*pSMBr
= (WRITE_RSP
*)iov
[0].iov_base
;
2203 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2204 *nbytes
= (*nbytes
) << 16;
2205 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2208 * Mask off high 16 bits when bytes written as returned by the
2209 * server is greater than bytes requested by the client. OS/2
2210 * servers are known to set incorrect CountHigh values.
2212 if (*nbytes
> count
)
2216 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2217 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
2218 cifs_small_buf_release(iov
[0].iov_base
);
2219 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
2220 cifs_buf_release(iov
[0].iov_base
);
2222 /* Note: On -EAGAIN error only caller can retry on handle based calls
2223 since file handle passed in no longer valid */
2228 int cifs_lockv(const unsigned int xid
, struct cifs_tcon
*tcon
,
2229 const __u16 netfid
, const __u8 lock_type
, const __u32 num_unlock
,
2230 const __u32 num_lock
, LOCKING_ANDX_RANGE
*buf
)
2233 LOCK_REQ
*pSMB
= NULL
;
2238 cifs_dbg(FYI
, "cifs_lockv num lock %d num unlock %d\n",
2239 num_lock
, num_unlock
);
2241 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2246 pSMB
->NumberOfLocks
= cpu_to_le16(num_lock
);
2247 pSMB
->NumberOfUnlocks
= cpu_to_le16(num_unlock
);
2248 pSMB
->LockType
= lock_type
;
2249 pSMB
->AndXCommand
= 0xFF; /* none */
2250 pSMB
->Fid
= netfid
; /* netfid stays le */
2252 count
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2253 inc_rfc1001_len(pSMB
, count
);
2254 pSMB
->ByteCount
= cpu_to_le16(count
);
2256 iov
[0].iov_base
= (char *)pSMB
;
2257 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4 -
2258 (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2259 iov
[1].iov_base
= (char *)buf
;
2260 iov
[1].iov_len
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2262 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2263 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 2, &resp_buf_type
, CIFS_NO_RESP
);
2265 cifs_dbg(FYI
, "Send error in cifs_lockv = %d\n", rc
);
2271 CIFSSMBLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2272 const __u16 smb_file_id
, const __u32 netpid
, const __u64 len
,
2273 const __u64 offset
, const __u32 numUnlock
,
2274 const __u32 numLock
, const __u8 lockType
,
2275 const bool waitFlag
, const __u8 oplock_level
)
2278 LOCK_REQ
*pSMB
= NULL
;
2279 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2284 cifs_dbg(FYI
, "CIFSSMBLock timeout %d numLock %d\n",
2285 (int)waitFlag
, numLock
);
2286 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2291 if (lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
2292 /* no response expected */
2293 flags
= CIFS_ASYNC_OP
| CIFS_OBREAK_OP
;
2295 } else if (waitFlag
) {
2296 flags
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2297 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
2302 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
2303 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
2304 pSMB
->LockType
= lockType
;
2305 pSMB
->OplockLevel
= oplock_level
;
2306 pSMB
->AndXCommand
= 0xFF; /* none */
2307 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
2309 if ((numLock
!= 0) || (numUnlock
!= 0)) {
2310 pSMB
->Locks
[0].Pid
= cpu_to_le16(netpid
);
2311 /* BB where to store pid high? */
2312 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
2313 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
2314 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
2315 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
2316 count
= sizeof(LOCKING_ANDX_RANGE
);
2321 inc_rfc1001_len(pSMB
, count
);
2322 pSMB
->ByteCount
= cpu_to_le16(count
);
2325 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2326 (struct smb_hdr
*) pSMB
, &bytes_returned
);
2327 cifs_small_buf_release(pSMB
);
2329 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)pSMB
, flags
);
2330 /* SMB buffer freed by function above */
2332 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2334 cifs_dbg(FYI
, "Send error in Lock = %d\n", rc
);
2336 /* Note: On -EAGAIN error only caller can retry on handle based calls
2337 since file handle passed in no longer valid */
2342 CIFSSMBPosixLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2343 const __u16 smb_file_id
, const __u32 netpid
,
2344 const loff_t start_offset
, const __u64 len
,
2345 struct file_lock
*pLockData
, const __u16 lock_type
,
2346 const bool waitFlag
)
2348 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2349 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2350 struct cifs_posix_lock
*parm_data
;
2353 int bytes_returned
= 0;
2354 int resp_buf_type
= 0;
2355 __u16 params
, param_offset
, offset
, byte_count
, count
;
2358 cifs_dbg(FYI
, "Posix Lock\n");
2360 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
2365 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)pSMB
;
2368 pSMB
->MaxSetupCount
= 0;
2371 pSMB
->Reserved2
= 0;
2372 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2373 offset
= param_offset
+ params
;
2375 count
= sizeof(struct cifs_posix_lock
);
2376 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2377 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2378 pSMB
->SetupCount
= 1;
2379 pSMB
->Reserved3
= 0;
2381 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
2383 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2384 byte_count
= 3 /* pad */ + params
+ count
;
2385 pSMB
->DataCount
= cpu_to_le16(count
);
2386 pSMB
->ParameterCount
= cpu_to_le16(params
);
2387 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2388 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2389 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2390 parm_data
= (struct cifs_posix_lock
*)
2391 (((char *) &pSMB
->hdr
.Protocol
) + offset
);
2393 parm_data
->lock_type
= cpu_to_le16(lock_type
);
2395 timeout
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2396 parm_data
->lock_flags
= cpu_to_le16(1);
2397 pSMB
->Timeout
= cpu_to_le32(-1);
2401 parm_data
->pid
= cpu_to_le32(netpid
);
2402 parm_data
->start
= cpu_to_le64(start_offset
);
2403 parm_data
->length
= cpu_to_le64(len
); /* normalize negative numbers */
2405 pSMB
->DataOffset
= cpu_to_le16(offset
);
2406 pSMB
->Fid
= smb_file_id
;
2407 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_LOCK
);
2408 pSMB
->Reserved4
= 0;
2409 inc_rfc1001_len(pSMB
, byte_count
);
2410 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2412 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2413 (struct smb_hdr
*) pSMBr
, &bytes_returned
);
2415 iov
[0].iov_base
= (char *)pSMB
;
2416 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
2417 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
2418 &resp_buf_type
, timeout
);
2419 pSMB
= NULL
; /* request buf already freed by SendReceive2. Do
2420 not try to free it twice below on exit */
2421 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)iov
[0].iov_base
;
2425 cifs_dbg(FYI
, "Send error in Posix Lock = %d\n", rc
);
2426 } else if (pLockData
) {
2427 /* lock structure can be returned on get */
2430 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2432 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(*parm_data
)) {
2433 rc
= -EIO
; /* bad smb */
2436 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
2437 data_count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2438 if (data_count
< sizeof(struct cifs_posix_lock
)) {
2442 parm_data
= (struct cifs_posix_lock
*)
2443 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2444 if (parm_data
->lock_type
== __constant_cpu_to_le16(CIFS_UNLCK
))
2445 pLockData
->fl_type
= F_UNLCK
;
2447 if (parm_data
->lock_type
==
2448 __constant_cpu_to_le16(CIFS_RDLCK
))
2449 pLockData
->fl_type
= F_RDLCK
;
2450 else if (parm_data
->lock_type
==
2451 __constant_cpu_to_le16(CIFS_WRLCK
))
2452 pLockData
->fl_type
= F_WRLCK
;
2454 pLockData
->fl_start
= le64_to_cpu(parm_data
->start
);
2455 pLockData
->fl_end
= pLockData
->fl_start
+
2456 le64_to_cpu(parm_data
->length
) - 1;
2457 pLockData
->fl_pid
= le32_to_cpu(parm_data
->pid
);
2463 cifs_small_buf_release(pSMB
);
2465 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
2466 cifs_small_buf_release(iov
[0].iov_base
);
2467 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
2468 cifs_buf_release(iov
[0].iov_base
);
2470 /* Note: On -EAGAIN error only caller can retry on handle based calls
2471 since file handle passed in no longer valid */
2478 CIFSSMBClose(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2481 CLOSE_REQ
*pSMB
= NULL
;
2482 cifs_dbg(FYI
, "In CIFSSMBClose\n");
2484 /* do not retry on dead session on close */
2485 rc
= small_smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
);
2491 pSMB
->FileID
= (__u16
) smb_file_id
;
2492 pSMB
->LastWriteTime
= 0xFFFFFFFF;
2493 pSMB
->ByteCount
= 0;
2494 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2495 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_closes
);
2498 /* EINTR is expected when user ctl-c to kill app */
2499 cifs_dbg(VFS
, "Send error in Close = %d\n", rc
);
2503 /* Since session is dead, file will be closed on server already */
2511 CIFSSMBFlush(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2514 FLUSH_REQ
*pSMB
= NULL
;
2515 cifs_dbg(FYI
, "In CIFSSMBFlush\n");
2517 rc
= small_smb_init(SMB_COM_FLUSH
, 1, tcon
, (void **) &pSMB
);
2521 pSMB
->FileID
= (__u16
) smb_file_id
;
2522 pSMB
->ByteCount
= 0;
2523 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2524 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_flushes
);
2526 cifs_dbg(VFS
, "Send error in Flush = %d\n", rc
);
2532 CIFSSMBRename(const unsigned int xid
, struct cifs_tcon
*tcon
,
2533 const char *from_name
, const char *to_name
,
2534 struct cifs_sb_info
*cifs_sb
)
2537 RENAME_REQ
*pSMB
= NULL
;
2538 RENAME_RSP
*pSMBr
= NULL
;
2540 int name_len
, name_len2
;
2542 int remap
= cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
;
2544 cifs_dbg(FYI
, "In CIFSSMBRename\n");
2546 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
2551 pSMB
->BufferFormat
= 0x04;
2552 pSMB
->SearchAttributes
=
2553 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2556 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2557 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2558 from_name
, PATH_MAX
,
2559 cifs_sb
->local_nls
, remap
);
2560 name_len
++; /* trailing null */
2562 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2563 /* protocol requires ASCII signature byte on Unicode string */
2564 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2566 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2567 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2569 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2570 name_len2
*= 2; /* convert to bytes */
2571 } else { /* BB improve the check for buffer overruns BB */
2572 name_len
= strnlen(from_name
, PATH_MAX
);
2573 name_len
++; /* trailing null */
2574 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
2575 name_len2
= strnlen(to_name
, PATH_MAX
);
2576 name_len2
++; /* trailing null */
2577 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2578 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
2579 name_len2
++; /* trailing null */
2580 name_len2
++; /* signature byte */
2583 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2584 inc_rfc1001_len(pSMB
, count
);
2585 pSMB
->ByteCount
= cpu_to_le16(count
);
2587 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2588 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2589 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_renames
);
2591 cifs_dbg(FYI
, "Send error in rename = %d\n", rc
);
2593 cifs_buf_release(pSMB
);
2601 int CIFSSMBRenameOpenFile(const unsigned int xid
, struct cifs_tcon
*pTcon
,
2602 int netfid
, const char *target_name
,
2603 const struct nls_table
*nls_codepage
, int remap
)
2605 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2606 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2607 struct set_file_rename
*rename_info
;
2609 char dummy_string
[30];
2611 int bytes_returned
= 0;
2613 __u16 params
, param_offset
, offset
, count
, byte_count
;
2615 cifs_dbg(FYI
, "Rename to File by handle\n");
2616 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
2622 pSMB
->MaxSetupCount
= 0;
2626 pSMB
->Reserved2
= 0;
2627 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2628 offset
= param_offset
+ params
;
2630 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2631 rename_info
= (struct set_file_rename
*) data_offset
;
2632 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2633 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2634 pSMB
->SetupCount
= 1;
2635 pSMB
->Reserved3
= 0;
2636 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2637 byte_count
= 3 /* pad */ + params
;
2638 pSMB
->ParameterCount
= cpu_to_le16(params
);
2639 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2640 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2641 pSMB
->DataOffset
= cpu_to_le16(offset
);
2642 /* construct random name ".cifs_tmp<inodenum><mid>" */
2643 rename_info
->overwrite
= cpu_to_le32(1);
2644 rename_info
->root_fid
= 0;
2645 /* unicode only call */
2646 if (target_name
== NULL
) {
2647 sprintf(dummy_string
, "cifs%x", pSMB
->hdr
.Mid
);
2649 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2650 dummy_string
, 24, nls_codepage
, remap
);
2653 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2654 target_name
, PATH_MAX
, nls_codepage
,
2657 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
2658 count
= 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str
);
2659 byte_count
+= count
;
2660 pSMB
->DataCount
= cpu_to_le16(count
);
2661 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2663 pSMB
->InformationLevel
=
2664 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
2665 pSMB
->Reserved4
= 0;
2666 inc_rfc1001_len(pSMB
, byte_count
);
2667 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2668 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
2669 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2670 cifs_stats_inc(&pTcon
->stats
.cifs_stats
.num_t2renames
);
2672 cifs_dbg(FYI
, "Send error in Rename (by file handle) = %d\n",
2675 cifs_buf_release(pSMB
);
2677 /* Note: On -EAGAIN error only caller can retry on handle based calls
2678 since file handle passed in no longer valid */
2684 CIFSSMBCopy(const unsigned int xid
, struct cifs_tcon
*tcon
,
2685 const char *fromName
, const __u16 target_tid
, const char *toName
,
2686 const int flags
, const struct nls_table
*nls_codepage
, int remap
)
2689 COPY_REQ
*pSMB
= NULL
;
2690 COPY_RSP
*pSMBr
= NULL
;
2692 int name_len
, name_len2
;
2695 cifs_dbg(FYI
, "In CIFSSMBCopy\n");
2697 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
2702 pSMB
->BufferFormat
= 0x04;
2703 pSMB
->Tid2
= target_tid
;
2705 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
2707 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2708 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2709 fromName
, PATH_MAX
, nls_codepage
,
2711 name_len
++; /* trailing null */
2713 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2714 /* protocol requires ASCII signature byte on Unicode string */
2715 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2717 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2718 toName
, PATH_MAX
, nls_codepage
, remap
);
2719 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2720 name_len2
*= 2; /* convert to bytes */
2721 } else { /* BB improve the check for buffer overruns BB */
2722 name_len
= strnlen(fromName
, PATH_MAX
);
2723 name_len
++; /* trailing null */
2724 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
2725 name_len2
= strnlen(toName
, PATH_MAX
);
2726 name_len2
++; /* trailing null */
2727 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2728 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
2729 name_len2
++; /* trailing null */
2730 name_len2
++; /* signature byte */
2733 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2734 inc_rfc1001_len(pSMB
, count
);
2735 pSMB
->ByteCount
= cpu_to_le16(count
);
2737 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2738 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2740 cifs_dbg(FYI
, "Send error in copy = %d with %d files copied\n",
2741 rc
, le16_to_cpu(pSMBr
->CopyCount
));
2743 cifs_buf_release(pSMB
);
2752 CIFSUnixCreateSymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2753 const char *fromName
, const char *toName
,
2754 const struct nls_table
*nls_codepage
)
2756 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2757 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2760 int name_len_target
;
2762 int bytes_returned
= 0;
2763 __u16 params
, param_offset
, offset
, byte_count
;
2765 cifs_dbg(FYI
, "In Symlink Unix style\n");
2767 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2772 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2774 cifs_strtoUTF16((__le16
*) pSMB
->FileName
, fromName
,
2775 /* find define for this maxpathcomponent */
2776 PATH_MAX
, nls_codepage
);
2777 name_len
++; /* trailing null */
2780 } else { /* BB improve the check for buffer overruns BB */
2781 name_len
= strnlen(fromName
, PATH_MAX
);
2782 name_len
++; /* trailing null */
2783 strncpy(pSMB
->FileName
, fromName
, name_len
);
2785 params
= 6 + name_len
;
2786 pSMB
->MaxSetupCount
= 0;
2790 pSMB
->Reserved2
= 0;
2791 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2792 InformationLevel
) - 4;
2793 offset
= param_offset
+ params
;
2795 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2796 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2798 cifs_strtoUTF16((__le16
*) data_offset
, toName
, PATH_MAX
2799 /* find define for this maxpathcomponent */
2801 name_len_target
++; /* trailing null */
2802 name_len_target
*= 2;
2803 } else { /* BB improve the check for buffer overruns BB */
2804 name_len_target
= strnlen(toName
, PATH_MAX
);
2805 name_len_target
++; /* trailing null */
2806 strncpy(data_offset
, toName
, name_len_target
);
2809 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2810 /* BB find exact max on data count below from sess */
2811 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2812 pSMB
->SetupCount
= 1;
2813 pSMB
->Reserved3
= 0;
2814 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2815 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2816 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2817 pSMB
->ParameterCount
= cpu_to_le16(params
);
2818 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2819 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2820 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2821 pSMB
->DataOffset
= cpu_to_le16(offset
);
2822 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
2823 pSMB
->Reserved4
= 0;
2824 inc_rfc1001_len(pSMB
, byte_count
);
2825 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2826 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2827 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2828 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_symlinks
);
2830 cifs_dbg(FYI
, "Send error in SetPathInfo create symlink = %d\n",
2833 cifs_buf_release(pSMB
);
2836 goto createSymLinkRetry
;
2842 CIFSUnixCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2843 const char *fromName
, const char *toName
,
2844 const struct nls_table
*nls_codepage
, int remap
)
2846 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2847 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2850 int name_len_target
;
2852 int bytes_returned
= 0;
2853 __u16 params
, param_offset
, offset
, byte_count
;
2855 cifs_dbg(FYI
, "In Create Hard link Unix style\n");
2856 createHardLinkRetry
:
2857 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2862 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2863 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->FileName
, toName
,
2864 PATH_MAX
, nls_codepage
, remap
);
2865 name_len
++; /* trailing null */
2868 } else { /* BB improve the check for buffer overruns BB */
2869 name_len
= strnlen(toName
, PATH_MAX
);
2870 name_len
++; /* trailing null */
2871 strncpy(pSMB
->FileName
, toName
, name_len
);
2873 params
= 6 + name_len
;
2874 pSMB
->MaxSetupCount
= 0;
2878 pSMB
->Reserved2
= 0;
2879 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2880 InformationLevel
) - 4;
2881 offset
= param_offset
+ params
;
2883 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2884 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2886 cifsConvertToUTF16((__le16
*) data_offset
, fromName
,
2887 PATH_MAX
, nls_codepage
, remap
);
2888 name_len_target
++; /* trailing null */
2889 name_len_target
*= 2;
2890 } else { /* BB improve the check for buffer overruns BB */
2891 name_len_target
= strnlen(fromName
, PATH_MAX
);
2892 name_len_target
++; /* trailing null */
2893 strncpy(data_offset
, fromName
, name_len_target
);
2896 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2897 /* BB find exact max on data count below from sess*/
2898 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2899 pSMB
->SetupCount
= 1;
2900 pSMB
->Reserved3
= 0;
2901 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2902 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2903 pSMB
->ParameterCount
= cpu_to_le16(params
);
2904 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2905 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2906 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2907 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2908 pSMB
->DataOffset
= cpu_to_le16(offset
);
2909 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
2910 pSMB
->Reserved4
= 0;
2911 inc_rfc1001_len(pSMB
, byte_count
);
2912 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2913 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2914 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2915 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
2917 cifs_dbg(FYI
, "Send error in SetPathInfo (hard link) = %d\n",
2920 cifs_buf_release(pSMB
);
2922 goto createHardLinkRetry
;
2928 CIFSCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2929 const char *from_name
, const char *to_name
,
2930 struct cifs_sb_info
*cifs_sb
)
2933 NT_RENAME_REQ
*pSMB
= NULL
;
2934 RENAME_RSP
*pSMBr
= NULL
;
2936 int name_len
, name_len2
;
2938 int remap
= cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
;
2940 cifs_dbg(FYI
, "In CIFSCreateHardLink\n");
2941 winCreateHardLinkRetry
:
2943 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
2948 pSMB
->SearchAttributes
=
2949 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2951 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
2952 pSMB
->ClusterCount
= 0;
2954 pSMB
->BufferFormat
= 0x04;
2956 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2958 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, from_name
,
2959 PATH_MAX
, cifs_sb
->local_nls
, remap
);
2960 name_len
++; /* trailing null */
2963 /* protocol specifies ASCII buffer format (0x04) for unicode */
2964 pSMB
->OldFileName
[name_len
] = 0x04;
2965 pSMB
->OldFileName
[name_len
+ 1] = 0x00; /* pad */
2967 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2968 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2970 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2971 name_len2
*= 2; /* convert to bytes */
2972 } else { /* BB improve the check for buffer overruns BB */
2973 name_len
= strnlen(from_name
, PATH_MAX
);
2974 name_len
++; /* trailing null */
2975 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
2976 name_len2
= strnlen(to_name
, PATH_MAX
);
2977 name_len2
++; /* trailing null */
2978 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2979 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
2980 name_len2
++; /* trailing null */
2981 name_len2
++; /* signature byte */
2984 count
= 1 /* string type byte */ + name_len
+ name_len2
;
2985 inc_rfc1001_len(pSMB
, count
);
2986 pSMB
->ByteCount
= cpu_to_le16(count
);
2988 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2989 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2990 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
2992 cifs_dbg(FYI
, "Send error in hard link (NT rename) = %d\n", rc
);
2994 cifs_buf_release(pSMB
);
2996 goto winCreateHardLinkRetry
;
3002 CIFSSMBUnixQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3003 const unsigned char *searchName
, char **symlinkinfo
,
3004 const struct nls_table
*nls_codepage
)
3006 /* SMB_QUERY_FILE_UNIX_LINK */
3007 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3008 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3012 __u16 params
, byte_count
;
3015 cifs_dbg(FYI
, "In QPathSymLinkInfo (Unix) for path %s\n", searchName
);
3018 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3023 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3025 cifs_strtoUTF16((__le16
*) pSMB
->FileName
, searchName
,
3026 PATH_MAX
, nls_codepage
);
3027 name_len
++; /* trailing null */
3029 } else { /* BB improve the check for buffer overruns BB */
3030 name_len
= strnlen(searchName
, PATH_MAX
);
3031 name_len
++; /* trailing null */
3032 strncpy(pSMB
->FileName
, searchName
, name_len
);
3035 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3036 pSMB
->TotalDataCount
= 0;
3037 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3038 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3039 pSMB
->MaxSetupCount
= 0;
3043 pSMB
->Reserved2
= 0;
3044 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3045 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3046 pSMB
->DataCount
= 0;
3047 pSMB
->DataOffset
= 0;
3048 pSMB
->SetupCount
= 1;
3049 pSMB
->Reserved3
= 0;
3050 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3051 byte_count
= params
+ 1 /* pad */ ;
3052 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3053 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3054 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
3055 pSMB
->Reserved4
= 0;
3056 inc_rfc1001_len(pSMB
, byte_count
);
3057 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3059 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3060 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3062 cifs_dbg(FYI
, "Send error in QuerySymLinkInfo = %d\n", rc
);
3064 /* decode response */
3066 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3067 /* BB also check enough total bytes returned */
3068 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3072 u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3074 data_start
= ((char *) &pSMBr
->hdr
.Protocol
) +
3075 le16_to_cpu(pSMBr
->t2
.DataOffset
);
3077 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3082 /* BB FIXME investigate remapping reserved chars here */
3083 *symlinkinfo
= cifs_strndup_from_utf16(data_start
,
3084 count
, is_unicode
, nls_codepage
);
3089 cifs_buf_release(pSMB
);
3091 goto querySymLinkRetry
;
3095 #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
3097 * Recent Windows versions now create symlinks more frequently
3098 * and they use the "reparse point" mechanism below. We can of course
3099 * do symlinks nicely to Samba and other servers which support the
3100 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3101 * "MF" symlinks optionally, but for recent Windows we really need to
3102 * reenable the code below and fix the cifs_symlink callers to handle this.
3103 * In the interim this code has been moved to its own config option so
3104 * it is not compiled in by default until callers fixed up and more tested.
3107 CIFSSMBQueryReparseLinkInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
3108 const unsigned char *searchName
,
3109 char *symlinkinfo
, const int buflen
, __u16 fid
,
3110 const struct nls_table
*nls_codepage
)
3114 struct smb_com_transaction_ioctl_req
*pSMB
;
3115 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3117 cifs_dbg(FYI
, "In Windows reparse style QueryLink for path %s\n",
3119 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3124 pSMB
->TotalParameterCount
= 0 ;
3125 pSMB
->TotalDataCount
= 0;
3126 pSMB
->MaxParameterCount
= cpu_to_le32(2);
3127 /* BB find exact data count max from sess structure BB */
3128 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3129 pSMB
->MaxSetupCount
= 4;
3131 pSMB
->ParameterOffset
= 0;
3132 pSMB
->DataCount
= 0;
3133 pSMB
->DataOffset
= 0;
3134 pSMB
->SetupCount
= 4;
3135 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3136 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3137 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
3138 pSMB
->IsFsctl
= 1; /* FSCTL */
3139 pSMB
->IsRootFlag
= 0;
3140 pSMB
->Fid
= fid
; /* file handle always le */
3141 pSMB
->ByteCount
= 0;
3143 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3144 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3146 cifs_dbg(FYI
, "Send error in QueryReparseLinkInfo = %d\n", rc
);
3147 } else { /* decode response */
3148 __u32 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3149 __u32 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3150 if (get_bcc(&pSMBr
->hdr
) < 2 || data_offset
> 512) {
3151 /* BB also check enough total bytes returned */
3152 rc
= -EIO
; /* bad smb */
3155 if (data_count
&& (data_count
< 2048)) {
3156 char *end_of_smb
= 2 /* sizeof byte count */ +
3157 get_bcc(&pSMBr
->hdr
) + (char *)&pSMBr
->ByteCount
;
3159 struct reparse_data
*reparse_buf
=
3160 (struct reparse_data
*)
3161 ((char *)&pSMBr
->hdr
.Protocol
3163 if ((char *)reparse_buf
>= end_of_smb
) {
3167 if ((reparse_buf
->LinkNamesBuf
+
3168 reparse_buf
->TargetNameOffset
+
3169 reparse_buf
->TargetNameLen
) > end_of_smb
) {
3170 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3175 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3176 cifs_from_ucs2(symlinkinfo
, (__le16
*)
3177 (reparse_buf
->LinkNamesBuf
+
3178 reparse_buf
->TargetNameOffset
),
3180 reparse_buf
->TargetNameLen
,
3182 } else { /* ASCII names */
3183 strncpy(symlinkinfo
,
3184 reparse_buf
->LinkNamesBuf
+
3185 reparse_buf
->TargetNameOffset
,
3186 min_t(const int, buflen
,
3187 reparse_buf
->TargetNameLen
));
3191 cifs_dbg(FYI
, "Invalid return data count on get reparse info ioctl\n");
3193 symlinkinfo
[buflen
] = 0; /* just in case so the caller
3194 does not go off the end of the buffer */
3195 cifs_dbg(FYI
, "readlink result - %s\n", symlinkinfo
);
3199 cifs_buf_release(pSMB
);
3201 /* Note: On -EAGAIN error only caller can retry on handle based calls
3202 since file handle passed in no longer valid */
3206 #endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
3208 #ifdef CONFIG_CIFS_POSIX
3210 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3211 static void cifs_convert_ace(posix_acl_xattr_entry
*ace
,
3212 struct cifs_posix_ace
*cifs_ace
)
3214 /* u8 cifs fields do not need le conversion */
3215 ace
->e_perm
= cpu_to_le16(cifs_ace
->cifs_e_perm
);
3216 ace
->e_tag
= cpu_to_le16(cifs_ace
->cifs_e_tag
);
3217 ace
->e_id
= cpu_to_le32(le64_to_cpu(cifs_ace
->cifs_uid
));
3219 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3220 ace->e_perm, ace->e_tag, ace->e_id);
3226 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3227 static int cifs_copy_posix_acl(char *trgt
, char *src
, const int buflen
,
3228 const int acl_type
, const int size_of_data_area
)
3233 struct cifs_posix_ace
*pACE
;
3234 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)src
;
3235 posix_acl_xattr_header
*local_acl
= (posix_acl_xattr_header
*)trgt
;
3237 if (le16_to_cpu(cifs_acl
->version
) != CIFS_ACL_VERSION
)
3240 if (acl_type
& ACL_TYPE_ACCESS
) {
3241 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3242 pACE
= &cifs_acl
->ace_array
[0];
3243 size
= sizeof(struct cifs_posix_acl
);
3244 size
+= sizeof(struct cifs_posix_ace
) * count
;
3245 /* check if we would go beyond end of SMB */
3246 if (size_of_data_area
< size
) {
3247 cifs_dbg(FYI
, "bad CIFS POSIX ACL size %d vs. %d\n",
3248 size_of_data_area
, size
);
3251 } else if (acl_type
& ACL_TYPE_DEFAULT
) {
3252 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3253 size
= sizeof(struct cifs_posix_acl
);
3254 size
+= sizeof(struct cifs_posix_ace
) * count
;
3255 /* skip past access ACEs to get to default ACEs */
3256 pACE
= &cifs_acl
->ace_array
[count
];
3257 count
= le16_to_cpu(cifs_acl
->default_entry_count
);
3258 size
+= sizeof(struct cifs_posix_ace
) * count
;
3259 /* check if we would go beyond end of SMB */
3260 if (size_of_data_area
< size
)
3267 size
= posix_acl_xattr_size(count
);
3268 if ((buflen
== 0) || (local_acl
== NULL
)) {
3269 /* used to query ACL EA size */
3270 } else if (size
> buflen
) {
3272 } else /* buffer big enough */ {
3273 local_acl
->a_version
= cpu_to_le32(POSIX_ACL_XATTR_VERSION
);
3274 for (i
= 0; i
< count
; i
++) {
3275 cifs_convert_ace(&local_acl
->a_entries
[i
], pACE
);
3282 static __u16
convert_ace_to_cifs_ace(struct cifs_posix_ace
*cifs_ace
,
3283 const posix_acl_xattr_entry
*local_ace
)
3285 __u16 rc
= 0; /* 0 = ACL converted ok */
3287 cifs_ace
->cifs_e_perm
= le16_to_cpu(local_ace
->e_perm
);
3288 cifs_ace
->cifs_e_tag
= le16_to_cpu(local_ace
->e_tag
);
3289 /* BB is there a better way to handle the large uid? */
3290 if (local_ace
->e_id
== cpu_to_le32(-1)) {
3291 /* Probably no need to le convert -1 on any arch but can not hurt */
3292 cifs_ace
->cifs_uid
= cpu_to_le64(-1);
3294 cifs_ace
->cifs_uid
= cpu_to_le64(le32_to_cpu(local_ace
->e_id
));
3296 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3297 ace->e_perm, ace->e_tag, ace->e_id);
3302 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3303 static __u16
ACL_to_cifs_posix(char *parm_data
, const char *pACL
,
3304 const int buflen
, const int acl_type
)
3307 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)parm_data
;
3308 posix_acl_xattr_header
*local_acl
= (posix_acl_xattr_header
*)pACL
;
3312 if ((buflen
== 0) || (pACL
== NULL
) || (cifs_acl
== NULL
))
3315 count
= posix_acl_xattr_count((size_t)buflen
);
3316 cifs_dbg(FYI
, "setting acl with %d entries from buf of length %d and version of %d\n",
3317 count
, buflen
, le32_to_cpu(local_acl
->a_version
));
3318 if (le32_to_cpu(local_acl
->a_version
) != 2) {
3319 cifs_dbg(FYI
, "unknown POSIX ACL version %d\n",
3320 le32_to_cpu(local_acl
->a_version
));
3323 cifs_acl
->version
= cpu_to_le16(1);
3324 if (acl_type
== ACL_TYPE_ACCESS
) {
3325 cifs_acl
->access_entry_count
= cpu_to_le16(count
);
3326 cifs_acl
->default_entry_count
= __constant_cpu_to_le16(0xFFFF);
3327 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3328 cifs_acl
->default_entry_count
= cpu_to_le16(count
);
3329 cifs_acl
->access_entry_count
= __constant_cpu_to_le16(0xFFFF);
3331 cifs_dbg(FYI
, "unknown ACL type %d\n", acl_type
);
3334 for (i
= 0; i
< count
; i
++) {
3335 rc
= convert_ace_to_cifs_ace(&cifs_acl
->ace_array
[i
],
3336 &local_acl
->a_entries
[i
]);
3338 /* ACE not converted */
3343 rc
= (__u16
)(count
* sizeof(struct cifs_posix_ace
));
3344 rc
+= sizeof(struct cifs_posix_acl
);
3345 /* BB add check to make sure ACL does not overflow SMB */
3351 CIFSSMBGetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3352 const unsigned char *searchName
,
3353 char *acl_inf
, const int buflen
, const int acl_type
,
3354 const struct nls_table
*nls_codepage
, int remap
)
3356 /* SMB_QUERY_POSIX_ACL */
3357 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3358 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3362 __u16 params
, byte_count
;
3364 cifs_dbg(FYI
, "In GetPosixACL (Unix) for path %s\n", searchName
);
3367 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3372 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3374 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3375 searchName
, PATH_MAX
, nls_codepage
,
3377 name_len
++; /* trailing null */
3379 pSMB
->FileName
[name_len
] = 0;
3380 pSMB
->FileName
[name_len
+1] = 0;
3381 } else { /* BB improve the check for buffer overruns BB */
3382 name_len
= strnlen(searchName
, PATH_MAX
);
3383 name_len
++; /* trailing null */
3384 strncpy(pSMB
->FileName
, searchName
, name_len
);
3387 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3388 pSMB
->TotalDataCount
= 0;
3389 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3390 /* BB find exact max data count below from sess structure BB */
3391 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3392 pSMB
->MaxSetupCount
= 0;
3396 pSMB
->Reserved2
= 0;
3397 pSMB
->ParameterOffset
= cpu_to_le16(
3398 offsetof(struct smb_com_transaction2_qpi_req
,
3399 InformationLevel
) - 4);
3400 pSMB
->DataCount
= 0;
3401 pSMB
->DataOffset
= 0;
3402 pSMB
->SetupCount
= 1;
3403 pSMB
->Reserved3
= 0;
3404 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3405 byte_count
= params
+ 1 /* pad */ ;
3406 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3407 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3408 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_ACL
);
3409 pSMB
->Reserved4
= 0;
3410 inc_rfc1001_len(pSMB
, byte_count
);
3411 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3413 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3414 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3415 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3417 cifs_dbg(FYI
, "Send error in Query POSIX ACL = %d\n", rc
);
3419 /* decode response */
3421 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3422 /* BB also check enough total bytes returned */
3423 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3424 rc
= -EIO
; /* bad smb */
3426 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3427 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3428 rc
= cifs_copy_posix_acl(acl_inf
,
3429 (char *)&pSMBr
->hdr
.Protocol
+data_offset
,
3430 buflen
, acl_type
, count
);
3433 cifs_buf_release(pSMB
);
3440 CIFSSMBSetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3441 const unsigned char *fileName
,
3442 const char *local_acl
, const int buflen
,
3444 const struct nls_table
*nls_codepage
, int remap
)
3446 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3447 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3451 int bytes_returned
= 0;
3452 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
3454 cifs_dbg(FYI
, "In SetPosixACL (Unix) for path %s\n", fileName
);
3456 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3460 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3462 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
3463 PATH_MAX
, nls_codepage
, remap
);
3464 name_len
++; /* trailing null */
3466 } else { /* BB improve the check for buffer overruns BB */
3467 name_len
= strnlen(fileName
, PATH_MAX
);
3468 name_len
++; /* trailing null */
3469 strncpy(pSMB
->FileName
, fileName
, name_len
);
3471 params
= 6 + name_len
;
3472 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3473 /* BB find max SMB size from sess */
3474 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3475 pSMB
->MaxSetupCount
= 0;
3479 pSMB
->Reserved2
= 0;
3480 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3481 InformationLevel
) - 4;
3482 offset
= param_offset
+ params
;
3483 parm_data
= ((char *) &pSMB
->hdr
.Protocol
) + offset
;
3484 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3486 /* convert to on the wire format for POSIX ACL */
3487 data_count
= ACL_to_cifs_posix(parm_data
, local_acl
, buflen
, acl_type
);
3489 if (data_count
== 0) {
3491 goto setACLerrorExit
;
3493 pSMB
->DataOffset
= cpu_to_le16(offset
);
3494 pSMB
->SetupCount
= 1;
3495 pSMB
->Reserved3
= 0;
3496 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3497 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_ACL
);
3498 byte_count
= 3 /* pad */ + params
+ data_count
;
3499 pSMB
->DataCount
= cpu_to_le16(data_count
);
3500 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3501 pSMB
->ParameterCount
= cpu_to_le16(params
);
3502 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3503 pSMB
->Reserved4
= 0;
3504 inc_rfc1001_len(pSMB
, byte_count
);
3505 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3506 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3507 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3509 cifs_dbg(FYI
, "Set POSIX ACL returned %d\n", rc
);
3512 cifs_buf_release(pSMB
);
3518 /* BB fix tabs in this function FIXME BB */
3520 CIFSGetExtAttr(const unsigned int xid
, struct cifs_tcon
*tcon
,
3521 const int netfid
, __u64
*pExtAttrBits
, __u64
*pMask
)
3524 struct smb_t2_qfi_req
*pSMB
= NULL
;
3525 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3527 __u16 params
, byte_count
;
3529 cifs_dbg(FYI
, "In GetExtAttr\n");
3534 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3539 params
= 2 /* level */ + 2 /* fid */;
3540 pSMB
->t2
.TotalDataCount
= 0;
3541 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3542 /* BB find exact max data count below from sess structure BB */
3543 pSMB
->t2
.MaxDataCount
= cpu_to_le16(4000);
3544 pSMB
->t2
.MaxSetupCount
= 0;
3545 pSMB
->t2
.Reserved
= 0;
3547 pSMB
->t2
.Timeout
= 0;
3548 pSMB
->t2
.Reserved2
= 0;
3549 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3551 pSMB
->t2
.DataCount
= 0;
3552 pSMB
->t2
.DataOffset
= 0;
3553 pSMB
->t2
.SetupCount
= 1;
3554 pSMB
->t2
.Reserved3
= 0;
3555 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3556 byte_count
= params
+ 1 /* pad */ ;
3557 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3558 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3559 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_ATTR_FLAGS
);
3562 inc_rfc1001_len(pSMB
, byte_count
);
3563 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3565 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3566 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3568 cifs_dbg(FYI
, "error %d in GetExtAttr\n", rc
);
3570 /* decode response */
3571 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3572 /* BB also check enough total bytes returned */
3573 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3574 /* If rc should we check for EOPNOSUPP and
3575 disable the srvino flag? or in caller? */
3576 rc
= -EIO
; /* bad smb */
3578 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3579 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3580 struct file_chattr_info
*pfinfo
;
3581 /* BB Do we need a cast or hash here ? */
3583 cifs_dbg(FYI
, "Illegal size ret in GetExtAttr\n");
3587 pfinfo
= (struct file_chattr_info
*)
3588 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
3589 *pExtAttrBits
= le64_to_cpu(pfinfo
->mode
);
3590 *pMask
= le64_to_cpu(pfinfo
->mask
);
3594 cifs_buf_release(pSMB
);
3596 goto GetExtAttrRetry
;
3600 #endif /* CONFIG_POSIX */
3602 #ifdef CONFIG_CIFS_ACL
3604 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3605 * all NT TRANSACTS that we init here have total parm and data under about 400
3606 * bytes (to fit in small cifs buffer size), which is the case so far, it
3607 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3608 * returned setup area) and MaxParameterCount (returned parms size) must be set
3612 smb_init_nttransact(const __u16 sub_command
, const int setup_count
,
3613 const int parm_len
, struct cifs_tcon
*tcon
,
3618 struct smb_com_ntransact_req
*pSMB
;
3620 rc
= small_smb_init(SMB_COM_NT_TRANSACT
, 19 + setup_count
, tcon
,
3624 *ret_buf
= (void *)pSMB
;
3626 pSMB
->TotalParameterCount
= cpu_to_le32(parm_len
);
3627 pSMB
->TotalDataCount
= 0;
3628 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3629 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3630 pSMB
->DataCount
= pSMB
->TotalDataCount
;
3631 temp_offset
= offsetof(struct smb_com_ntransact_req
, Parms
) +
3632 (setup_count
* 2) - 4 /* for rfc1001 length itself */;
3633 pSMB
->ParameterOffset
= cpu_to_le32(temp_offset
);
3634 pSMB
->DataOffset
= cpu_to_le32(temp_offset
+ parm_len
);
3635 pSMB
->SetupCount
= setup_count
; /* no need to le convert byte fields */
3636 pSMB
->SubCommand
= cpu_to_le16(sub_command
);
3641 validate_ntransact(char *buf
, char **ppparm
, char **ppdata
,
3642 __u32
*pparmlen
, __u32
*pdatalen
)
3645 __u32 data_count
, data_offset
, parm_count
, parm_offset
;
3646 struct smb_com_ntransact_rsp
*pSMBr
;
3655 pSMBr
= (struct smb_com_ntransact_rsp
*)buf
;
3657 bcc
= get_bcc(&pSMBr
->hdr
);
3658 end_of_smb
= 2 /* sizeof byte count */ + bcc
+
3659 (char *)&pSMBr
->ByteCount
;
3661 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3662 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3663 parm_offset
= le32_to_cpu(pSMBr
->ParameterOffset
);
3664 parm_count
= le32_to_cpu(pSMBr
->ParameterCount
);
3666 *ppparm
= (char *)&pSMBr
->hdr
.Protocol
+ parm_offset
;
3667 *ppdata
= (char *)&pSMBr
->hdr
.Protocol
+ data_offset
;
3669 /* should we also check that parm and data areas do not overlap? */
3670 if (*ppparm
> end_of_smb
) {
3671 cifs_dbg(FYI
, "parms start after end of smb\n");
3673 } else if (parm_count
+ *ppparm
> end_of_smb
) {
3674 cifs_dbg(FYI
, "parm end after end of smb\n");
3676 } else if (*ppdata
> end_of_smb
) {
3677 cifs_dbg(FYI
, "data starts after end of smb\n");
3679 } else if (data_count
+ *ppdata
> end_of_smb
) {
3680 cifs_dbg(FYI
, "data %p + count %d (%p) past smb end %p start %p\n",
3681 *ppdata
, data_count
, (data_count
+ *ppdata
),
3684 } else if (parm_count
+ data_count
> bcc
) {
3685 cifs_dbg(FYI
, "parm count and data count larger than SMB\n");
3688 *pdatalen
= data_count
;
3689 *pparmlen
= parm_count
;
3693 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3695 CIFSSMBGetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3696 struct cifs_ntsd
**acl_inf
, __u32
*pbuflen
)
3700 QUERY_SEC_DESC_REQ
*pSMB
;
3703 cifs_dbg(FYI
, "GetCifsACL\n");
3708 rc
= smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC
, 0,
3709 8 /* parm len */, tcon
, (void **) &pSMB
);
3713 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3714 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3715 pSMB
->MaxSetupCount
= 0;
3716 pSMB
->Fid
= fid
; /* file handle always le */
3717 pSMB
->AclFlags
= cpu_to_le32(CIFS_ACL_OWNER
| CIFS_ACL_GROUP
|
3719 pSMB
->ByteCount
= cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3720 inc_rfc1001_len(pSMB
, 11);
3721 iov
[0].iov_base
= (char *)pSMB
;
3722 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
3724 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovec */, &buf_type
,
3726 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3728 cifs_dbg(FYI
, "Send error in QuerySecDesc = %d\n", rc
);
3729 } else { /* decode response */
3733 struct smb_com_ntransact_rsp
*pSMBr
;
3736 /* validate_nttransact */
3737 rc
= validate_ntransact(iov
[0].iov_base
, (char **)&parm
,
3738 &pdata
, &parm_len
, pbuflen
);
3741 pSMBr
= (struct smb_com_ntransact_rsp
*)iov
[0].iov_base
;
3743 cifs_dbg(FYI
, "smb %p parm %p data %p\n",
3744 pSMBr
, parm
, *acl_inf
);
3746 if (le32_to_cpu(pSMBr
->ParameterCount
) != 4) {
3747 rc
= -EIO
; /* bad smb */
3752 /* BB check that data area is minimum length and as big as acl_len */
3754 acl_len
= le32_to_cpu(*parm
);
3755 if (acl_len
!= *pbuflen
) {
3756 cifs_dbg(VFS
, "acl length %d does not match %d\n",
3758 if (*pbuflen
> acl_len
)
3762 /* check if buffer is big enough for the acl
3763 header followed by the smallest SID */
3764 if ((*pbuflen
< sizeof(struct cifs_ntsd
) + 8) ||
3765 (*pbuflen
>= 64 * 1024)) {
3766 cifs_dbg(VFS
, "bad acl length %d\n", *pbuflen
);
3770 *acl_inf
= kmemdup(pdata
, *pbuflen
, GFP_KERNEL
);
3771 if (*acl_inf
== NULL
) {
3778 if (buf_type
== CIFS_SMALL_BUFFER
)
3779 cifs_small_buf_release(iov
[0].iov_base
);
3780 else if (buf_type
== CIFS_LARGE_BUFFER
)
3781 cifs_buf_release(iov
[0].iov_base
);
3782 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3787 CIFSSMBSetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3788 struct cifs_ntsd
*pntsd
, __u32 acllen
, int aclflag
)
3790 __u16 byte_count
, param_count
, data_count
, param_offset
, data_offset
;
3792 int bytes_returned
= 0;
3793 SET_SEC_DESC_REQ
*pSMB
= NULL
;
3797 rc
= smb_init(SMB_COM_NT_TRANSACT
, 19, tcon
, (void **) &pSMB
, &pSMBr
);
3801 pSMB
->MaxSetupCount
= 0;
3805 param_offset
= offsetof(struct smb_com_transaction_ssec_req
, Fid
) - 4;
3806 data_count
= acllen
;
3807 data_offset
= param_offset
+ param_count
;
3808 byte_count
= 3 /* pad */ + param_count
;
3810 pSMB
->DataCount
= cpu_to_le32(data_count
);
3811 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3812 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3813 pSMB
->MaxDataCount
= cpu_to_le32(16384);
3814 pSMB
->ParameterCount
= cpu_to_le32(param_count
);
3815 pSMB
->ParameterOffset
= cpu_to_le32(param_offset
);
3816 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3817 pSMB
->DataOffset
= cpu_to_le32(data_offset
);
3818 pSMB
->SetupCount
= 0;
3819 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC
);
3820 pSMB
->ByteCount
= cpu_to_le16(byte_count
+data_count
);
3822 pSMB
->Fid
= fid
; /* file handle always le */
3823 pSMB
->Reserved2
= 0;
3824 pSMB
->AclFlags
= cpu_to_le32(aclflag
);
3826 if (pntsd
&& acllen
) {
3827 memcpy((char *)pSMBr
+ offsetof(struct smb_hdr
, Protocol
) +
3828 data_offset
, pntsd
, acllen
);
3829 inc_rfc1001_len(pSMB
, byte_count
+ data_count
);
3831 inc_rfc1001_len(pSMB
, byte_count
);
3833 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3834 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3836 cifs_dbg(FYI
, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3837 bytes_returned
, rc
);
3839 cifs_dbg(FYI
, "Set CIFS ACL returned %d\n", rc
);
3840 cifs_buf_release(pSMB
);
3843 goto setCifsAclRetry
;
3848 #endif /* CONFIG_CIFS_ACL */
3850 /* Legacy Query Path Information call for lookup to old servers such
3853 SMBQueryInformation(const unsigned int xid
, struct cifs_tcon
*tcon
,
3854 const char *search_name
, FILE_ALL_INFO
*data
,
3855 const struct nls_table
*nls_codepage
, int remap
)
3857 QUERY_INFORMATION_REQ
*pSMB
;
3858 QUERY_INFORMATION_RSP
*pSMBr
;
3863 cifs_dbg(FYI
, "In SMBQPath path %s\n", search_name
);
3865 rc
= smb_init(SMB_COM_QUERY_INFORMATION
, 0, tcon
, (void **) &pSMB
,
3870 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3872 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3873 search_name
, PATH_MAX
, nls_codepage
,
3875 name_len
++; /* trailing null */
3878 name_len
= strnlen(search_name
, PATH_MAX
);
3879 name_len
++; /* trailing null */
3880 strncpy(pSMB
->FileName
, search_name
, name_len
);
3882 pSMB
->BufferFormat
= 0x04;
3883 name_len
++; /* account for buffer type byte */
3884 inc_rfc1001_len(pSMB
, (__u16
)name_len
);
3885 pSMB
->ByteCount
= cpu_to_le16(name_len
);
3887 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3888 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3890 cifs_dbg(FYI
, "Send error in QueryInfo = %d\n", rc
);
3893 __u32 time
= le32_to_cpu(pSMBr
->last_write_time
);
3895 /* decode response */
3896 /* BB FIXME - add time zone adjustment BB */
3897 memset(data
, 0, sizeof(FILE_ALL_INFO
));
3900 /* decode time fields */
3901 data
->ChangeTime
= cpu_to_le64(cifs_UnixTimeToNT(ts
));
3902 data
->LastWriteTime
= data
->ChangeTime
;
3903 data
->LastAccessTime
= 0;
3904 data
->AllocationSize
=
3905 cpu_to_le64(le32_to_cpu(pSMBr
->size
));
3906 data
->EndOfFile
= data
->AllocationSize
;
3908 cpu_to_le32(le16_to_cpu(pSMBr
->attr
));
3910 rc
= -EIO
; /* bad buffer passed in */
3912 cifs_buf_release(pSMB
);
3921 CIFSSMBQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
3922 u16 netfid
, FILE_ALL_INFO
*pFindData
)
3924 struct smb_t2_qfi_req
*pSMB
= NULL
;
3925 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3928 __u16 params
, byte_count
;
3931 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3936 params
= 2 /* level */ + 2 /* fid */;
3937 pSMB
->t2
.TotalDataCount
= 0;
3938 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3939 /* BB find exact max data count below from sess structure BB */
3940 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3941 pSMB
->t2
.MaxSetupCount
= 0;
3942 pSMB
->t2
.Reserved
= 0;
3944 pSMB
->t2
.Timeout
= 0;
3945 pSMB
->t2
.Reserved2
= 0;
3946 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3948 pSMB
->t2
.DataCount
= 0;
3949 pSMB
->t2
.DataOffset
= 0;
3950 pSMB
->t2
.SetupCount
= 1;
3951 pSMB
->t2
.Reserved3
= 0;
3952 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3953 byte_count
= params
+ 1 /* pad */ ;
3954 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3955 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3956 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
3959 inc_rfc1001_len(pSMB
, byte_count
);
3961 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3962 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3964 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
3965 } else { /* decode response */
3966 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3968 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
3970 else if (get_bcc(&pSMBr
->hdr
) < 40)
3971 rc
= -EIO
; /* bad smb */
3972 else if (pFindData
) {
3973 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3974 memcpy((char *) pFindData
,
3975 (char *) &pSMBr
->hdr
.Protocol
+
3976 data_offset
, sizeof(FILE_ALL_INFO
));
3980 cifs_buf_release(pSMB
);
3982 goto QFileInfoRetry
;
3988 CIFSSMBQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
3989 const char *search_name
, FILE_ALL_INFO
*data
,
3990 int legacy
/* old style infolevel */,
3991 const struct nls_table
*nls_codepage
, int remap
)
3993 /* level 263 SMB_QUERY_FILE_ALL_INFO */
3994 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3995 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3999 __u16 params
, byte_count
;
4001 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4003 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4008 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4010 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, search_name
,
4011 PATH_MAX
, nls_codepage
, remap
);
4012 name_len
++; /* trailing null */
4014 } else { /* BB improve the check for buffer overruns BB */
4015 name_len
= strnlen(search_name
, PATH_MAX
);
4016 name_len
++; /* trailing null */
4017 strncpy(pSMB
->FileName
, search_name
, name_len
);
4020 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4021 pSMB
->TotalDataCount
= 0;
4022 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4023 /* BB find exact max SMB PDU from sess structure BB */
4024 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4025 pSMB
->MaxSetupCount
= 0;
4029 pSMB
->Reserved2
= 0;
4030 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4031 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4032 pSMB
->DataCount
= 0;
4033 pSMB
->DataOffset
= 0;
4034 pSMB
->SetupCount
= 1;
4035 pSMB
->Reserved3
= 0;
4036 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4037 byte_count
= params
+ 1 /* pad */ ;
4038 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4039 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4041 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
4043 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4044 pSMB
->Reserved4
= 0;
4045 inc_rfc1001_len(pSMB
, byte_count
);
4046 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4048 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4049 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4051 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4052 } else { /* decode response */
4053 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4055 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4057 else if (!legacy
&& get_bcc(&pSMBr
->hdr
) < 40)
4058 rc
= -EIO
; /* bad smb */
4059 else if (legacy
&& get_bcc(&pSMBr
->hdr
) < 24)
4060 rc
= -EIO
; /* 24 or 26 expected but we do not read
4064 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4067 * On legacy responses we do not read the last field,
4068 * EAsize, fortunately since it varies by subdialect and
4069 * also note it differs on Set vs Get, ie two bytes or 4
4070 * bytes depending but we don't care here.
4073 size
= sizeof(FILE_INFO_STANDARD
);
4075 size
= sizeof(FILE_ALL_INFO
);
4076 memcpy((char *) data
, (char *) &pSMBr
->hdr
.Protocol
+
4081 cifs_buf_release(pSMB
);
4083 goto QPathInfoRetry
;
4089 CIFSSMBUnixQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4090 u16 netfid
, FILE_UNIX_BASIC_INFO
*pFindData
)
4092 struct smb_t2_qfi_req
*pSMB
= NULL
;
4093 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4096 __u16 params
, byte_count
;
4099 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4104 params
= 2 /* level */ + 2 /* fid */;
4105 pSMB
->t2
.TotalDataCount
= 0;
4106 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4107 /* BB find exact max data count below from sess structure BB */
4108 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4109 pSMB
->t2
.MaxSetupCount
= 0;
4110 pSMB
->t2
.Reserved
= 0;
4112 pSMB
->t2
.Timeout
= 0;
4113 pSMB
->t2
.Reserved2
= 0;
4114 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4116 pSMB
->t2
.DataCount
= 0;
4117 pSMB
->t2
.DataOffset
= 0;
4118 pSMB
->t2
.SetupCount
= 1;
4119 pSMB
->t2
.Reserved3
= 0;
4120 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4121 byte_count
= params
+ 1 /* pad */ ;
4122 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4123 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4124 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4127 inc_rfc1001_len(pSMB
, byte_count
);
4129 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4130 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4132 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4133 } else { /* decode response */
4134 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4136 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4137 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4138 rc
= -EIO
; /* bad smb */
4140 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4141 memcpy((char *) pFindData
,
4142 (char *) &pSMBr
->hdr
.Protocol
+
4144 sizeof(FILE_UNIX_BASIC_INFO
));
4148 cifs_buf_release(pSMB
);
4150 goto UnixQFileInfoRetry
;
4156 CIFSSMBUnixQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4157 const unsigned char *searchName
,
4158 FILE_UNIX_BASIC_INFO
*pFindData
,
4159 const struct nls_table
*nls_codepage
, int remap
)
4161 /* SMB_QUERY_FILE_UNIX_BASIC */
4162 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4163 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4165 int bytes_returned
= 0;
4167 __u16 params
, byte_count
;
4169 cifs_dbg(FYI
, "In QPathInfo (Unix) the path %s\n", searchName
);
4171 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4176 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4178 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4179 PATH_MAX
, nls_codepage
, remap
);
4180 name_len
++; /* trailing null */
4182 } else { /* BB improve the check for buffer overruns BB */
4183 name_len
= strnlen(searchName
, PATH_MAX
);
4184 name_len
++; /* trailing null */
4185 strncpy(pSMB
->FileName
, searchName
, name_len
);
4188 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4189 pSMB
->TotalDataCount
= 0;
4190 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4191 /* BB find exact max SMB PDU from sess structure BB */
4192 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4193 pSMB
->MaxSetupCount
= 0;
4197 pSMB
->Reserved2
= 0;
4198 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4199 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4200 pSMB
->DataCount
= 0;
4201 pSMB
->DataOffset
= 0;
4202 pSMB
->SetupCount
= 1;
4203 pSMB
->Reserved3
= 0;
4204 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4205 byte_count
= params
+ 1 /* pad */ ;
4206 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4207 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4208 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4209 pSMB
->Reserved4
= 0;
4210 inc_rfc1001_len(pSMB
, byte_count
);
4211 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4213 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4214 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4216 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4217 } else { /* decode response */
4218 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4220 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4221 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4222 rc
= -EIO
; /* bad smb */
4224 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4225 memcpy((char *) pFindData
,
4226 (char *) &pSMBr
->hdr
.Protocol
+
4228 sizeof(FILE_UNIX_BASIC_INFO
));
4231 cifs_buf_release(pSMB
);
4233 goto UnixQPathInfoRetry
;
4238 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4240 CIFSFindFirst(const unsigned int xid
, struct cifs_tcon
*tcon
,
4241 const char *searchName
, struct cifs_sb_info
*cifs_sb
,
4242 __u16
*pnetfid
, __u16 search_flags
,
4243 struct cifs_search_info
*psrch_inf
, bool msearch
)
4245 /* level 257 SMB_ */
4246 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
4247 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
4248 T2_FFIRST_RSP_PARMS
*parms
;
4250 int bytes_returned
= 0;
4251 int name_len
, remap
;
4252 __u16 params
, byte_count
;
4253 struct nls_table
*nls_codepage
;
4255 cifs_dbg(FYI
, "In FindFirst for %s\n", searchName
);
4258 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4263 nls_codepage
= cifs_sb
->local_nls
;
4264 remap
= cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
;
4266 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4268 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4269 PATH_MAX
, nls_codepage
, remap
);
4270 /* We can not add the asterik earlier in case
4271 it got remapped to 0xF03A as if it were part of the
4272 directory name instead of a wildcard */
4275 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4276 pSMB
->FileName
[name_len
+1] = 0;
4277 pSMB
->FileName
[name_len
+2] = '*';
4278 pSMB
->FileName
[name_len
+3] = 0;
4279 name_len
+= 4; /* now the trailing null */
4280 /* null terminate just in case */
4281 pSMB
->FileName
[name_len
] = 0;
4282 pSMB
->FileName
[name_len
+1] = 0;
4285 } else { /* BB add check for overrun of SMB buf BB */
4286 name_len
= strnlen(searchName
, PATH_MAX
);
4287 /* BB fix here and in unicode clause above ie
4288 if (name_len > buffersize-header)
4289 free buffer exit; BB */
4290 strncpy(pSMB
->FileName
, searchName
, name_len
);
4292 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4293 pSMB
->FileName
[name_len
+1] = '*';
4294 pSMB
->FileName
[name_len
+2] = 0;
4299 params
= 12 + name_len
/* includes null */ ;
4300 pSMB
->TotalDataCount
= 0; /* no EAs */
4301 pSMB
->MaxParameterCount
= cpu_to_le16(10);
4302 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4303 pSMB
->MaxSetupCount
= 0;
4307 pSMB
->Reserved2
= 0;
4308 byte_count
= params
+ 1 /* pad */ ;
4309 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4310 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4311 pSMB
->ParameterOffset
= cpu_to_le16(
4312 offsetof(struct smb_com_transaction2_ffirst_req
, SearchAttributes
)
4314 pSMB
->DataCount
= 0;
4315 pSMB
->DataOffset
= 0;
4316 pSMB
->SetupCount
= 1; /* one byte, no need to make endian neutral */
4317 pSMB
->Reserved3
= 0;
4318 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
4319 pSMB
->SearchAttributes
=
4320 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
4322 pSMB
->SearchCount
= cpu_to_le16(CIFSMaxBufSize
/sizeof(FILE_UNIX_INFO
));
4323 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4324 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4326 /* BB what should we set StorageType to? Does it matter? BB */
4327 pSMB
->SearchStorageType
= 0;
4328 inc_rfc1001_len(pSMB
, byte_count
);
4329 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4331 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4332 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4333 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_ffirst
);
4335 if (rc
) {/* BB add logic to retry regular search if Unix search
4336 rejected unexpectedly by server */
4337 /* BB Add code to handle unsupported level rc */
4338 cifs_dbg(FYI
, "Error in FindFirst = %d\n", rc
);
4340 cifs_buf_release(pSMB
);
4342 /* BB eventually could optimize out free and realloc of buf */
4345 goto findFirstRetry
;
4346 } else { /* decode response */
4347 /* BB remember to free buffer if error BB */
4348 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4352 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4353 psrch_inf
->unicode
= true;
4355 psrch_inf
->unicode
= false;
4357 psrch_inf
->ntwrk_buf_start
= (char *)pSMBr
;
4358 psrch_inf
->smallBuf
= 0;
4359 psrch_inf
->srch_entries_start
=
4360 (char *) &pSMBr
->hdr
.Protocol
+
4361 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4362 parms
= (T2_FFIRST_RSP_PARMS
*)((char *) &pSMBr
->hdr
.Protocol
+
4363 le16_to_cpu(pSMBr
->t2
.ParameterOffset
));
4365 if (parms
->EndofSearch
)
4366 psrch_inf
->endOfSearch
= true;
4368 psrch_inf
->endOfSearch
= false;
4370 psrch_inf
->entries_in_buffer
=
4371 le16_to_cpu(parms
->SearchCount
);
4372 psrch_inf
->index_of_last_entry
= 2 /* skip . and .. */ +
4373 psrch_inf
->entries_in_buffer
;
4374 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4375 if (CIFSMaxBufSize
< lnoff
) {
4376 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4377 psrch_inf
->last_entry
= NULL
;
4381 psrch_inf
->last_entry
= psrch_inf
->srch_entries_start
+
4385 *pnetfid
= parms
->SearchHandle
;
4387 cifs_buf_release(pSMB
);
4394 int CIFSFindNext(const unsigned int xid
, struct cifs_tcon
*tcon
,
4395 __u16 searchHandle
, __u16 search_flags
,
4396 struct cifs_search_info
*psrch_inf
)
4398 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
4399 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
4400 T2_FNEXT_RSP_PARMS
*parms
;
4401 char *response_data
;
4404 unsigned int name_len
;
4405 __u16 params
, byte_count
;
4407 cifs_dbg(FYI
, "In FindNext\n");
4409 if (psrch_inf
->endOfSearch
)
4412 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4417 params
= 14; /* includes 2 bytes of null string, converted to LE below*/
4419 pSMB
->TotalDataCount
= 0; /* no EAs */
4420 pSMB
->MaxParameterCount
= cpu_to_le16(8);
4421 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4422 pSMB
->MaxSetupCount
= 0;
4426 pSMB
->Reserved2
= 0;
4427 pSMB
->ParameterOffset
= cpu_to_le16(
4428 offsetof(struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
4429 pSMB
->DataCount
= 0;
4430 pSMB
->DataOffset
= 0;
4431 pSMB
->SetupCount
= 1;
4432 pSMB
->Reserved3
= 0;
4433 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
4434 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
4436 cpu_to_le16(CIFSMaxBufSize
/ sizeof(FILE_UNIX_INFO
));
4437 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4438 pSMB
->ResumeKey
= psrch_inf
->resume_key
;
4439 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4441 name_len
= psrch_inf
->resume_name_len
;
4443 if (name_len
< PATH_MAX
) {
4444 memcpy(pSMB
->ResumeFileName
, psrch_inf
->presume_name
, name_len
);
4445 byte_count
+= name_len
;
4446 /* 14 byte parm len above enough for 2 byte null terminator */
4447 pSMB
->ResumeFileName
[name_len
] = 0;
4448 pSMB
->ResumeFileName
[name_len
+1] = 0;
4451 goto FNext2_err_exit
;
4453 byte_count
= params
+ 1 /* pad */ ;
4454 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4455 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4456 inc_rfc1001_len(pSMB
, byte_count
);
4457 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4459 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4460 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4461 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fnext
);
4464 psrch_inf
->endOfSearch
= true;
4465 cifs_buf_release(pSMB
);
4466 rc
= 0; /* search probably was closed at end of search*/
4468 cifs_dbg(FYI
, "FindNext returned = %d\n", rc
);
4469 } else { /* decode response */
4470 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4475 /* BB fixme add lock for file (srch_info) struct here */
4476 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4477 psrch_inf
->unicode
= true;
4479 psrch_inf
->unicode
= false;
4480 response_data
= (char *) &pSMBr
->hdr
.Protocol
+
4481 le16_to_cpu(pSMBr
->t2
.ParameterOffset
);
4482 parms
= (T2_FNEXT_RSP_PARMS
*)response_data
;
4483 response_data
= (char *)&pSMBr
->hdr
.Protocol
+
4484 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4485 if (psrch_inf
->smallBuf
)
4486 cifs_small_buf_release(
4487 psrch_inf
->ntwrk_buf_start
);
4489 cifs_buf_release(psrch_inf
->ntwrk_buf_start
);
4490 psrch_inf
->srch_entries_start
= response_data
;
4491 psrch_inf
->ntwrk_buf_start
= (char *)pSMB
;
4492 psrch_inf
->smallBuf
= 0;
4493 if (parms
->EndofSearch
)
4494 psrch_inf
->endOfSearch
= true;
4496 psrch_inf
->endOfSearch
= false;
4497 psrch_inf
->entries_in_buffer
=
4498 le16_to_cpu(parms
->SearchCount
);
4499 psrch_inf
->index_of_last_entry
+=
4500 psrch_inf
->entries_in_buffer
;
4501 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4502 if (CIFSMaxBufSize
< lnoff
) {
4503 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4504 psrch_inf
->last_entry
= NULL
;
4507 psrch_inf
->last_entry
=
4508 psrch_inf
->srch_entries_start
+ lnoff
;
4510 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4511 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4513 /* BB fixme add unlock here */
4518 /* BB On error, should we leave previous search buf (and count and
4519 last entry fields) intact or free the previous one? */
4521 /* Note: On -EAGAIN error only caller can retry on handle based calls
4522 since file handle passed in no longer valid */
4525 cifs_buf_release(pSMB
);
4530 CIFSFindClose(const unsigned int xid
, struct cifs_tcon
*tcon
,
4531 const __u16 searchHandle
)
4534 FINDCLOSE_REQ
*pSMB
= NULL
;
4536 cifs_dbg(FYI
, "In CIFSSMBFindClose\n");
4537 rc
= small_smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **)&pSMB
);
4539 /* no sense returning error if session restarted
4540 as file handle has been closed */
4546 pSMB
->FileID
= searchHandle
;
4547 pSMB
->ByteCount
= 0;
4548 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
4550 cifs_dbg(VFS
, "Send error in FindClose = %d\n", rc
);
4552 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fclose
);
4554 /* Since session is dead, search handle closed on server already */
4562 CIFSGetSrvInodeNumber(const unsigned int xid
, struct cifs_tcon
*tcon
,
4563 const char *search_name
, __u64
*inode_number
,
4564 const struct nls_table
*nls_codepage
, int remap
)
4567 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4568 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4569 int name_len
, bytes_returned
;
4570 __u16 params
, byte_count
;
4572 cifs_dbg(FYI
, "In GetSrvInodeNum for %s\n", search_name
);
4576 GetInodeNumberRetry
:
4577 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4582 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4584 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4585 search_name
, PATH_MAX
, nls_codepage
,
4587 name_len
++; /* trailing null */
4589 } else { /* BB improve the check for buffer overruns BB */
4590 name_len
= strnlen(search_name
, PATH_MAX
);
4591 name_len
++; /* trailing null */
4592 strncpy(pSMB
->FileName
, search_name
, name_len
);
4595 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
4596 pSMB
->TotalDataCount
= 0;
4597 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4598 /* BB find exact max data count below from sess structure BB */
4599 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4600 pSMB
->MaxSetupCount
= 0;
4604 pSMB
->Reserved2
= 0;
4605 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4606 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4607 pSMB
->DataCount
= 0;
4608 pSMB
->DataOffset
= 0;
4609 pSMB
->SetupCount
= 1;
4610 pSMB
->Reserved3
= 0;
4611 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4612 byte_count
= params
+ 1 /* pad */ ;
4613 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4614 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4615 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO
);
4616 pSMB
->Reserved4
= 0;
4617 inc_rfc1001_len(pSMB
, byte_count
);
4618 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4620 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4621 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4623 cifs_dbg(FYI
, "error %d in QueryInternalInfo\n", rc
);
4625 /* decode response */
4626 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4627 /* BB also check enough total bytes returned */
4628 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
4629 /* If rc should we check for EOPNOSUPP and
4630 disable the srvino flag? or in caller? */
4631 rc
= -EIO
; /* bad smb */
4633 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4634 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
4635 struct file_internal_info
*pfinfo
;
4636 /* BB Do we need a cast or hash here ? */
4638 cifs_dbg(FYI
, "Illegal size ret in QryIntrnlInf\n");
4640 goto GetInodeNumOut
;
4642 pfinfo
= (struct file_internal_info
*)
4643 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
4644 *inode_number
= le64_to_cpu(pfinfo
->UniqueId
);
4648 cifs_buf_release(pSMB
);
4650 goto GetInodeNumberRetry
;
4654 /* parses DFS refferal V3 structure
4655 * caller is responsible for freeing target_nodes
4658 * on failure - errno
4661 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
,
4662 unsigned int *num_of_nodes
,
4663 struct dfs_info3_param
**target_nodes
,
4664 const struct nls_table
*nls_codepage
, int remap
,
4665 const char *searchName
)
4670 struct dfs_referral_level_3
*ref
;
4672 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4676 *num_of_nodes
= le16_to_cpu(pSMBr
->NumberOfReferrals
);
4678 if (*num_of_nodes
< 1) {
4679 cifs_dbg(VFS
, "num_referrals: must be at least > 0, but we get num_referrals = %d\n",
4682 goto parse_DFS_referrals_exit
;
4685 ref
= (struct dfs_referral_level_3
*) &(pSMBr
->referrals
);
4686 if (ref
->VersionNumber
!= cpu_to_le16(3)) {
4687 cifs_dbg(VFS
, "Referrals of V%d version are not supported, should be V3\n",
4688 le16_to_cpu(ref
->VersionNumber
));
4690 goto parse_DFS_referrals_exit
;
4693 /* get the upper boundary of the resp buffer */
4694 data_end
= (char *)(&(pSMBr
->PathConsumed
)) +
4695 le16_to_cpu(pSMBr
->t2
.DataCount
);
4697 cifs_dbg(FYI
, "num_referrals: %d dfs flags: 0x%x ...\n",
4698 *num_of_nodes
, le32_to_cpu(pSMBr
->DFSFlags
));
4700 *target_nodes
= kcalloc(*num_of_nodes
, sizeof(struct dfs_info3_param
),
4702 if (*target_nodes
== NULL
) {
4704 goto parse_DFS_referrals_exit
;
4707 /* collect necessary data from referrals */
4708 for (i
= 0; i
< *num_of_nodes
; i
++) {
4711 struct dfs_info3_param
*node
= (*target_nodes
)+i
;
4713 node
->flags
= le32_to_cpu(pSMBr
->DFSFlags
);
4715 __le16
*tmp
= kmalloc(strlen(searchName
)*2 + 2,
4719 goto parse_DFS_referrals_exit
;
4721 cifsConvertToUTF16((__le16
*) tmp
, searchName
,
4722 PATH_MAX
, nls_codepage
, remap
);
4723 node
->path_consumed
= cifs_utf16_bytes(tmp
,
4724 le16_to_cpu(pSMBr
->PathConsumed
),
4728 node
->path_consumed
= le16_to_cpu(pSMBr
->PathConsumed
);
4730 node
->server_type
= le16_to_cpu(ref
->ServerType
);
4731 node
->ref_flag
= le16_to_cpu(ref
->ReferralEntryFlags
);
4734 temp
= (char *)ref
+ le16_to_cpu(ref
->DfsPathOffset
);
4735 max_len
= data_end
- temp
;
4736 node
->path_name
= cifs_strndup_from_utf16(temp
, max_len
,
4737 is_unicode
, nls_codepage
);
4738 if (!node
->path_name
) {
4740 goto parse_DFS_referrals_exit
;
4743 /* copy link target UNC */
4744 temp
= (char *)ref
+ le16_to_cpu(ref
->NetworkAddressOffset
);
4745 max_len
= data_end
- temp
;
4746 node
->node_name
= cifs_strndup_from_utf16(temp
, max_len
,
4747 is_unicode
, nls_codepage
);
4748 if (!node
->node_name
) {
4750 goto parse_DFS_referrals_exit
;
4756 parse_DFS_referrals_exit
:
4758 free_dfs_info_array(*target_nodes
, *num_of_nodes
);
4759 *target_nodes
= NULL
;
4766 CIFSGetDFSRefer(const unsigned int xid
, struct cifs_ses
*ses
,
4767 const char *search_name
, struct dfs_info3_param
**target_nodes
,
4768 unsigned int *num_of_nodes
,
4769 const struct nls_table
*nls_codepage
, int remap
)
4771 /* TRANS2_GET_DFS_REFERRAL */
4772 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
4773 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
4777 __u16 params
, byte_count
;
4779 *target_nodes
= NULL
;
4781 cifs_dbg(FYI
, "In GetDFSRefer the path %s\n", search_name
);
4785 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, NULL
, (void **) &pSMB
,
4790 /* server pointer checked in called function,
4791 but should never be null here anyway */
4792 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
4793 pSMB
->hdr
.Tid
= ses
->ipc_tid
;
4794 pSMB
->hdr
.Uid
= ses
->Suid
;
4795 if (ses
->capabilities
& CAP_STATUS32
)
4796 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
4797 if (ses
->capabilities
& CAP_DFS
)
4798 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
4800 if (ses
->capabilities
& CAP_UNICODE
) {
4801 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
4803 cifsConvertToUTF16((__le16
*) pSMB
->RequestFileName
,
4804 search_name
, PATH_MAX
, nls_codepage
,
4806 name_len
++; /* trailing null */
4808 } else { /* BB improve the check for buffer overruns BB */
4809 name_len
= strnlen(search_name
, PATH_MAX
);
4810 name_len
++; /* trailing null */
4811 strncpy(pSMB
->RequestFileName
, search_name
, name_len
);
4815 if (ses
->server
->sec_mode
&
4816 (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
))
4817 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
4820 pSMB
->hdr
.Uid
= ses
->Suid
;
4822 params
= 2 /* level */ + name_len
/*includes null */ ;
4823 pSMB
->TotalDataCount
= 0;
4824 pSMB
->DataCount
= 0;
4825 pSMB
->DataOffset
= 0;
4826 pSMB
->MaxParameterCount
= 0;
4827 /* BB find exact max SMB PDU from sess structure BB */
4828 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4829 pSMB
->MaxSetupCount
= 0;
4833 pSMB
->Reserved2
= 0;
4834 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4835 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
4836 pSMB
->SetupCount
= 1;
4837 pSMB
->Reserved3
= 0;
4838 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
4839 byte_count
= params
+ 3 /* pad */ ;
4840 pSMB
->ParameterCount
= cpu_to_le16(params
);
4841 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4842 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
4843 inc_rfc1001_len(pSMB
, byte_count
);
4844 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4846 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
4847 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4849 cifs_dbg(FYI
, "Send error in GetDFSRefer = %d\n", rc
);
4852 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4854 /* BB Also check if enough total bytes returned? */
4855 if (rc
|| get_bcc(&pSMBr
->hdr
) < 17) {
4856 rc
= -EIO
; /* bad smb */
4860 cifs_dbg(FYI
, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4861 get_bcc(&pSMBr
->hdr
), le16_to_cpu(pSMBr
->t2
.DataOffset
));
4863 /* parse returned result into more usable form */
4864 rc
= parse_DFS_referrals(pSMBr
, num_of_nodes
,
4865 target_nodes
, nls_codepage
, remap
,
4869 cifs_buf_release(pSMB
);
4877 /* Query File System Info such as free space to old servers such as Win 9x */
4879 SMBOldQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4880 struct kstatfs
*FSData
)
4882 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4883 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4884 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4885 FILE_SYSTEM_ALLOC_INFO
*response_data
;
4887 int bytes_returned
= 0;
4888 __u16 params
, byte_count
;
4890 cifs_dbg(FYI
, "OldQFSInfo\n");
4892 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4897 params
= 2; /* level */
4898 pSMB
->TotalDataCount
= 0;
4899 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4900 pSMB
->MaxDataCount
= cpu_to_le16(1000);
4901 pSMB
->MaxSetupCount
= 0;
4905 pSMB
->Reserved2
= 0;
4906 byte_count
= params
+ 1 /* pad */ ;
4907 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4908 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4909 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4910 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
4911 pSMB
->DataCount
= 0;
4912 pSMB
->DataOffset
= 0;
4913 pSMB
->SetupCount
= 1;
4914 pSMB
->Reserved3
= 0;
4915 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
4916 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_ALLOCATION
);
4917 inc_rfc1001_len(pSMB
, byte_count
);
4918 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4920 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4921 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4923 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
4924 } else { /* decode response */
4925 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4927 if (rc
|| get_bcc(&pSMBr
->hdr
) < 18)
4928 rc
= -EIO
; /* bad smb */
4930 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4931 cifs_dbg(FYI
, "qfsinf resp BCC: %d Offset %d\n",
4932 get_bcc(&pSMBr
->hdr
), data_offset
);
4934 response_data
= (FILE_SYSTEM_ALLOC_INFO
*)
4935 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
4937 le16_to_cpu(response_data
->BytesPerSector
) *
4938 le32_to_cpu(response_data
->
4939 SectorsPerAllocationUnit
);
4941 le32_to_cpu(response_data
->TotalAllocationUnits
);
4942 FSData
->f_bfree
= FSData
->f_bavail
=
4943 le32_to_cpu(response_data
->FreeAllocationUnits
);
4944 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
4945 (unsigned long long)FSData
->f_blocks
,
4946 (unsigned long long)FSData
->f_bfree
,
4950 cifs_buf_release(pSMB
);
4953 goto oldQFSInfoRetry
;
4959 CIFSSMBQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4960 struct kstatfs
*FSData
)
4962 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4963 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4964 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4965 FILE_SYSTEM_INFO
*response_data
;
4967 int bytes_returned
= 0;
4968 __u16 params
, byte_count
;
4970 cifs_dbg(FYI
, "In QFSInfo\n");
4972 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4977 params
= 2; /* level */
4978 pSMB
->TotalDataCount
= 0;
4979 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4980 pSMB
->MaxDataCount
= cpu_to_le16(1000);
4981 pSMB
->MaxSetupCount
= 0;
4985 pSMB
->Reserved2
= 0;
4986 byte_count
= params
+ 1 /* pad */ ;
4987 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4988 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4989 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4990 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
4991 pSMB
->DataCount
= 0;
4992 pSMB
->DataOffset
= 0;
4993 pSMB
->SetupCount
= 1;
4994 pSMB
->Reserved3
= 0;
4995 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
4996 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
4997 inc_rfc1001_len(pSMB
, byte_count
);
4998 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5000 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5001 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5003 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5004 } else { /* decode response */
5005 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5007 if (rc
|| get_bcc(&pSMBr
->hdr
) < 24)
5008 rc
= -EIO
; /* bad smb */
5010 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5014 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5017 le32_to_cpu(response_data
->BytesPerSector
) *
5018 le32_to_cpu(response_data
->
5019 SectorsPerAllocationUnit
);
5021 le64_to_cpu(response_data
->TotalAllocationUnits
);
5022 FSData
->f_bfree
= FSData
->f_bavail
=
5023 le64_to_cpu(response_data
->FreeAllocationUnits
);
5024 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5025 (unsigned long long)FSData
->f_blocks
,
5026 (unsigned long long)FSData
->f_bfree
,
5030 cifs_buf_release(pSMB
);
5039 CIFSSMBQFSAttributeInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5041 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5042 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5043 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5044 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
5046 int bytes_returned
= 0;
5047 __u16 params
, byte_count
;
5049 cifs_dbg(FYI
, "In QFSAttributeInfo\n");
5051 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5056 params
= 2; /* level */
5057 pSMB
->TotalDataCount
= 0;
5058 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5059 /* BB find exact max SMB PDU from sess structure BB */
5060 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5061 pSMB
->MaxSetupCount
= 0;
5065 pSMB
->Reserved2
= 0;
5066 byte_count
= params
+ 1 /* pad */ ;
5067 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5068 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5069 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5070 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5071 pSMB
->DataCount
= 0;
5072 pSMB
->DataOffset
= 0;
5073 pSMB
->SetupCount
= 1;
5074 pSMB
->Reserved3
= 0;
5075 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5076 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
5077 inc_rfc1001_len(pSMB
, byte_count
);
5078 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5080 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5081 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5083 cifs_dbg(VFS
, "Send error in QFSAttributeInfo = %d\n", rc
);
5084 } else { /* decode response */
5085 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5087 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5088 /* BB also check if enough bytes returned */
5089 rc
= -EIO
; /* bad smb */
5091 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5093 (FILE_SYSTEM_ATTRIBUTE_INFO
5094 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5096 memcpy(&tcon
->fsAttrInfo
, response_data
,
5097 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO
));
5100 cifs_buf_release(pSMB
);
5103 goto QFSAttributeRetry
;
5109 CIFSSMBQFSDeviceInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5111 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5112 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5113 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5114 FILE_SYSTEM_DEVICE_INFO
*response_data
;
5116 int bytes_returned
= 0;
5117 __u16 params
, byte_count
;
5119 cifs_dbg(FYI
, "In QFSDeviceInfo\n");
5121 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5126 params
= 2; /* level */
5127 pSMB
->TotalDataCount
= 0;
5128 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5129 /* BB find exact max SMB PDU from sess structure BB */
5130 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5131 pSMB
->MaxSetupCount
= 0;
5135 pSMB
->Reserved2
= 0;
5136 byte_count
= params
+ 1 /* pad */ ;
5137 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5138 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5139 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5140 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5142 pSMB
->DataCount
= 0;
5143 pSMB
->DataOffset
= 0;
5144 pSMB
->SetupCount
= 1;
5145 pSMB
->Reserved3
= 0;
5146 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5147 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
5148 inc_rfc1001_len(pSMB
, byte_count
);
5149 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5151 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5152 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5154 cifs_dbg(FYI
, "Send error in QFSDeviceInfo = %d\n", rc
);
5155 } else { /* decode response */
5156 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5158 if (rc
|| get_bcc(&pSMBr
->hdr
) <
5159 sizeof(FILE_SYSTEM_DEVICE_INFO
))
5160 rc
= -EIO
; /* bad smb */
5162 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5164 (FILE_SYSTEM_DEVICE_INFO
*)
5165 (((char *) &pSMBr
->hdr
.Protocol
) +
5167 memcpy(&tcon
->fsDevInfo
, response_data
,
5168 sizeof(FILE_SYSTEM_DEVICE_INFO
));
5171 cifs_buf_release(pSMB
);
5174 goto QFSDeviceRetry
;
5180 CIFSSMBQFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5182 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5183 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5184 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5185 FILE_SYSTEM_UNIX_INFO
*response_data
;
5187 int bytes_returned
= 0;
5188 __u16 params
, byte_count
;
5190 cifs_dbg(FYI
, "In QFSUnixInfo\n");
5192 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5193 (void **) &pSMB
, (void **) &pSMBr
);
5197 params
= 2; /* level */
5198 pSMB
->TotalDataCount
= 0;
5199 pSMB
->DataCount
= 0;
5200 pSMB
->DataOffset
= 0;
5201 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5202 /* BB find exact max SMB PDU from sess structure BB */
5203 pSMB
->MaxDataCount
= cpu_to_le16(100);
5204 pSMB
->MaxSetupCount
= 0;
5208 pSMB
->Reserved2
= 0;
5209 byte_count
= params
+ 1 /* pad */ ;
5210 pSMB
->ParameterCount
= cpu_to_le16(params
);
5211 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5212 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5213 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5214 pSMB
->SetupCount
= 1;
5215 pSMB
->Reserved3
= 0;
5216 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5217 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
5218 inc_rfc1001_len(pSMB
, byte_count
);
5219 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5221 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5222 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5224 cifs_dbg(VFS
, "Send error in QFSUnixInfo = %d\n", rc
);
5225 } else { /* decode response */
5226 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5228 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5229 rc
= -EIO
; /* bad smb */
5231 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5233 (FILE_SYSTEM_UNIX_INFO
5234 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5236 memcpy(&tcon
->fsUnixInfo
, response_data
,
5237 sizeof(FILE_SYSTEM_UNIX_INFO
));
5240 cifs_buf_release(pSMB
);
5250 CIFSSMBSetFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
, __u64 cap
)
5252 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5253 TRANSACTION2_SETFSI_REQ
*pSMB
= NULL
;
5254 TRANSACTION2_SETFSI_RSP
*pSMBr
= NULL
;
5256 int bytes_returned
= 0;
5257 __u16 params
, param_offset
, offset
, byte_count
;
5259 cifs_dbg(FYI
, "In SETFSUnixInfo\n");
5261 /* BB switch to small buf init to save memory */
5262 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5263 (void **) &pSMB
, (void **) &pSMBr
);
5267 params
= 4; /* 2 bytes zero followed by info level. */
5268 pSMB
->MaxSetupCount
= 0;
5272 pSMB
->Reserved2
= 0;
5273 param_offset
= offsetof(struct smb_com_transaction2_setfsi_req
, FileNum
)
5275 offset
= param_offset
+ params
;
5277 pSMB
->MaxParameterCount
= cpu_to_le16(4);
5278 /* BB find exact max SMB PDU from sess structure BB */
5279 pSMB
->MaxDataCount
= cpu_to_le16(100);
5280 pSMB
->SetupCount
= 1;
5281 pSMB
->Reserved3
= 0;
5282 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FS_INFORMATION
);
5283 byte_count
= 1 /* pad */ + params
+ 12;
5285 pSMB
->DataCount
= cpu_to_le16(12);
5286 pSMB
->ParameterCount
= cpu_to_le16(params
);
5287 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5288 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5289 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5290 pSMB
->DataOffset
= cpu_to_le16(offset
);
5294 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_CIFS_UNIX_INFO
);
5297 pSMB
->ClientUnixMajor
= cpu_to_le16(CIFS_UNIX_MAJOR_VERSION
);
5298 pSMB
->ClientUnixMinor
= cpu_to_le16(CIFS_UNIX_MINOR_VERSION
);
5299 pSMB
->ClientUnixCap
= cpu_to_le64(cap
);
5301 inc_rfc1001_len(pSMB
, byte_count
);
5302 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5304 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5305 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5307 cifs_dbg(VFS
, "Send error in SETFSUnixInfo = %d\n", rc
);
5308 } else { /* decode response */
5309 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5311 rc
= -EIO
; /* bad smb */
5313 cifs_buf_release(pSMB
);
5316 goto SETFSUnixRetry
;
5324 CIFSSMBQFSPosixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5325 struct kstatfs
*FSData
)
5327 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5328 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5329 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5330 FILE_SYSTEM_POSIX_INFO
*response_data
;
5332 int bytes_returned
= 0;
5333 __u16 params
, byte_count
;
5335 cifs_dbg(FYI
, "In QFSPosixInfo\n");
5337 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5342 params
= 2; /* level */
5343 pSMB
->TotalDataCount
= 0;
5344 pSMB
->DataCount
= 0;
5345 pSMB
->DataOffset
= 0;
5346 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5347 /* BB find exact max SMB PDU from sess structure BB */
5348 pSMB
->MaxDataCount
= cpu_to_le16(100);
5349 pSMB
->MaxSetupCount
= 0;
5353 pSMB
->Reserved2
= 0;
5354 byte_count
= params
+ 1 /* pad */ ;
5355 pSMB
->ParameterCount
= cpu_to_le16(params
);
5356 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5357 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5358 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5359 pSMB
->SetupCount
= 1;
5360 pSMB
->Reserved3
= 0;
5361 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5362 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_FS_INFO
);
5363 inc_rfc1001_len(pSMB
, byte_count
);
5364 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5366 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5367 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5369 cifs_dbg(FYI
, "Send error in QFSUnixInfo = %d\n", rc
);
5370 } else { /* decode response */
5371 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5373 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5374 rc
= -EIO
; /* bad smb */
5376 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5378 (FILE_SYSTEM_POSIX_INFO
5379 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5382 le32_to_cpu(response_data
->BlockSize
);
5384 le64_to_cpu(response_data
->TotalBlocks
);
5386 le64_to_cpu(response_data
->BlocksAvail
);
5387 if (response_data
->UserBlocksAvail
== cpu_to_le64(-1)) {
5388 FSData
->f_bavail
= FSData
->f_bfree
;
5391 le64_to_cpu(response_data
->UserBlocksAvail
);
5393 if (response_data
->TotalFileNodes
!= cpu_to_le64(-1))
5395 le64_to_cpu(response_data
->TotalFileNodes
);
5396 if (response_data
->FreeFileNodes
!= cpu_to_le64(-1))
5398 le64_to_cpu(response_data
->FreeFileNodes
);
5401 cifs_buf_release(pSMB
);
5411 * We can not use write of zero bytes trick to set file size due to need for
5412 * large file support. Also note that this SetPathInfo is preferred to
5413 * SetFileInfo based method in next routine which is only needed to work around
5414 * a sharing violation bugin Samba which this routine can run into.
5417 CIFSSMBSetEOF(const unsigned int xid
, struct cifs_tcon
*tcon
,
5418 const char *file_name
, __u64 size
, struct cifs_sb_info
*cifs_sb
,
5419 bool set_allocation
)
5421 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5422 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5423 struct file_end_of_file_info
*parm_data
;
5426 int bytes_returned
= 0;
5427 int remap
= cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
;
5429 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
5431 cifs_dbg(FYI
, "In SetEOF\n");
5433 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5438 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5440 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5441 PATH_MAX
, cifs_sb
->local_nls
, remap
);
5442 name_len
++; /* trailing null */
5444 } else { /* BB improve the check for buffer overruns BB */
5445 name_len
= strnlen(file_name
, PATH_MAX
);
5446 name_len
++; /* trailing null */
5447 strncpy(pSMB
->FileName
, file_name
, name_len
);
5449 params
= 6 + name_len
;
5450 data_count
= sizeof(struct file_end_of_file_info
);
5451 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5452 pSMB
->MaxDataCount
= cpu_to_le16(4100);
5453 pSMB
->MaxSetupCount
= 0;
5457 pSMB
->Reserved2
= 0;
5458 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5459 InformationLevel
) - 4;
5460 offset
= param_offset
+ params
;
5461 if (set_allocation
) {
5462 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5463 pSMB
->InformationLevel
=
5464 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5466 pSMB
->InformationLevel
=
5467 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5468 } else /* Set File Size */ {
5469 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5470 pSMB
->InformationLevel
=
5471 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5473 pSMB
->InformationLevel
=
5474 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5478 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
5480 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5481 pSMB
->DataOffset
= cpu_to_le16(offset
);
5482 pSMB
->SetupCount
= 1;
5483 pSMB
->Reserved3
= 0;
5484 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5485 byte_count
= 3 /* pad */ + params
+ data_count
;
5486 pSMB
->DataCount
= cpu_to_le16(data_count
);
5487 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5488 pSMB
->ParameterCount
= cpu_to_le16(params
);
5489 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5490 pSMB
->Reserved4
= 0;
5491 inc_rfc1001_len(pSMB
, byte_count
);
5492 parm_data
->FileSize
= cpu_to_le64(size
);
5493 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5494 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5495 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5497 cifs_dbg(FYI
, "SetPathInfo (file size) returned %d\n", rc
);
5499 cifs_buf_release(pSMB
);
5508 CIFSSMBSetFileSize(const unsigned int xid
, struct cifs_tcon
*tcon
,
5509 struct cifsFileInfo
*cfile
, __u64 size
, bool set_allocation
)
5511 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5512 struct file_end_of_file_info
*parm_data
;
5514 __u16 params
, param_offset
, offset
, byte_count
, count
;
5516 cifs_dbg(FYI
, "SetFileSize (via SetFileInfo) %lld\n",
5518 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5523 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)cfile
->pid
);
5524 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(cfile
->pid
>> 16));
5527 pSMB
->MaxSetupCount
= 0;
5531 pSMB
->Reserved2
= 0;
5532 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5533 offset
= param_offset
+ params
;
5535 count
= sizeof(struct file_end_of_file_info
);
5536 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5537 /* BB find exact max SMB PDU from sess structure BB */
5538 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5539 pSMB
->SetupCount
= 1;
5540 pSMB
->Reserved3
= 0;
5541 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5542 byte_count
= 3 /* pad */ + params
+ count
;
5543 pSMB
->DataCount
= cpu_to_le16(count
);
5544 pSMB
->ParameterCount
= cpu_to_le16(params
);
5545 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5546 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5547 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5549 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
)
5551 pSMB
->DataOffset
= cpu_to_le16(offset
);
5552 parm_data
->FileSize
= cpu_to_le64(size
);
5553 pSMB
->Fid
= cfile
->fid
.netfid
;
5554 if (set_allocation
) {
5555 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5556 pSMB
->InformationLevel
=
5557 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5559 pSMB
->InformationLevel
=
5560 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5561 } else /* Set File Size */ {
5562 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5563 pSMB
->InformationLevel
=
5564 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5566 pSMB
->InformationLevel
=
5567 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5569 pSMB
->Reserved4
= 0;
5570 inc_rfc1001_len(pSMB
, byte_count
);
5571 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5572 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5574 cifs_dbg(FYI
, "Send error in SetFileInfo (SetFileSize) = %d\n",
5578 /* Note: On -EAGAIN error only caller can retry on handle based calls
5579 since file handle passed in no longer valid */
5584 /* Some legacy servers such as NT4 require that the file times be set on
5585 an open handle, rather than by pathname - this is awkward due to
5586 potential access conflicts on the open, but it is unavoidable for these
5587 old servers since the only other choice is to go from 100 nanosecond DCE
5588 time and resort to the original setpathinfo level which takes the ancient
5589 DOS time format with 2 second granularity */
5591 CIFSSMBSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5592 const FILE_BASIC_INFO
*data
, __u16 fid
, __u32 pid_of_opener
)
5594 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5597 __u16 params
, param_offset
, offset
, byte_count
, count
;
5599 cifs_dbg(FYI
, "Set Times (via SetFileInfo)\n");
5600 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5605 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5606 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5609 pSMB
->MaxSetupCount
= 0;
5613 pSMB
->Reserved2
= 0;
5614 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5615 offset
= param_offset
+ params
;
5617 data_offset
= (char *)pSMB
+
5618 offsetof(struct smb_hdr
, Protocol
) + offset
;
5620 count
= sizeof(FILE_BASIC_INFO
);
5621 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5622 /* BB find max SMB PDU from sess */
5623 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5624 pSMB
->SetupCount
= 1;
5625 pSMB
->Reserved3
= 0;
5626 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5627 byte_count
= 3 /* pad */ + params
+ count
;
5628 pSMB
->DataCount
= cpu_to_le16(count
);
5629 pSMB
->ParameterCount
= cpu_to_le16(params
);
5630 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5631 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5632 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5633 pSMB
->DataOffset
= cpu_to_le16(offset
);
5635 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5636 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5638 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5639 pSMB
->Reserved4
= 0;
5640 inc_rfc1001_len(pSMB
, byte_count
);
5641 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5642 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5643 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5645 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5648 /* Note: On -EAGAIN error only caller can retry on handle based calls
5649 since file handle passed in no longer valid */
5655 CIFSSMBSetFileDisposition(const unsigned int xid
, struct cifs_tcon
*tcon
,
5656 bool delete_file
, __u16 fid
, __u32 pid_of_opener
)
5658 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5661 __u16 params
, param_offset
, offset
, byte_count
, count
;
5663 cifs_dbg(FYI
, "Set File Disposition (via SetFileInfo)\n");
5664 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5669 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5670 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5673 pSMB
->MaxSetupCount
= 0;
5677 pSMB
->Reserved2
= 0;
5678 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5679 offset
= param_offset
+ params
;
5681 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5684 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5685 /* BB find max SMB PDU from sess */
5686 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5687 pSMB
->SetupCount
= 1;
5688 pSMB
->Reserved3
= 0;
5689 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5690 byte_count
= 3 /* pad */ + params
+ count
;
5691 pSMB
->DataCount
= cpu_to_le16(count
);
5692 pSMB
->ParameterCount
= cpu_to_le16(params
);
5693 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5694 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5695 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5696 pSMB
->DataOffset
= cpu_to_le16(offset
);
5698 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO
);
5699 pSMB
->Reserved4
= 0;
5700 inc_rfc1001_len(pSMB
, byte_count
);
5701 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5702 *data_offset
= delete_file
? 1 : 0;
5703 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5705 cifs_dbg(FYI
, "Send error in SetFileDisposition = %d\n", rc
);
5711 CIFSSMBSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5712 const char *fileName
, const FILE_BASIC_INFO
*data
,
5713 const struct nls_table
*nls_codepage
, int remap
)
5715 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5716 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5719 int bytes_returned
= 0;
5721 __u16 params
, param_offset
, offset
, byte_count
, count
;
5723 cifs_dbg(FYI
, "In SetTimes\n");
5726 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5731 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5733 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5734 PATH_MAX
, nls_codepage
, remap
);
5735 name_len
++; /* trailing null */
5737 } else { /* BB improve the check for buffer overruns BB */
5738 name_len
= strnlen(fileName
, PATH_MAX
);
5739 name_len
++; /* trailing null */
5740 strncpy(pSMB
->FileName
, fileName
, name_len
);
5743 params
= 6 + name_len
;
5744 count
= sizeof(FILE_BASIC_INFO
);
5745 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5746 /* BB find max SMB PDU from sess structure BB */
5747 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5748 pSMB
->MaxSetupCount
= 0;
5752 pSMB
->Reserved2
= 0;
5753 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5754 InformationLevel
) - 4;
5755 offset
= param_offset
+ params
;
5756 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5757 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5758 pSMB
->DataOffset
= cpu_to_le16(offset
);
5759 pSMB
->SetupCount
= 1;
5760 pSMB
->Reserved3
= 0;
5761 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5762 byte_count
= 3 /* pad */ + params
+ count
;
5764 pSMB
->DataCount
= cpu_to_le16(count
);
5765 pSMB
->ParameterCount
= cpu_to_le16(params
);
5766 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5767 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5768 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5769 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5771 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5772 pSMB
->Reserved4
= 0;
5773 inc_rfc1001_len(pSMB
, byte_count
);
5774 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5775 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5776 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5777 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5779 cifs_dbg(FYI
, "SetPathInfo (times) returned %d\n", rc
);
5781 cifs_buf_release(pSMB
);
5789 /* Can not be used to set time stamps yet (due to old DOS time format) */
5790 /* Can be used to set attributes */
5791 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5792 handling it anyway and NT4 was what we thought it would be needed for
5793 Do not delete it until we prove whether needed for Win9x though */
5795 CIFSSMBSetAttrLegacy(unsigned int xid
, struct cifs_tcon
*tcon
, char *fileName
,
5796 __u16 dos_attrs
, const struct nls_table
*nls_codepage
)
5798 SETATTR_REQ
*pSMB
= NULL
;
5799 SETATTR_RSP
*pSMBr
= NULL
;
5804 cifs_dbg(FYI
, "In SetAttrLegacy\n");
5807 rc
= smb_init(SMB_COM_SETATTR
, 8, tcon
, (void **) &pSMB
,
5812 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5814 ConvertToUTF16((__le16
*) pSMB
->fileName
, fileName
,
5815 PATH_MAX
, nls_codepage
);
5816 name_len
++; /* trailing null */
5818 } else { /* BB improve the check for buffer overruns BB */
5819 name_len
= strnlen(fileName
, PATH_MAX
);
5820 name_len
++; /* trailing null */
5821 strncpy(pSMB
->fileName
, fileName
, name_len
);
5823 pSMB
->attr
= cpu_to_le16(dos_attrs
);
5824 pSMB
->BufferFormat
= 0x04;
5825 inc_rfc1001_len(pSMB
, name_len
+ 1);
5826 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
5827 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5828 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5830 cifs_dbg(FYI
, "Error in LegacySetAttr = %d\n", rc
);
5832 cifs_buf_release(pSMB
);
5835 goto SetAttrLgcyRetry
;
5839 #endif /* temporarily unneeded SetAttr legacy function */
5842 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO
*data_offset
,
5843 const struct cifs_unix_set_info_args
*args
)
5845 u64 uid
= NO_CHANGE_64
, gid
= NO_CHANGE_64
;
5846 u64 mode
= args
->mode
;
5848 if (uid_valid(args
->uid
))
5849 uid
= from_kuid(&init_user_ns
, args
->uid
);
5850 if (gid_valid(args
->gid
))
5851 gid
= from_kgid(&init_user_ns
, args
->gid
);
5854 * Samba server ignores set of file size to zero due to bugs in some
5855 * older clients, but we should be precise - we use SetFileSize to
5856 * set file size and do not want to truncate file size to zero
5857 * accidentally as happened on one Samba server beta by putting
5858 * zero instead of -1 here
5860 data_offset
->EndOfFile
= cpu_to_le64(NO_CHANGE_64
);
5861 data_offset
->NumOfBytes
= cpu_to_le64(NO_CHANGE_64
);
5862 data_offset
->LastStatusChange
= cpu_to_le64(args
->ctime
);
5863 data_offset
->LastAccessTime
= cpu_to_le64(args
->atime
);
5864 data_offset
->LastModificationTime
= cpu_to_le64(args
->mtime
);
5865 data_offset
->Uid
= cpu_to_le64(uid
);
5866 data_offset
->Gid
= cpu_to_le64(gid
);
5867 /* better to leave device as zero when it is */
5868 data_offset
->DevMajor
= cpu_to_le64(MAJOR(args
->device
));
5869 data_offset
->DevMinor
= cpu_to_le64(MINOR(args
->device
));
5870 data_offset
->Permissions
= cpu_to_le64(mode
);
5873 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
5874 else if (S_ISDIR(mode
))
5875 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
5876 else if (S_ISLNK(mode
))
5877 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
5878 else if (S_ISCHR(mode
))
5879 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
5880 else if (S_ISBLK(mode
))
5881 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
5882 else if (S_ISFIFO(mode
))
5883 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
5884 else if (S_ISSOCK(mode
))
5885 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
5889 CIFSSMBUnixSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5890 const struct cifs_unix_set_info_args
*args
,
5891 u16 fid
, u32 pid_of_opener
)
5893 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5896 u16 params
, param_offset
, offset
, byte_count
, count
;
5898 cifs_dbg(FYI
, "Set Unix Info (via SetFileInfo)\n");
5899 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5904 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5905 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5908 pSMB
->MaxSetupCount
= 0;
5912 pSMB
->Reserved2
= 0;
5913 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5914 offset
= param_offset
+ params
;
5916 data_offset
= (char *)pSMB
+
5917 offsetof(struct smb_hdr
, Protocol
) + offset
;
5919 count
= sizeof(FILE_UNIX_BASIC_INFO
);
5921 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5922 /* BB find max SMB PDU from sess */
5923 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5924 pSMB
->SetupCount
= 1;
5925 pSMB
->Reserved3
= 0;
5926 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5927 byte_count
= 3 /* pad */ + params
+ count
;
5928 pSMB
->DataCount
= cpu_to_le16(count
);
5929 pSMB
->ParameterCount
= cpu_to_le16(params
);
5930 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5931 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5932 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5933 pSMB
->DataOffset
= cpu_to_le16(offset
);
5935 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
5936 pSMB
->Reserved4
= 0;
5937 inc_rfc1001_len(pSMB
, byte_count
);
5938 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5940 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO
*)data_offset
, args
);
5942 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5944 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5947 /* Note: On -EAGAIN error only caller can retry on handle based calls
5948 since file handle passed in no longer valid */
5954 CIFSSMBUnixSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5955 const char *file_name
,
5956 const struct cifs_unix_set_info_args
*args
,
5957 const struct nls_table
*nls_codepage
, int remap
)
5959 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5960 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5963 int bytes_returned
= 0;
5964 FILE_UNIX_BASIC_INFO
*data_offset
;
5965 __u16 params
, param_offset
, offset
, count
, byte_count
;
5967 cifs_dbg(FYI
, "In SetUID/GID/Mode\n");
5969 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5974 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5976 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5977 PATH_MAX
, nls_codepage
, remap
);
5978 name_len
++; /* trailing null */
5980 } else { /* BB improve the check for buffer overruns BB */
5981 name_len
= strnlen(file_name
, PATH_MAX
);
5982 name_len
++; /* trailing null */
5983 strncpy(pSMB
->FileName
, file_name
, name_len
);
5986 params
= 6 + name_len
;
5987 count
= sizeof(FILE_UNIX_BASIC_INFO
);
5988 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5989 /* BB find max SMB PDU from sess structure BB */
5990 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5991 pSMB
->MaxSetupCount
= 0;
5995 pSMB
->Reserved2
= 0;
5996 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5997 InformationLevel
) - 4;
5998 offset
= param_offset
+ params
;
6000 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
6002 memset(data_offset
, 0, count
);
6003 pSMB
->DataOffset
= cpu_to_le16(offset
);
6004 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6005 pSMB
->SetupCount
= 1;
6006 pSMB
->Reserved3
= 0;
6007 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6008 byte_count
= 3 /* pad */ + params
+ count
;
6009 pSMB
->ParameterCount
= cpu_to_le16(params
);
6010 pSMB
->DataCount
= cpu_to_le16(count
);
6011 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6012 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6013 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6014 pSMB
->Reserved4
= 0;
6015 inc_rfc1001_len(pSMB
, byte_count
);
6017 cifs_fill_unix_set_info(data_offset
, args
);
6019 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6020 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6021 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6023 cifs_dbg(FYI
, "SetPathInfo (perms) returned %d\n", rc
);
6025 cifs_buf_release(pSMB
);
6031 #ifdef CONFIG_CIFS_XATTR
6033 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6034 * function used by listxattr and getxattr type calls. When ea_name is set,
6035 * it looks for that attribute name and stuffs that value into the EAData
6036 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6037 * buffer. In both cases, the return value is either the length of the
6038 * resulting data or a negative error code. If EAData is a NULL pointer then
6039 * the data isn't copied to it, but the length is returned.
6042 CIFSSMBQAllEAs(const unsigned int xid
, struct cifs_tcon
*tcon
,
6043 const unsigned char *searchName
, const unsigned char *ea_name
,
6044 char *EAData
, size_t buf_size
,
6045 const struct nls_table
*nls_codepage
, int remap
)
6047 /* BB assumes one setup word */
6048 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
6049 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
6053 struct fealist
*ea_response_data
;
6054 struct fea
*temp_fea
;
6057 __u16 params
, byte_count
, data_offset
;
6058 unsigned int ea_name_len
= ea_name
? strlen(ea_name
) : 0;
6060 cifs_dbg(FYI
, "In Query All EAs path %s\n", searchName
);
6062 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6067 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6069 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
6070 PATH_MAX
, nls_codepage
, remap
);
6071 list_len
++; /* trailing null */
6073 } else { /* BB improve the check for buffer overruns BB */
6074 list_len
= strnlen(searchName
, PATH_MAX
);
6075 list_len
++; /* trailing null */
6076 strncpy(pSMB
->FileName
, searchName
, list_len
);
6079 params
= 2 /* level */ + 4 /* reserved */ + list_len
/* includes NUL */;
6080 pSMB
->TotalDataCount
= 0;
6081 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6082 /* BB find exact max SMB PDU from sess structure BB */
6083 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
6084 pSMB
->MaxSetupCount
= 0;
6088 pSMB
->Reserved2
= 0;
6089 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
6090 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
6091 pSMB
->DataCount
= 0;
6092 pSMB
->DataOffset
= 0;
6093 pSMB
->SetupCount
= 1;
6094 pSMB
->Reserved3
= 0;
6095 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
6096 byte_count
= params
+ 1 /* pad */ ;
6097 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
6098 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6099 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
6100 pSMB
->Reserved4
= 0;
6101 inc_rfc1001_len(pSMB
, byte_count
);
6102 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6104 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6105 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6107 cifs_dbg(FYI
, "Send error in QueryAllEAs = %d\n", rc
);
6112 /* BB also check enough total bytes returned */
6113 /* BB we need to improve the validity checking
6114 of these trans2 responses */
6116 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
6117 if (rc
|| get_bcc(&pSMBr
->hdr
) < 4) {
6118 rc
= -EIO
; /* bad smb */
6122 /* check that length of list is not more than bcc */
6123 /* check that each entry does not go beyond length
6125 /* check that each element of each entry does not
6126 go beyond end of list */
6127 /* validate_trans2_offsets() */
6128 /* BB check if start of smb + data_offset > &bcc+ bcc */
6130 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
6131 ea_response_data
= (struct fealist
*)
6132 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
6134 list_len
= le32_to_cpu(ea_response_data
->list_len
);
6135 cifs_dbg(FYI
, "ea length %d\n", list_len
);
6136 if (list_len
<= 8) {
6137 cifs_dbg(FYI
, "empty EA list returned from server\n");
6141 /* make sure list_len doesn't go past end of SMB */
6142 end_of_smb
= (char *)pByteArea(&pSMBr
->hdr
) + get_bcc(&pSMBr
->hdr
);
6143 if ((char *)ea_response_data
+ list_len
> end_of_smb
) {
6144 cifs_dbg(FYI
, "EA list appears to go beyond SMB\n");
6149 /* account for ea list len */
6151 temp_fea
= ea_response_data
->list
;
6152 temp_ptr
= (char *)temp_fea
;
6153 while (list_len
> 0) {
6154 unsigned int name_len
;
6159 /* make sure we can read name_len and value_len */
6161 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6166 name_len
= temp_fea
->name_len
;
6167 value_len
= le16_to_cpu(temp_fea
->value_len
);
6168 list_len
-= name_len
+ 1 + value_len
;
6170 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6176 if (ea_name_len
== name_len
&&
6177 memcmp(ea_name
, temp_ptr
, name_len
) == 0) {
6178 temp_ptr
+= name_len
+ 1;
6182 if ((size_t)value_len
> buf_size
) {
6186 memcpy(EAData
, temp_ptr
, value_len
);
6190 /* account for prefix user. and trailing null */
6191 rc
+= (5 + 1 + name_len
);
6192 if (rc
< (int) buf_size
) {
6193 memcpy(EAData
, "user.", 5);
6195 memcpy(EAData
, temp_ptr
, name_len
);
6197 /* null terminate name */
6200 } else if (buf_size
== 0) {
6201 /* skip copy - calc size only */
6203 /* stop before overrun buffer */
6208 temp_ptr
+= name_len
+ 1 + value_len
;
6209 temp_fea
= (struct fea
*)temp_ptr
;
6212 /* didn't find the named attribute */
6217 cifs_buf_release(pSMB
);
6225 CIFSSMBSetEA(const unsigned int xid
, struct cifs_tcon
*tcon
,
6226 const char *fileName
, const char *ea_name
, const void *ea_value
,
6227 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
,
6230 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
6231 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
6232 struct fealist
*parm_data
;
6235 int bytes_returned
= 0;
6236 __u16 params
, param_offset
, byte_count
, offset
, count
;
6238 cifs_dbg(FYI
, "In SetEA\n");
6240 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6245 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6247 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
6248 PATH_MAX
, nls_codepage
, remap
);
6249 name_len
++; /* trailing null */
6251 } else { /* BB improve the check for buffer overruns BB */
6252 name_len
= strnlen(fileName
, PATH_MAX
);
6253 name_len
++; /* trailing null */
6254 strncpy(pSMB
->FileName
, fileName
, name_len
);
6257 params
= 6 + name_len
;
6259 /* done calculating parms using name_len of file name,
6260 now use name_len to calculate length of ea name
6261 we are going to create in the inode xattrs */
6262 if (ea_name
== NULL
)
6265 name_len
= strnlen(ea_name
, 255);
6267 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
;
6268 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6269 /* BB find max SMB PDU from sess */
6270 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6271 pSMB
->MaxSetupCount
= 0;
6275 pSMB
->Reserved2
= 0;
6276 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6277 InformationLevel
) - 4;
6278 offset
= param_offset
+ params
;
6279 pSMB
->InformationLevel
=
6280 cpu_to_le16(SMB_SET_FILE_EA
);
6283 (struct fealist
*) (((char *) &pSMB
->hdr
.Protocol
) +
6285 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6286 pSMB
->DataOffset
= cpu_to_le16(offset
);
6287 pSMB
->SetupCount
= 1;
6288 pSMB
->Reserved3
= 0;
6289 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6290 byte_count
= 3 /* pad */ + params
+ count
;
6291 pSMB
->DataCount
= cpu_to_le16(count
);
6292 parm_data
->list_len
= cpu_to_le32(count
);
6293 parm_data
->list
[0].EA_flags
= 0;
6294 /* we checked above that name len is less than 255 */
6295 parm_data
->list
[0].name_len
= (__u8
)name_len
;
6296 /* EA names are always ASCII */
6298 strncpy(parm_data
->list
[0].name
, ea_name
, name_len
);
6299 parm_data
->list
[0].name
[name_len
] = 0;
6300 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
6301 /* caller ensures that ea_value_len is less than 64K but
6302 we need to ensure that it fits within the smb */
6304 /*BB add length check to see if it would fit in
6305 negotiated SMB buffer size BB */
6306 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6308 memcpy(parm_data
->list
[0].name
+name_len
+1,
6309 ea_value
, ea_value_len
);
6311 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6312 pSMB
->ParameterCount
= cpu_to_le16(params
);
6313 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6314 pSMB
->Reserved4
= 0;
6315 inc_rfc1001_len(pSMB
, byte_count
);
6316 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6317 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6318 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6320 cifs_dbg(FYI
, "SetPathInfo (EA) returned %d\n", rc
);
6322 cifs_buf_release(pSMB
);
6331 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6333 * Years ago the kernel added a "dnotify" function for Samba server,
6334 * to allow network clients (such as Windows) to display updated
6335 * lists of files in directory listings automatically when
6336 * files are added by one user when another user has the
6337 * same directory open on their desktop. The Linux cifs kernel
6338 * client hooked into the kernel side of this interface for
6339 * the same reason, but ironically when the VFS moved from
6340 * "dnotify" to "inotify" it became harder to plug in Linux
6341 * network file system clients (the most obvious use case
6342 * for notify interfaces is when multiple users can update
6343 * the contents of the same directory - exactly what network
6344 * file systems can do) although the server (Samba) could
6345 * still use it. For the short term we leave the worker
6346 * function ifdeffed out (below) until inotify is fixed
6347 * in the VFS to make it easier to plug in network file
6348 * system clients. If inotify turns out to be permanently
6349 * incompatible for network fs clients, we could instead simply
6350 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6352 int CIFSSMBNotify(const unsigned int xid
, struct cifs_tcon
*tcon
,
6353 const int notify_subdirs
, const __u16 netfid
,
6354 __u32 filter
, struct file
*pfile
, int multishot
,
6355 const struct nls_table
*nls_codepage
)
6358 struct smb_com_transaction_change_notify_req
*pSMB
= NULL
;
6359 struct smb_com_ntransaction_change_notify_rsp
*pSMBr
= NULL
;
6360 struct dir_notify_req
*dnotify_req
;
6363 cifs_dbg(FYI
, "In CIFSSMBNotify for file handle %d\n", (int)netfid
);
6364 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
6369 pSMB
->TotalParameterCount
= 0 ;
6370 pSMB
->TotalDataCount
= 0;
6371 pSMB
->MaxParameterCount
= cpu_to_le32(2);
6372 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
6373 pSMB
->MaxSetupCount
= 4;
6375 pSMB
->ParameterOffset
= 0;
6376 pSMB
->DataCount
= 0;
6377 pSMB
->DataOffset
= 0;
6378 pSMB
->SetupCount
= 4; /* single byte does not need le conversion */
6379 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE
);
6380 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6382 pSMB
->WatchTree
= 1; /* one byte - no le conversion needed */
6383 pSMB
->Reserved2
= 0;
6384 pSMB
->CompletionFilter
= cpu_to_le32(filter
);
6385 pSMB
->Fid
= netfid
; /* file handle always le */
6386 pSMB
->ByteCount
= 0;
6388 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6389 (struct smb_hdr
*)pSMBr
, &bytes_returned
,
6392 cifs_dbg(FYI
, "Error in Notify = %d\n", rc
);
6394 /* Add file to outstanding requests */
6395 /* BB change to kmem cache alloc */
6396 dnotify_req
= kmalloc(
6397 sizeof(struct dir_notify_req
),
6400 dnotify_req
->Pid
= pSMB
->hdr
.Pid
;
6401 dnotify_req
->PidHigh
= pSMB
->hdr
.PidHigh
;
6402 dnotify_req
->Mid
= pSMB
->hdr
.Mid
;
6403 dnotify_req
->Tid
= pSMB
->hdr
.Tid
;
6404 dnotify_req
->Uid
= pSMB
->hdr
.Uid
;
6405 dnotify_req
->netfid
= netfid
;
6406 dnotify_req
->pfile
= pfile
;
6407 dnotify_req
->filter
= filter
;
6408 dnotify_req
->multishot
= multishot
;
6409 spin_lock(&GlobalMid_Lock
);
6410 list_add_tail(&dnotify_req
->lhead
,
6411 &GlobalDnotifyReqList
);
6412 spin_unlock(&GlobalMid_Lock
);
6416 cifs_buf_release(pSMB
);
6419 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */