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(&tcon
->open_file_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(&tcon
->open_file_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 rc
= wait_event_interruptible_timeout(server
->response_q
,
154 (server
->tcpStatus
!= CifsNeedReconnect
),
157 cifs_dbg(FYI
, "%s: aborting reconnect due to a received"
158 " signal by the process\n", __func__
);
162 /* are we still trying to reconnect? */
163 if (server
->tcpStatus
!= CifsNeedReconnect
)
167 * on "soft" mounts we wait once. Hard mounts keep
168 * retrying until process is killed or server comes
172 cifs_dbg(FYI
, "gave up waiting on reconnect in smb_init\n");
177 if (!ses
->need_reconnect
&& !tcon
->need_reconnect
)
180 nls_codepage
= load_nls_default();
183 * need to prevent multiple threads trying to simultaneously
184 * reconnect the same SMB session
186 mutex_lock(&ses
->session_mutex
);
187 rc
= cifs_negotiate_protocol(0, ses
);
188 if (rc
== 0 && ses
->need_reconnect
)
189 rc
= cifs_setup_session(0, ses
, nls_codepage
);
191 /* do we need to reconnect tcon? */
192 if (rc
|| !tcon
->need_reconnect
) {
193 mutex_unlock(&ses
->session_mutex
);
197 cifs_mark_open_files_invalid(tcon
);
198 rc
= CIFSTCon(0, ses
, tcon
->treeName
, tcon
, nls_codepage
);
199 mutex_unlock(&ses
->session_mutex
);
200 cifs_dbg(FYI
, "reconnect tcon rc = %d\n", rc
);
205 atomic_inc(&tconInfoReconnectCount
);
207 /* tell server Unix caps we support */
208 if (ses
->capabilities
& CAP_UNIX
)
209 reset_cifs_unix_caps(0, tcon
, NULL
, NULL
);
212 * Removed call to reopen open files here. It is safer (and faster) to
213 * reopen files one at a time as needed in read and write.
215 * FIXME: what about file locks? don't we need to reclaim them ASAP?
220 * Check if handle based operation so we know whether we can continue
221 * or not without returning to caller to reset file handle
223 switch (smb_command
) {
224 case SMB_COM_READ_ANDX
:
225 case SMB_COM_WRITE_ANDX
:
227 case SMB_COM_FIND_CLOSE2
:
228 case SMB_COM_LOCKING_ANDX
:
232 unload_nls(nls_codepage
);
236 /* Allocate and return pointer to an SMB request buffer, and set basic
237 SMB information in the SMB header. If the return code is zero, this
238 function must have filled in request_buf pointer */
240 small_smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
245 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
249 *request_buf
= cifs_small_buf_get();
250 if (*request_buf
== NULL
) {
251 /* BB should we add a retry in here if not a writepage? */
255 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
,
259 cifs_stats_inc(&tcon
->num_smbs_sent
);
265 small_smb_init_no_tc(const int smb_command
, const int wct
,
266 struct cifs_ses
*ses
, void **request_buf
)
269 struct smb_hdr
*buffer
;
271 rc
= small_smb_init(smb_command
, wct
, NULL
, request_buf
);
275 buffer
= (struct smb_hdr
*)*request_buf
;
276 buffer
->Mid
= get_next_mid(ses
->server
);
277 if (ses
->capabilities
& CAP_UNICODE
)
278 buffer
->Flags2
|= SMBFLG2_UNICODE
;
279 if (ses
->capabilities
& CAP_STATUS32
)
280 buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
282 /* uid, tid can stay at zero as set in header assemble */
284 /* BB add support for turning on the signing when
285 this function is used after 1st of session setup requests */
290 /* If the return code is zero, this function must fill in request_buf pointer */
292 __smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
293 void **request_buf
, void **response_buf
)
295 *request_buf
= cifs_buf_get();
296 if (*request_buf
== NULL
) {
297 /* BB should we add a retry in here if not a writepage? */
300 /* Although the original thought was we needed the response buf for */
301 /* potential retries of smb operations it turns out we can determine */
302 /* from the mid flags when the request buffer can be resent without */
303 /* having to use a second distinct buffer for the response */
305 *response_buf
= *request_buf
;
307 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
, tcon
,
311 cifs_stats_inc(&tcon
->num_smbs_sent
);
316 /* If the return code is zero, this function must fill in request_buf pointer */
318 smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
319 void **request_buf
, void **response_buf
)
323 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
327 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
331 smb_init_no_reconnect(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
332 void **request_buf
, void **response_buf
)
334 if (tcon
->ses
->need_reconnect
|| tcon
->need_reconnect
)
337 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
340 static int validate_t2(struct smb_t2_rsp
*pSMB
)
342 unsigned int total_size
;
344 /* check for plausible wct */
345 if (pSMB
->hdr
.WordCount
< 10)
348 /* check for parm and data offset going beyond end of smb */
349 if (get_unaligned_le16(&pSMB
->t2_rsp
.ParameterOffset
) > 1024 ||
350 get_unaligned_le16(&pSMB
->t2_rsp
.DataOffset
) > 1024)
353 total_size
= get_unaligned_le16(&pSMB
->t2_rsp
.ParameterCount
);
354 if (total_size
>= 512)
357 /* check that bcc is at least as big as parms + data, and that it is
358 * less than negotiated smb buffer
360 total_size
+= get_unaligned_le16(&pSMB
->t2_rsp
.DataCount
);
361 if (total_size
> get_bcc(&pSMB
->hdr
) ||
362 total_size
>= CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
)
367 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB
,
368 sizeof(struct smb_t2_rsp
) + 16);
373 decode_ext_sec_blob(struct cifs_ses
*ses
, NEGOTIATE_RSP
*pSMBr
)
377 char *guid
= pSMBr
->u
.extended_response
.GUID
;
378 struct TCP_Server_Info
*server
= ses
->server
;
380 count
= get_bcc(&pSMBr
->hdr
);
381 if (count
< SMB1_CLIENT_GUID_SIZE
)
384 spin_lock(&cifs_tcp_ses_lock
);
385 if (server
->srv_count
> 1) {
386 spin_unlock(&cifs_tcp_ses_lock
);
387 if (memcmp(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
) != 0) {
388 cifs_dbg(FYI
, "server UID changed\n");
389 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
392 spin_unlock(&cifs_tcp_ses_lock
);
393 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
396 if (count
== SMB1_CLIENT_GUID_SIZE
) {
397 server
->sec_ntlmssp
= true;
399 count
-= SMB1_CLIENT_GUID_SIZE
;
400 rc
= decode_negTokenInit(
401 pSMBr
->u
.extended_response
.SecurityBlob
, count
, server
);
410 cifs_enable_signing(struct TCP_Server_Info
*server
, bool mnt_sign_required
)
412 bool srv_sign_required
= server
->sec_mode
& server
->vals
->signing_required
;
413 bool srv_sign_enabled
= server
->sec_mode
& server
->vals
->signing_enabled
;
414 bool mnt_sign_enabled
= global_secflags
& CIFSSEC_MAY_SIGN
;
417 * Is signing required by mnt options? If not then check
418 * global_secflags to see if it is there.
420 if (!mnt_sign_required
)
421 mnt_sign_required
= ((global_secflags
& CIFSSEC_MUST_SIGN
) ==
425 * If signing is required then it's automatically enabled too,
426 * otherwise, check to see if the secflags allow it.
428 mnt_sign_enabled
= mnt_sign_required
? mnt_sign_required
:
429 (global_secflags
& CIFSSEC_MAY_SIGN
);
431 /* If server requires signing, does client allow it? */
432 if (srv_sign_required
) {
433 if (!mnt_sign_enabled
) {
434 cifs_dbg(VFS
, "Server requires signing, but it's disabled in SecurityFlags!");
440 /* If client requires signing, does server allow it? */
441 if (mnt_sign_required
) {
442 if (!srv_sign_enabled
) {
443 cifs_dbg(VFS
, "Server does not support signing!");
452 #ifdef CONFIG_CIFS_WEAK_PW_HASH
454 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
457 struct lanman_neg_rsp
*rsp
= (struct lanman_neg_rsp
*)pSMBr
;
459 if (server
->dialect
!= LANMAN_PROT
&& server
->dialect
!= LANMAN2_PROT
)
462 server
->sec_mode
= le16_to_cpu(rsp
->SecurityMode
);
463 server
->maxReq
= min_t(unsigned int,
464 le16_to_cpu(rsp
->MaxMpxCount
),
466 set_credits(server
, server
->maxReq
);
467 server
->maxBuf
= le16_to_cpu(rsp
->MaxBufSize
);
468 /* even though we do not use raw we might as well set this
469 accurately, in case we ever find a need for it */
470 if ((le16_to_cpu(rsp
->RawMode
) & RAW_ENABLE
) == RAW_ENABLE
) {
471 server
->max_rw
= 0xFF00;
472 server
->capabilities
= CAP_MPX_MODE
| CAP_RAW_MODE
;
474 server
->max_rw
= 0;/* do not need to use raw anyway */
475 server
->capabilities
= CAP_MPX_MODE
;
477 tmp
= (__s16
)le16_to_cpu(rsp
->ServerTimeZone
);
479 /* OS/2 often does not set timezone therefore
480 * we must use server time to calc time zone.
481 * Could deviate slightly from the right zone.
482 * Smallest defined timezone difference is 15 minutes
483 * (i.e. Nepal). Rounding up/down is done to match
486 int val
, seconds
, remain
, result
;
487 struct timespec ts
, utc
;
489 ts
= cnvrtDosUnixTm(rsp
->SrvTime
.Date
,
490 rsp
->SrvTime
.Time
, 0);
491 cifs_dbg(FYI
, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
492 (int)ts
.tv_sec
, (int)utc
.tv_sec
,
493 (int)(utc
.tv_sec
- ts
.tv_sec
));
494 val
= (int)(utc
.tv_sec
- ts
.tv_sec
);
496 result
= (seconds
/ MIN_TZ_ADJ
) * MIN_TZ_ADJ
;
497 remain
= seconds
% MIN_TZ_ADJ
;
498 if (remain
>= (MIN_TZ_ADJ
/ 2))
499 result
+= MIN_TZ_ADJ
;
502 server
->timeAdj
= result
;
504 server
->timeAdj
= (int)tmp
;
505 server
->timeAdj
*= 60; /* also in seconds */
507 cifs_dbg(FYI
, "server->timeAdj: %d seconds\n", server
->timeAdj
);
510 /* BB get server time for time conversions and add
511 code to use it and timezone since this is not UTC */
513 if (rsp
->EncryptionKeyLength
==
514 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE
)) {
515 memcpy(server
->cryptkey
, rsp
->EncryptionKey
,
516 CIFS_CRYPTO_KEY_SIZE
);
517 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
518 return -EIO
; /* need cryptkey unless plain text */
521 cifs_dbg(FYI
, "LANMAN negotiated\n");
526 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
528 cifs_dbg(VFS
, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
534 should_set_ext_sec_flag(enum securityEnum sectype
)
541 if (global_secflags
&
542 (CIFSSEC_MAY_KRB5
| CIFSSEC_MAY_NTLMSSP
))
551 CIFSSMBNegotiate(const unsigned int xid
, struct cifs_ses
*ses
)
554 NEGOTIATE_RSP
*pSMBr
;
558 struct TCP_Server_Info
*server
= ses
->server
;
562 WARN(1, "%s: server is NULL!\n", __func__
);
566 rc
= smb_init(SMB_COM_NEGOTIATE
, 0, NULL
/* no tcon yet */ ,
567 (void **) &pSMB
, (void **) &pSMBr
);
571 pSMB
->hdr
.Mid
= get_next_mid(server
);
572 pSMB
->hdr
.Flags2
|= (SMBFLG2_UNICODE
| SMBFLG2_ERR_STATUS
);
574 if (should_set_ext_sec_flag(ses
->sectype
)) {
575 cifs_dbg(FYI
, "Requesting extended security.");
576 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
581 * We know that all the name entries in the protocols array
582 * are short (< 16 bytes anyway) and are NUL terminated.
584 for (i
= 0; i
< CIFS_NUM_PROT
; i
++) {
585 size_t len
= strlen(protocols
[i
].name
) + 1;
587 memcpy(pSMB
->DialectsArray
+count
, protocols
[i
].name
, len
);
590 inc_rfc1001_len(pSMB
, count
);
591 pSMB
->ByteCount
= cpu_to_le16(count
);
593 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
594 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
598 server
->dialect
= le16_to_cpu(pSMBr
->DialectIndex
);
599 cifs_dbg(FYI
, "Dialect: %d\n", server
->dialect
);
600 /* Check wct = 1 error case */
601 if ((pSMBr
->hdr
.WordCount
< 13) || (server
->dialect
== BAD_PROT
)) {
602 /* core returns wct = 1, but we do not ask for core - otherwise
603 small wct just comes when dialect index is -1 indicating we
604 could not negotiate a common dialect */
607 } else if (pSMBr
->hdr
.WordCount
== 13) {
608 server
->negflavor
= CIFS_NEGFLAVOR_LANMAN
;
609 rc
= decode_lanman_negprot_rsp(server
, pSMBr
);
611 } else if (pSMBr
->hdr
.WordCount
!= 17) {
616 /* else wct == 17, NTLM or better */
618 server
->sec_mode
= pSMBr
->SecurityMode
;
619 if ((server
->sec_mode
& SECMODE_USER
) == 0)
620 cifs_dbg(FYI
, "share mode security\n");
622 /* one byte, so no need to convert this or EncryptionKeyLen from
624 server
->maxReq
= min_t(unsigned int, le16_to_cpu(pSMBr
->MaxMpxCount
),
626 set_credits(server
, server
->maxReq
);
627 /* probably no need to store and check maxvcs */
628 server
->maxBuf
= le32_to_cpu(pSMBr
->MaxBufferSize
);
629 server
->max_rw
= le32_to_cpu(pSMBr
->MaxRawSize
);
630 cifs_dbg(NOISY
, "Max buf = %d\n", ses
->server
->maxBuf
);
631 server
->capabilities
= le32_to_cpu(pSMBr
->Capabilities
);
632 server
->timeAdj
= (int)(__s16
)le16_to_cpu(pSMBr
->ServerTimeZone
);
633 server
->timeAdj
*= 60;
635 if (pSMBr
->EncryptionKeyLength
== CIFS_CRYPTO_KEY_SIZE
) {
636 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
637 memcpy(ses
->server
->cryptkey
, pSMBr
->u
.EncryptionKey
,
638 CIFS_CRYPTO_KEY_SIZE
);
639 } else if (pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
||
640 server
->capabilities
& CAP_EXTENDED_SECURITY
) {
641 server
->negflavor
= CIFS_NEGFLAVOR_EXTENDED
;
642 rc
= decode_ext_sec_blob(ses
, pSMBr
);
643 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
644 rc
= -EIO
; /* no crypt key only if plain text pwd */
646 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
647 server
->capabilities
&= ~CAP_EXTENDED_SECURITY
;
652 rc
= cifs_enable_signing(server
, ses
->sign
);
654 cifs_buf_release(pSMB
);
656 cifs_dbg(FYI
, "negprot rc %d\n", rc
);
661 CIFSSMBTDis(const unsigned int xid
, struct cifs_tcon
*tcon
)
663 struct smb_hdr
*smb_buffer
;
666 cifs_dbg(FYI
, "In tree disconnect\n");
668 /* BB: do we need to check this? These should never be NULL. */
669 if ((tcon
->ses
== NULL
) || (tcon
->ses
->server
== NULL
))
673 * No need to return error on this operation if tid invalidated and
674 * closed on server already e.g. due to tcp session crashing. Also,
675 * the tcon is no longer on the list, so no need to take lock before
678 if ((tcon
->need_reconnect
) || (tcon
->ses
->need_reconnect
))
681 rc
= small_smb_init(SMB_COM_TREE_DISCONNECT
, 0, tcon
,
682 (void **)&smb_buffer
);
686 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)smb_buffer
, 0);
688 cifs_dbg(FYI
, "Tree disconnect failed %d\n", rc
);
690 /* No need to return error on this operation if tid invalidated and
691 closed on server already e.g. due to tcp session crashing */
699 * This is a no-op for now. We're not really interested in the reply, but
700 * rather in the fact that the server sent one and that server->lstrp
703 * FIXME: maybe we should consider checking that the reply matches request?
706 cifs_echo_callback(struct mid_q_entry
*mid
)
708 struct TCP_Server_Info
*server
= mid
->callback_data
;
710 mutex_lock(&server
->srv_mutex
);
711 DeleteMidQEntry(mid
);
712 mutex_unlock(&server
->srv_mutex
);
713 add_credits(server
, 1, CIFS_ECHO_OP
);
717 CIFSSMBEcho(struct TCP_Server_Info
*server
)
722 struct smb_rqst rqst
= { .rq_iov
= &iov
,
725 cifs_dbg(FYI
, "In echo request\n");
727 rc
= small_smb_init(SMB_COM_ECHO
, 0, NULL
, (void **)&smb
);
731 if (server
->capabilities
& CAP_UNICODE
)
732 smb
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
734 /* set up echo request */
735 smb
->hdr
.Tid
= 0xffff;
736 smb
->hdr
.WordCount
= 1;
737 put_unaligned_le16(1, &smb
->EchoCount
);
738 put_bcc(1, &smb
->hdr
);
740 inc_rfc1001_len(smb
, 3);
742 iov
.iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4;
744 rc
= cifs_call_async(server
, &rqst
, NULL
, cifs_echo_callback
,
745 server
, CIFS_ASYNC_OP
| CIFS_ECHO_OP
);
747 cifs_dbg(FYI
, "Echo request failed: %d\n", rc
);
749 cifs_small_buf_release(smb
);
755 CIFSSMBLogoff(const unsigned int xid
, struct cifs_ses
*ses
)
757 LOGOFF_ANDX_REQ
*pSMB
;
760 cifs_dbg(FYI
, "In SMBLogoff for session disconnect\n");
763 * BB: do we need to check validity of ses and server? They should
764 * always be valid since we have an active reference. If not, that
765 * should probably be a BUG()
767 if (!ses
|| !ses
->server
)
770 mutex_lock(&ses
->session_mutex
);
771 if (ses
->need_reconnect
)
772 goto session_already_dead
; /* no need to send SMBlogoff if uid
773 already closed due to reconnect */
774 rc
= small_smb_init(SMB_COM_LOGOFF_ANDX
, 2, NULL
, (void **)&pSMB
);
776 mutex_unlock(&ses
->session_mutex
);
780 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
782 if (ses
->server
->sign
)
783 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
785 pSMB
->hdr
.Uid
= ses
->Suid
;
787 pSMB
->AndXCommand
= 0xFF;
788 rc
= SendReceiveNoRsp(xid
, ses
, (char *) pSMB
, 0);
789 session_already_dead
:
790 mutex_unlock(&ses
->session_mutex
);
792 /* if session dead then we do not need to do ulogoff,
793 since server closed smb session, no sense reporting
801 CIFSPOSIXDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
,
802 const char *fileName
, __u16 type
,
803 const struct nls_table
*nls_codepage
, int remap
)
805 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
806 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
807 struct unlink_psx_rq
*pRqD
;
810 int bytes_returned
= 0;
811 __u16 params
, param_offset
, offset
, byte_count
;
813 cifs_dbg(FYI
, "In POSIX delete\n");
815 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
820 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
822 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
823 PATH_MAX
, nls_codepage
, remap
);
824 name_len
++; /* trailing null */
826 } else { /* BB add path length overrun check */
827 name_len
= strnlen(fileName
, PATH_MAX
);
828 name_len
++; /* trailing null */
829 strncpy(pSMB
->FileName
, fileName
, name_len
);
832 params
= 6 + name_len
;
833 pSMB
->MaxParameterCount
= cpu_to_le16(2);
834 pSMB
->MaxDataCount
= 0; /* BB double check this with jra */
835 pSMB
->MaxSetupCount
= 0;
840 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
841 InformationLevel
) - 4;
842 offset
= param_offset
+ params
;
844 /* Setup pointer to Request Data (inode type) */
845 pRqD
= (struct unlink_psx_rq
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
846 pRqD
->type
= cpu_to_le16(type
);
847 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
848 pSMB
->DataOffset
= cpu_to_le16(offset
);
849 pSMB
->SetupCount
= 1;
851 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
852 byte_count
= 3 /* pad */ + params
+ sizeof(struct unlink_psx_rq
);
854 pSMB
->DataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
855 pSMB
->TotalDataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
856 pSMB
->ParameterCount
= cpu_to_le16(params
);
857 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
858 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_UNLINK
);
860 inc_rfc1001_len(pSMB
, byte_count
);
861 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
862 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
863 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
865 cifs_dbg(FYI
, "Posix delete returned %d\n", rc
);
866 cifs_buf_release(pSMB
);
868 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
877 CIFSSMBDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
878 struct cifs_sb_info
*cifs_sb
)
880 DELETE_FILE_REQ
*pSMB
= NULL
;
881 DELETE_FILE_RSP
*pSMBr
= NULL
;
885 int remap
= cifs_remap(cifs_sb
);
888 rc
= smb_init(SMB_COM_DELETE
, 1, tcon
, (void **) &pSMB
,
893 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
894 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->fileName
, name
,
895 PATH_MAX
, cifs_sb
->local_nls
,
897 name_len
++; /* trailing null */
899 } else { /* BB improve check for buffer overruns BB */
900 name_len
= strnlen(name
, PATH_MAX
);
901 name_len
++; /* trailing null */
902 strncpy(pSMB
->fileName
, name
, name_len
);
904 pSMB
->SearchAttributes
=
905 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
);
906 pSMB
->BufferFormat
= 0x04;
907 inc_rfc1001_len(pSMB
, name_len
+ 1);
908 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
909 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
910 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
911 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
913 cifs_dbg(FYI
, "Error in RMFile = %d\n", rc
);
915 cifs_buf_release(pSMB
);
923 CIFSSMBRmDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
924 struct cifs_sb_info
*cifs_sb
)
926 DELETE_DIRECTORY_REQ
*pSMB
= NULL
;
927 DELETE_DIRECTORY_RSP
*pSMBr
= NULL
;
931 int remap
= cifs_remap(cifs_sb
);
933 cifs_dbg(FYI
, "In CIFSSMBRmDir\n");
935 rc
= smb_init(SMB_COM_DELETE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
940 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
941 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
942 PATH_MAX
, cifs_sb
->local_nls
,
944 name_len
++; /* trailing null */
946 } else { /* BB improve check for buffer overruns BB */
947 name_len
= strnlen(name
, PATH_MAX
);
948 name_len
++; /* trailing null */
949 strncpy(pSMB
->DirName
, name
, name_len
);
952 pSMB
->BufferFormat
= 0x04;
953 inc_rfc1001_len(pSMB
, name_len
+ 1);
954 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
955 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
956 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
957 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_rmdirs
);
959 cifs_dbg(FYI
, "Error in RMDir = %d\n", rc
);
961 cifs_buf_release(pSMB
);
968 CIFSSMBMkDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
969 struct cifs_sb_info
*cifs_sb
)
972 CREATE_DIRECTORY_REQ
*pSMB
= NULL
;
973 CREATE_DIRECTORY_RSP
*pSMBr
= NULL
;
976 int remap
= cifs_remap(cifs_sb
);
978 cifs_dbg(FYI
, "In CIFSSMBMkDir\n");
980 rc
= smb_init(SMB_COM_CREATE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
985 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
986 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
987 PATH_MAX
, cifs_sb
->local_nls
,
989 name_len
++; /* trailing null */
991 } else { /* BB improve check for buffer overruns BB */
992 name_len
= strnlen(name
, PATH_MAX
);
993 name_len
++; /* trailing null */
994 strncpy(pSMB
->DirName
, name
, name_len
);
997 pSMB
->BufferFormat
= 0x04;
998 inc_rfc1001_len(pSMB
, name_len
+ 1);
999 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1000 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1001 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1002 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_mkdirs
);
1004 cifs_dbg(FYI
, "Error in Mkdir = %d\n", rc
);
1006 cifs_buf_release(pSMB
);
1013 CIFSPOSIXCreate(const unsigned int xid
, struct cifs_tcon
*tcon
,
1014 __u32 posix_flags
, __u64 mode
, __u16
*netfid
,
1015 FILE_UNIX_BASIC_INFO
*pRetData
, __u32
*pOplock
,
1016 const char *name
, const struct nls_table
*nls_codepage
,
1019 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
1020 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
1023 int bytes_returned
= 0;
1024 __u16 params
, param_offset
, offset
, byte_count
, count
;
1025 OPEN_PSX_REQ
*pdata
;
1026 OPEN_PSX_RSP
*psx_rsp
;
1028 cifs_dbg(FYI
, "In POSIX Create\n");
1030 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1035 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1037 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, name
,
1038 PATH_MAX
, nls_codepage
, remap
);
1039 name_len
++; /* trailing null */
1041 } else { /* BB improve the check for buffer overruns BB */
1042 name_len
= strnlen(name
, PATH_MAX
);
1043 name_len
++; /* trailing null */
1044 strncpy(pSMB
->FileName
, name
, name_len
);
1047 params
= 6 + name_len
;
1048 count
= sizeof(OPEN_PSX_REQ
);
1049 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1050 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* large enough */
1051 pSMB
->MaxSetupCount
= 0;
1055 pSMB
->Reserved2
= 0;
1056 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
1057 InformationLevel
) - 4;
1058 offset
= param_offset
+ params
;
1059 pdata
= (OPEN_PSX_REQ
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
1060 pdata
->Level
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
1061 pdata
->Permissions
= cpu_to_le64(mode
);
1062 pdata
->PosixOpenFlags
= cpu_to_le32(posix_flags
);
1063 pdata
->OpenFlags
= cpu_to_le32(*pOplock
);
1064 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
1065 pSMB
->DataOffset
= cpu_to_le16(offset
);
1066 pSMB
->SetupCount
= 1;
1067 pSMB
->Reserved3
= 0;
1068 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
1069 byte_count
= 3 /* pad */ + params
+ count
;
1071 pSMB
->DataCount
= cpu_to_le16(count
);
1072 pSMB
->ParameterCount
= cpu_to_le16(params
);
1073 pSMB
->TotalDataCount
= pSMB
->DataCount
;
1074 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1075 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_OPEN
);
1076 pSMB
->Reserved4
= 0;
1077 inc_rfc1001_len(pSMB
, byte_count
);
1078 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1079 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1080 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1082 cifs_dbg(FYI
, "Posix create returned %d\n", rc
);
1083 goto psx_create_err
;
1086 cifs_dbg(FYI
, "copying inode info\n");
1087 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
1089 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)) {
1090 rc
= -EIO
; /* bad smb */
1091 goto psx_create_err
;
1094 /* copy return information to pRetData */
1095 psx_rsp
= (OPEN_PSX_RSP
*)((char *) &pSMBr
->hdr
.Protocol
1096 + le16_to_cpu(pSMBr
->t2
.DataOffset
));
1098 *pOplock
= le16_to_cpu(psx_rsp
->OplockFlags
);
1100 *netfid
= psx_rsp
->Fid
; /* cifs fid stays in le */
1101 /* Let caller know file was created so we can set the mode. */
1102 /* Do we care about the CreateAction in any other cases? */
1103 if (cpu_to_le32(FILE_CREATE
) == psx_rsp
->CreateAction
)
1104 *pOplock
|= CIFS_CREATE_ACTION
;
1105 /* check to make sure response data is there */
1106 if (psx_rsp
->ReturnedLevel
!= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
)) {
1107 pRetData
->Type
= cpu_to_le32(-1); /* unknown */
1108 cifs_dbg(NOISY
, "unknown type\n");
1110 if (get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)
1111 + sizeof(FILE_UNIX_BASIC_INFO
)) {
1112 cifs_dbg(VFS
, "Open response data too small\n");
1113 pRetData
->Type
= cpu_to_le32(-1);
1114 goto psx_create_err
;
1116 memcpy((char *) pRetData
,
1117 (char *)psx_rsp
+ sizeof(OPEN_PSX_RSP
),
1118 sizeof(FILE_UNIX_BASIC_INFO
));
1122 cifs_buf_release(pSMB
);
1124 if (posix_flags
& SMB_O_DIRECTORY
)
1125 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixmkdirs
);
1127 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixopens
);
1135 static __u16
convert_disposition(int disposition
)
1139 switch (disposition
) {
1140 case FILE_SUPERSEDE
:
1141 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1144 ofun
= SMBOPEN_OAPPEND
;
1147 ofun
= SMBOPEN_OCREATE
;
1150 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OAPPEND
;
1152 case FILE_OVERWRITE
:
1153 ofun
= SMBOPEN_OTRUNC
;
1155 case FILE_OVERWRITE_IF
:
1156 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1159 cifs_dbg(FYI
, "unknown disposition %d\n", disposition
);
1160 ofun
= SMBOPEN_OAPPEND
; /* regular open */
1166 access_flags_to_smbopen_mode(const int access_flags
)
1168 int masked_flags
= access_flags
& (GENERIC_READ
| GENERIC_WRITE
);
1170 if (masked_flags
== GENERIC_READ
)
1171 return SMBOPEN_READ
;
1172 else if (masked_flags
== GENERIC_WRITE
)
1173 return SMBOPEN_WRITE
;
1175 /* just go for read/write */
1176 return SMBOPEN_READWRITE
;
1180 SMBLegacyOpen(const unsigned int xid
, struct cifs_tcon
*tcon
,
1181 const char *fileName
, const int openDisposition
,
1182 const int access_flags
, const int create_options
, __u16
*netfid
,
1183 int *pOplock
, FILE_ALL_INFO
*pfile_info
,
1184 const struct nls_table
*nls_codepage
, int remap
)
1187 OPENX_REQ
*pSMB
= NULL
;
1188 OPENX_RSP
*pSMBr
= NULL
;
1194 rc
= smb_init(SMB_COM_OPEN_ANDX
, 15, tcon
, (void **) &pSMB
,
1199 pSMB
->AndXCommand
= 0xFF; /* none */
1201 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1202 count
= 1; /* account for one byte pad to word boundary */
1204 cifsConvertToUTF16((__le16
*) (pSMB
->fileName
+ 1),
1205 fileName
, PATH_MAX
, nls_codepage
, remap
);
1206 name_len
++; /* trailing null */
1208 } else { /* BB improve check for buffer overruns BB */
1209 count
= 0; /* no pad */
1210 name_len
= strnlen(fileName
, PATH_MAX
);
1211 name_len
++; /* trailing null */
1212 strncpy(pSMB
->fileName
, fileName
, name_len
);
1214 if (*pOplock
& REQ_OPLOCK
)
1215 pSMB
->OpenFlags
= cpu_to_le16(REQ_OPLOCK
);
1216 else if (*pOplock
& REQ_BATCHOPLOCK
)
1217 pSMB
->OpenFlags
= cpu_to_le16(REQ_BATCHOPLOCK
);
1219 pSMB
->OpenFlags
|= cpu_to_le16(REQ_MORE_INFO
);
1220 pSMB
->Mode
= cpu_to_le16(access_flags_to_smbopen_mode(access_flags
));
1221 pSMB
->Mode
|= cpu_to_le16(0x40); /* deny none */
1222 /* set file as system file if special file such
1223 as fifo and server expecting SFU style and
1224 no Unix extensions */
1226 if (create_options
& CREATE_OPTION_SPECIAL
)
1227 pSMB
->FileAttributes
= cpu_to_le16(ATTR_SYSTEM
);
1228 else /* BB FIXME BB */
1229 pSMB
->FileAttributes
= cpu_to_le16(0/*ATTR_NORMAL*/);
1231 if (create_options
& CREATE_OPTION_READONLY
)
1232 pSMB
->FileAttributes
|= cpu_to_le16(ATTR_READONLY
);
1235 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1236 CREATE_OPTIONS_MASK); */
1237 /* BB FIXME END BB */
1239 pSMB
->Sattr
= cpu_to_le16(ATTR_HIDDEN
| ATTR_SYSTEM
| ATTR_DIRECTORY
);
1240 pSMB
->OpenFunction
= cpu_to_le16(convert_disposition(openDisposition
));
1242 inc_rfc1001_len(pSMB
, count
);
1244 pSMB
->ByteCount
= cpu_to_le16(count
);
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 CIFS_open(const unsigned int xid
, struct cifs_open_parms
*oparms
, int *oplock
,
1290 OPEN_REQ
*req
= NULL
;
1291 OPEN_RSP
*rsp
= NULL
;
1295 struct cifs_sb_info
*cifs_sb
= oparms
->cifs_sb
;
1296 struct cifs_tcon
*tcon
= oparms
->tcon
;
1297 int remap
= cifs_remap(cifs_sb
);
1298 const struct nls_table
*nls
= cifs_sb
->local_nls
;
1299 int create_options
= oparms
->create_options
;
1300 int desired_access
= oparms
->desired_access
;
1301 int disposition
= oparms
->disposition
;
1302 const char *path
= oparms
->path
;
1305 rc
= smb_init(SMB_COM_NT_CREATE_ANDX
, 24, tcon
, (void **)&req
,
1310 /* no commands go after this */
1311 req
->AndXCommand
= 0xFF;
1313 if (req
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1314 /* account for one byte pad to word boundary */
1316 name_len
= cifsConvertToUTF16((__le16
*)(req
->fileName
+ 1),
1317 path
, PATH_MAX
, nls
, remap
);
1321 req
->NameLength
= cpu_to_le16(name_len
);
1323 /* BB improve check for buffer overruns BB */
1326 name_len
= strnlen(path
, PATH_MAX
);
1329 req
->NameLength
= cpu_to_le16(name_len
);
1330 strncpy(req
->fileName
, path
, name_len
);
1333 if (*oplock
& REQ_OPLOCK
)
1334 req
->OpenFlags
= cpu_to_le32(REQ_OPLOCK
);
1335 else if (*oplock
& REQ_BATCHOPLOCK
)
1336 req
->OpenFlags
= cpu_to_le32(REQ_BATCHOPLOCK
);
1338 req
->DesiredAccess
= cpu_to_le32(desired_access
);
1339 req
->AllocationSize
= 0;
1342 * Set file as system file if special file such as fifo and server
1343 * expecting SFU style and no Unix extensions.
1345 if (create_options
& CREATE_OPTION_SPECIAL
)
1346 req
->FileAttributes
= cpu_to_le32(ATTR_SYSTEM
);
1348 req
->FileAttributes
= cpu_to_le32(ATTR_NORMAL
);
1351 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1352 * sensitive checks for other servers such as Samba.
1354 if (tcon
->ses
->capabilities
& CAP_UNIX
)
1355 req
->FileAttributes
|= cpu_to_le32(ATTR_POSIX_SEMANTICS
);
1357 if (create_options
& CREATE_OPTION_READONLY
)
1358 req
->FileAttributes
|= cpu_to_le32(ATTR_READONLY
);
1360 req
->ShareAccess
= cpu_to_le32(FILE_SHARE_ALL
);
1361 req
->CreateDisposition
= cpu_to_le32(disposition
);
1362 req
->CreateOptions
= cpu_to_le32(create_options
& CREATE_OPTIONS_MASK
);
1364 /* BB Expirement with various impersonation levels and verify */
1365 req
->ImpersonationLevel
= cpu_to_le32(SECURITY_IMPERSONATION
);
1366 req
->SecurityFlags
= SECURITY_CONTEXT_TRACKING
|SECURITY_EFFECTIVE_ONLY
;
1369 inc_rfc1001_len(req
, count
);
1371 req
->ByteCount
= cpu_to_le16(count
);
1372 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*)req
,
1373 (struct smb_hdr
*)rsp
, &bytes_returned
, 0);
1374 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1376 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1377 cifs_buf_release(req
);
1383 /* 1 byte no need to le_to_cpu */
1384 *oplock
= rsp
->OplockLevel
;
1385 /* cifs fid stays in le */
1386 oparms
->fid
->netfid
= rsp
->Fid
;
1388 /* Let caller know file was created so we can set the mode. */
1389 /* Do we care about the CreateAction in any other cases? */
1390 if (cpu_to_le32(FILE_CREATE
) == rsp
->CreateAction
)
1391 *oplock
|= CIFS_CREATE_ACTION
;
1394 /* copy from CreationTime to Attributes */
1395 memcpy((char *)buf
, (char *)&rsp
->CreationTime
, 36);
1396 /* the file_info buf is endian converted by caller */
1397 buf
->AllocationSize
= rsp
->AllocationSize
;
1398 buf
->EndOfFile
= rsp
->EndOfFile
;
1399 buf
->NumberOfLinks
= cpu_to_le32(1);
1400 buf
->DeletePending
= 0;
1403 cifs_buf_release(req
);
1408 * Discard any remaining data in the current SMB. To do this, we borrow the
1412 discard_remaining_data(struct TCP_Server_Info
*server
)
1414 unsigned int rfclen
= get_rfc1002_length(server
->smallbuf
);
1415 int remaining
= rfclen
+ 4 - server
->total_read
;
1417 while (remaining
> 0) {
1420 length
= cifs_read_from_socket(server
, server
->bigbuf
,
1421 min_t(unsigned int, remaining
,
1422 CIFSMaxBufSize
+ MAX_HEADER_SIZE(server
)));
1425 server
->total_read
+= length
;
1426 remaining
-= length
;
1433 cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1436 struct cifs_readdata
*rdata
= mid
->callback_data
;
1438 length
= discard_remaining_data(server
);
1439 dequeue_mid(mid
, rdata
->result
);
1440 mid
->resp_buf
= server
->smallbuf
;
1441 server
->smallbuf
= NULL
;
1446 cifs_readv_receive(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1449 unsigned int data_offset
, data_len
;
1450 struct cifs_readdata
*rdata
= mid
->callback_data
;
1451 char *buf
= server
->smallbuf
;
1452 unsigned int buflen
= get_rfc1002_length(buf
) + 4;
1454 cifs_dbg(FYI
, "%s: mid=%llu offset=%llu bytes=%u\n",
1455 __func__
, mid
->mid
, rdata
->offset
, rdata
->bytes
);
1458 * read the rest of READ_RSP header (sans Data array), or whatever we
1459 * can if there's not enough data. At this point, we've read down to
1462 len
= min_t(unsigned int, buflen
, server
->vals
->read_rsp_size
) -
1463 HEADER_SIZE(server
) + 1;
1465 length
= cifs_read_from_socket(server
,
1466 buf
+ HEADER_SIZE(server
) - 1, len
);
1469 server
->total_read
+= length
;
1471 if (server
->ops
->is_session_expired
&&
1472 server
->ops
->is_session_expired(buf
)) {
1473 cifs_reconnect(server
);
1474 wake_up(&server
->response_q
);
1478 if (server
->ops
->is_status_pending
&&
1479 server
->ops
->is_status_pending(buf
, server
, 0)) {
1480 discard_remaining_data(server
);
1484 /* Was the SMB read successful? */
1485 rdata
->result
= server
->ops
->map_error(buf
, false);
1486 if (rdata
->result
!= 0) {
1487 cifs_dbg(FYI
, "%s: server returned error %d\n",
1488 __func__
, rdata
->result
);
1489 return cifs_readv_discard(server
, mid
);
1492 /* Is there enough to get to the rest of the READ_RSP header? */
1493 if (server
->total_read
< server
->vals
->read_rsp_size
) {
1494 cifs_dbg(FYI
, "%s: server returned short header. got=%u expected=%zu\n",
1495 __func__
, server
->total_read
,
1496 server
->vals
->read_rsp_size
);
1497 rdata
->result
= -EIO
;
1498 return cifs_readv_discard(server
, mid
);
1501 data_offset
= server
->ops
->read_data_offset(buf
) + 4;
1502 if (data_offset
< server
->total_read
) {
1504 * win2k8 sometimes sends an offset of 0 when the read
1505 * is beyond the EOF. Treat it as if the data starts just after
1508 cifs_dbg(FYI
, "%s: data offset (%u) inside read response header\n",
1509 __func__
, data_offset
);
1510 data_offset
= server
->total_read
;
1511 } else if (data_offset
> MAX_CIFS_SMALL_BUFFER_SIZE
) {
1512 /* data_offset is beyond the end of smallbuf */
1513 cifs_dbg(FYI
, "%s: data offset (%u) beyond end of smallbuf\n",
1514 __func__
, data_offset
);
1515 rdata
->result
= -EIO
;
1516 return cifs_readv_discard(server
, mid
);
1519 cifs_dbg(FYI
, "%s: total_read=%u data_offset=%u\n",
1520 __func__
, server
->total_read
, data_offset
);
1522 len
= data_offset
- server
->total_read
;
1524 /* read any junk before data into the rest of smallbuf */
1525 length
= cifs_read_from_socket(server
,
1526 buf
+ server
->total_read
, len
);
1529 server
->total_read
+= length
;
1532 /* set up first iov for signature check */
1533 rdata
->iov
.iov_base
= buf
;
1534 rdata
->iov
.iov_len
= server
->total_read
;
1535 cifs_dbg(FYI
, "0: iov_base=%p iov_len=%zu\n",
1536 rdata
->iov
.iov_base
, rdata
->iov
.iov_len
);
1538 /* how much data is in the response? */
1539 data_len
= server
->ops
->read_data_length(buf
);
1540 if (data_offset
+ data_len
> buflen
) {
1541 /* data_len is corrupt -- discard frame */
1542 rdata
->result
= -EIO
;
1543 return cifs_readv_discard(server
, mid
);
1546 length
= rdata
->read_into_pages(server
, rdata
, data_len
);
1550 server
->total_read
+= length
;
1552 cifs_dbg(FYI
, "total_read=%u buflen=%u remaining=%u\n",
1553 server
->total_read
, buflen
, data_len
);
1555 /* discard anything left over */
1556 if (server
->total_read
< buflen
)
1557 return cifs_readv_discard(server
, mid
);
1559 dequeue_mid(mid
, false);
1560 mid
->resp_buf
= server
->smallbuf
;
1561 server
->smallbuf
= NULL
;
1566 cifs_readv_callback(struct mid_q_entry
*mid
)
1568 struct cifs_readdata
*rdata
= mid
->callback_data
;
1569 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1570 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
1571 struct smb_rqst rqst
= { .rq_iov
= &rdata
->iov
,
1573 .rq_pages
= rdata
->pages
,
1574 .rq_npages
= rdata
->nr_pages
,
1575 .rq_pagesz
= rdata
->pagesz
,
1576 .rq_tailsz
= rdata
->tailsz
};
1578 cifs_dbg(FYI
, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1579 __func__
, mid
->mid
, mid
->mid_state
, rdata
->result
,
1582 switch (mid
->mid_state
) {
1583 case MID_RESPONSE_RECEIVED
:
1584 /* result already set, check signature */
1588 rc
= cifs_verify_signature(&rqst
, server
,
1589 mid
->sequence_number
);
1591 cifs_dbg(VFS
, "SMB signature verification returned error = %d\n",
1594 /* FIXME: should this be counted toward the initiating task? */
1595 task_io_account_read(rdata
->got_bytes
);
1596 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1598 case MID_REQUEST_SUBMITTED
:
1599 case MID_RETRY_NEEDED
:
1600 rdata
->result
= -EAGAIN
;
1601 if (server
->sign
&& rdata
->got_bytes
)
1602 /* reset bytes number since we can not check a sign */
1603 rdata
->got_bytes
= 0;
1604 /* FIXME: should this be counted toward the initiating task? */
1605 task_io_account_read(rdata
->got_bytes
);
1606 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1609 rdata
->result
= -EIO
;
1612 queue_work(cifsiod_wq
, &rdata
->work
);
1613 mutex_lock(&server
->srv_mutex
);
1614 DeleteMidQEntry(mid
);
1615 mutex_unlock(&server
->srv_mutex
);
1616 add_credits(server
, 1, 0);
1619 /* cifs_async_readv - send an async write, and set up mid to handle result */
1621 cifs_async_readv(struct cifs_readdata
*rdata
)
1624 READ_REQ
*smb
= NULL
;
1626 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1627 struct smb_rqst rqst
= { .rq_iov
= &rdata
->iov
,
1630 cifs_dbg(FYI
, "%s: offset=%llu bytes=%u\n",
1631 __func__
, rdata
->offset
, rdata
->bytes
);
1633 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1636 wct
= 10; /* old style read */
1637 if ((rdata
->offset
>> 32) > 0) {
1638 /* can not handle this big offset for old */
1643 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **)&smb
);
1647 smb
->hdr
.Pid
= cpu_to_le16((__u16
)rdata
->pid
);
1648 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(rdata
->pid
>> 16));
1650 smb
->AndXCommand
= 0xFF; /* none */
1651 smb
->Fid
= rdata
->cfile
->fid
.netfid
;
1652 smb
->OffsetLow
= cpu_to_le32(rdata
->offset
& 0xFFFFFFFF);
1654 smb
->OffsetHigh
= cpu_to_le32(rdata
->offset
>> 32);
1656 smb
->MaxCount
= cpu_to_le16(rdata
->bytes
& 0xFFFF);
1657 smb
->MaxCountHigh
= cpu_to_le32(rdata
->bytes
>> 16);
1661 /* old style read */
1662 struct smb_com_readx_req
*smbr
=
1663 (struct smb_com_readx_req
*)smb
;
1664 smbr
->ByteCount
= 0;
1667 /* 4 for RFC1001 length + 1 for BCC */
1668 rdata
->iov
.iov_base
= smb
;
1669 rdata
->iov
.iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4;
1671 kref_get(&rdata
->refcount
);
1672 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, cifs_readv_receive
,
1673 cifs_readv_callback
, rdata
, 0);
1676 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1678 kref_put(&rdata
->refcount
, cifs_readdata_release
);
1680 cifs_small_buf_release(smb
);
1685 CIFSSMBRead(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1686 unsigned int *nbytes
, char **buf
, int *pbuf_type
)
1689 READ_REQ
*pSMB
= NULL
;
1690 READ_RSP
*pSMBr
= NULL
;
1691 char *pReadData
= NULL
;
1693 int resp_buf_type
= 0;
1695 __u32 pid
= io_parms
->pid
;
1696 __u16 netfid
= io_parms
->netfid
;
1697 __u64 offset
= io_parms
->offset
;
1698 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1699 unsigned int count
= io_parms
->length
;
1701 cifs_dbg(FYI
, "Reading %d bytes on fid %d\n", count
, netfid
);
1702 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1705 wct
= 10; /* old style read */
1706 if ((offset
>> 32) > 0) {
1707 /* can not handle this big offset for old */
1713 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **) &pSMB
);
1717 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1718 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1720 /* tcon and ses pointer are checked in smb_init */
1721 if (tcon
->ses
->server
== NULL
)
1722 return -ECONNABORTED
;
1724 pSMB
->AndXCommand
= 0xFF; /* none */
1726 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1728 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1730 pSMB
->Remaining
= 0;
1731 pSMB
->MaxCount
= cpu_to_le16(count
& 0xFFFF);
1732 pSMB
->MaxCountHigh
= cpu_to_le32(count
>> 16);
1734 pSMB
->ByteCount
= 0; /* no need to do le conversion since 0 */
1736 /* old style read */
1737 struct smb_com_readx_req
*pSMBW
=
1738 (struct smb_com_readx_req
*)pSMB
;
1739 pSMBW
->ByteCount
= 0;
1742 iov
[0].iov_base
= (char *)pSMB
;
1743 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
1744 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
1745 &resp_buf_type
, CIFS_LOG_ERROR
);
1746 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1747 pSMBr
= (READ_RSP
*)iov
[0].iov_base
;
1749 cifs_dbg(VFS
, "Send error in read = %d\n", rc
);
1751 int data_length
= le16_to_cpu(pSMBr
->DataLengthHigh
);
1752 data_length
= data_length
<< 16;
1753 data_length
+= le16_to_cpu(pSMBr
->DataLength
);
1754 *nbytes
= data_length
;
1756 /*check that DataLength would not go beyond end of SMB */
1757 if ((data_length
> CIFSMaxBufSize
)
1758 || (data_length
> count
)) {
1759 cifs_dbg(FYI
, "bad length %d for count %d\n",
1760 data_length
, count
);
1764 pReadData
= (char *) (&pSMBr
->hdr
.Protocol
) +
1765 le16_to_cpu(pSMBr
->DataOffset
);
1766 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1767 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1769 }*/ /* can not use copy_to_user when using page cache*/
1771 memcpy(*buf
, pReadData
, data_length
);
1775 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1777 free_rsp_buf(resp_buf_type
, iov
[0].iov_base
);
1778 } else if (resp_buf_type
!= CIFS_NO_BUFFER
) {
1779 /* return buffer to caller to free */
1780 *buf
= iov
[0].iov_base
;
1781 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1782 *pbuf_type
= CIFS_SMALL_BUFFER
;
1783 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1784 *pbuf_type
= CIFS_LARGE_BUFFER
;
1785 } /* else no valid buffer on return - leave as null */
1787 /* Note: On -EAGAIN error only caller can retry on handle based calls
1788 since file handle passed in no longer valid */
1794 CIFSSMBWrite(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1795 unsigned int *nbytes
, const char *buf
)
1798 WRITE_REQ
*pSMB
= NULL
;
1799 WRITE_RSP
*pSMBr
= NULL
;
1800 int bytes_returned
, wct
;
1803 __u32 pid
= io_parms
->pid
;
1804 __u16 netfid
= io_parms
->netfid
;
1805 __u64 offset
= io_parms
->offset
;
1806 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1807 unsigned int count
= io_parms
->length
;
1811 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1812 if (tcon
->ses
== NULL
)
1813 return -ECONNABORTED
;
1815 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1819 if ((offset
>> 32) > 0) {
1820 /* can not handle big offset for old srv */
1825 rc
= smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
,
1830 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1831 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1833 /* tcon and ses pointer are checked in smb_init */
1834 if (tcon
->ses
->server
== NULL
)
1835 return -ECONNABORTED
;
1837 pSMB
->AndXCommand
= 0xFF; /* none */
1839 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1841 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1843 pSMB
->Reserved
= 0xFFFFFFFF;
1844 pSMB
->WriteMode
= 0;
1845 pSMB
->Remaining
= 0;
1847 /* Can increase buffer size if buffer is big enough in some cases ie we
1848 can send more if LARGE_WRITE_X capability returned by the server and if
1849 our buffer is big enough or if we convert to iovecs on socket writes
1850 and eliminate the copy to the CIFS buffer */
1851 if (tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
) {
1852 bytes_sent
= min_t(const unsigned int, CIFSMaxBufSize
, count
);
1854 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
)
1858 if (bytes_sent
> count
)
1861 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1863 memcpy(pSMB
->Data
, buf
, bytes_sent
);
1864 else if (count
!= 0) {
1866 cifs_buf_release(pSMB
);
1868 } /* else setting file size with write of zero bytes */
1870 byte_count
= bytes_sent
+ 1; /* pad */
1871 else /* wct == 12 */
1872 byte_count
= bytes_sent
+ 5; /* bigger pad, smaller smb hdr */
1874 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
& 0xFFFF);
1875 pSMB
->DataLengthHigh
= cpu_to_le16(bytes_sent
>> 16);
1876 inc_rfc1001_len(pSMB
, byte_count
);
1879 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1880 else { /* old style write has byte count 4 bytes earlier
1882 struct smb_com_writex_req
*pSMBW
=
1883 (struct smb_com_writex_req
*)pSMB
;
1884 pSMBW
->ByteCount
= cpu_to_le16(byte_count
);
1887 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1888 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1889 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
1891 cifs_dbg(FYI
, "Send error in write = %d\n", rc
);
1893 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
1894 *nbytes
= (*nbytes
) << 16;
1895 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
1898 * Mask off high 16 bits when bytes written as returned by the
1899 * server is greater than bytes requested by the client. Some
1900 * OS/2 servers are known to set incorrect CountHigh values.
1902 if (*nbytes
> count
)
1906 cifs_buf_release(pSMB
);
1908 /* Note: On -EAGAIN error only caller can retry on handle based calls
1909 since file handle passed in no longer valid */
1915 cifs_writedata_release(struct kref
*refcount
)
1917 struct cifs_writedata
*wdata
= container_of(refcount
,
1918 struct cifs_writedata
, refcount
);
1921 cifsFileInfo_put(wdata
->cfile
);
1927 * Write failed with a retryable error. Resend the write request. It's also
1928 * possible that the page was redirtied so re-clean the page.
1931 cifs_writev_requeue(struct cifs_writedata
*wdata
)
1934 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
1935 struct TCP_Server_Info
*server
;
1936 unsigned int rest_len
;
1938 server
= tlink_tcon(wdata
->cfile
->tlink
)->ses
->server
;
1940 rest_len
= wdata
->bytes
;
1942 struct cifs_writedata
*wdata2
;
1943 unsigned int j
, nr_pages
, wsize
, tailsz
, cur_len
;
1945 wsize
= server
->ops
->wp_retry_size(inode
);
1946 if (wsize
< rest_len
) {
1947 nr_pages
= wsize
/ PAGE_SIZE
;
1952 cur_len
= nr_pages
* PAGE_SIZE
;
1955 nr_pages
= DIV_ROUND_UP(rest_len
, PAGE_SIZE
);
1957 tailsz
= rest_len
- (nr_pages
- 1) * PAGE_SIZE
;
1960 wdata2
= cifs_writedata_alloc(nr_pages
, cifs_writev_complete
);
1966 for (j
= 0; j
< nr_pages
; j
++) {
1967 wdata2
->pages
[j
] = wdata
->pages
[i
+ j
];
1968 lock_page(wdata2
->pages
[j
]);
1969 clear_page_dirty_for_io(wdata2
->pages
[j
]);
1972 wdata2
->sync_mode
= wdata
->sync_mode
;
1973 wdata2
->nr_pages
= nr_pages
;
1974 wdata2
->offset
= page_offset(wdata2
->pages
[0]);
1975 wdata2
->pagesz
= PAGE_SIZE
;
1976 wdata2
->tailsz
= tailsz
;
1977 wdata2
->bytes
= cur_len
;
1979 wdata2
->cfile
= find_writable_file(CIFS_I(inode
), false);
1980 if (!wdata2
->cfile
) {
1981 cifs_dbg(VFS
, "No writable handles for inode\n");
1985 wdata2
->pid
= wdata2
->cfile
->pid
;
1986 rc
= server
->ops
->async_writev(wdata2
, cifs_writedata_release
);
1988 for (j
= 0; j
< nr_pages
; j
++) {
1989 unlock_page(wdata2
->pages
[j
]);
1990 if (rc
!= 0 && rc
!= -EAGAIN
) {
1991 SetPageError(wdata2
->pages
[j
]);
1992 end_page_writeback(wdata2
->pages
[j
]);
1993 put_page(wdata2
->pages
[j
]);
1998 kref_put(&wdata2
->refcount
, cifs_writedata_release
);
2004 rest_len
-= cur_len
;
2006 } while (i
< wdata
->nr_pages
);
2008 mapping_set_error(inode
->i_mapping
, rc
);
2009 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2013 cifs_writev_complete(struct work_struct
*work
)
2015 struct cifs_writedata
*wdata
= container_of(work
,
2016 struct cifs_writedata
, work
);
2017 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
2020 if (wdata
->result
== 0) {
2021 spin_lock(&inode
->i_lock
);
2022 cifs_update_eof(CIFS_I(inode
), wdata
->offset
, wdata
->bytes
);
2023 spin_unlock(&inode
->i_lock
);
2024 cifs_stats_bytes_written(tlink_tcon(wdata
->cfile
->tlink
),
2026 } else if (wdata
->sync_mode
== WB_SYNC_ALL
&& wdata
->result
== -EAGAIN
)
2027 return cifs_writev_requeue(wdata
);
2029 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
2030 struct page
*page
= wdata
->pages
[i
];
2031 if (wdata
->result
== -EAGAIN
)
2032 __set_page_dirty_nobuffers(page
);
2033 else if (wdata
->result
< 0)
2035 end_page_writeback(page
);
2038 if (wdata
->result
!= -EAGAIN
)
2039 mapping_set_error(inode
->i_mapping
, wdata
->result
);
2040 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2043 struct cifs_writedata
*
2044 cifs_writedata_alloc(unsigned int nr_pages
, work_func_t complete
)
2046 struct cifs_writedata
*wdata
;
2048 /* writedata + number of page pointers */
2049 wdata
= kzalloc(sizeof(*wdata
) +
2050 sizeof(struct page
*) * nr_pages
, GFP_NOFS
);
2051 if (wdata
!= NULL
) {
2052 kref_init(&wdata
->refcount
);
2053 INIT_LIST_HEAD(&wdata
->list
);
2054 init_completion(&wdata
->done
);
2055 INIT_WORK(&wdata
->work
, complete
);
2061 * Check the mid_state and signature on received buffer (if any), and queue the
2062 * workqueue completion task.
2065 cifs_writev_callback(struct mid_q_entry
*mid
)
2067 struct cifs_writedata
*wdata
= mid
->callback_data
;
2068 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2069 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
2070 unsigned int written
;
2071 WRITE_RSP
*smb
= (WRITE_RSP
*)mid
->resp_buf
;
2073 switch (mid
->mid_state
) {
2074 case MID_RESPONSE_RECEIVED
:
2075 wdata
->result
= cifs_check_receive(mid
, tcon
->ses
->server
, 0);
2076 if (wdata
->result
!= 0)
2079 written
= le16_to_cpu(smb
->CountHigh
);
2081 written
+= le16_to_cpu(smb
->Count
);
2083 * Mask off high 16 bits when bytes written as returned
2084 * by the server is greater than bytes requested by the
2085 * client. OS/2 servers are known to set incorrect
2088 if (written
> wdata
->bytes
)
2091 if (written
< wdata
->bytes
)
2092 wdata
->result
= -ENOSPC
;
2094 wdata
->bytes
= written
;
2096 case MID_REQUEST_SUBMITTED
:
2097 case MID_RETRY_NEEDED
:
2098 wdata
->result
= -EAGAIN
;
2101 wdata
->result
= -EIO
;
2105 queue_work(cifsiod_wq
, &wdata
->work
);
2106 mutex_lock(&server
->srv_mutex
);
2107 DeleteMidQEntry(mid
);
2108 mutex_unlock(&server
->srv_mutex
);
2109 add_credits(tcon
->ses
->server
, 1, 0);
2112 /* cifs_async_writev - send an async write, and set up mid to handle result */
2114 cifs_async_writev(struct cifs_writedata
*wdata
,
2115 void (*release
)(struct kref
*kref
))
2118 WRITE_REQ
*smb
= NULL
;
2120 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2122 struct smb_rqst rqst
= { };
2124 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2128 if (wdata
->offset
>> 32 > 0) {
2129 /* can not handle big offset for old srv */
2134 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **)&smb
);
2136 goto async_writev_out
;
2138 smb
->hdr
.Pid
= cpu_to_le16((__u16
)wdata
->pid
);
2139 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(wdata
->pid
>> 16));
2141 smb
->AndXCommand
= 0xFF; /* none */
2142 smb
->Fid
= wdata
->cfile
->fid
.netfid
;
2143 smb
->OffsetLow
= cpu_to_le32(wdata
->offset
& 0xFFFFFFFF);
2145 smb
->OffsetHigh
= cpu_to_le32(wdata
->offset
>> 32);
2146 smb
->Reserved
= 0xFFFFFFFF;
2151 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2153 /* 4 for RFC1001 length + 1 for BCC */
2154 iov
.iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4 + 1;
2159 rqst
.rq_pages
= wdata
->pages
;
2160 rqst
.rq_npages
= wdata
->nr_pages
;
2161 rqst
.rq_pagesz
= wdata
->pagesz
;
2162 rqst
.rq_tailsz
= wdata
->tailsz
;
2164 cifs_dbg(FYI
, "async write at %llu %u bytes\n",
2165 wdata
->offset
, wdata
->bytes
);
2167 smb
->DataLengthLow
= cpu_to_le16(wdata
->bytes
& 0xFFFF);
2168 smb
->DataLengthHigh
= cpu_to_le16(wdata
->bytes
>> 16);
2171 inc_rfc1001_len(&smb
->hdr
, wdata
->bytes
+ 1);
2172 put_bcc(wdata
->bytes
+ 1, &smb
->hdr
);
2175 struct smb_com_writex_req
*smbw
=
2176 (struct smb_com_writex_req
*)smb
;
2177 inc_rfc1001_len(&smbw
->hdr
, wdata
->bytes
+ 5);
2178 put_bcc(wdata
->bytes
+ 5, &smbw
->hdr
);
2179 iov
.iov_len
+= 4; /* pad bigger by four bytes */
2182 kref_get(&wdata
->refcount
);
2183 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, NULL
,
2184 cifs_writev_callback
, wdata
, 0);
2187 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2189 kref_put(&wdata
->refcount
, release
);
2192 cifs_small_buf_release(smb
);
2197 CIFSSMBWrite2(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
2198 unsigned int *nbytes
, struct kvec
*iov
, int n_vec
)
2201 WRITE_REQ
*pSMB
= NULL
;
2204 int resp_buf_type
= 0;
2205 __u32 pid
= io_parms
->pid
;
2206 __u16 netfid
= io_parms
->netfid
;
2207 __u64 offset
= io_parms
->offset
;
2208 struct cifs_tcon
*tcon
= io_parms
->tcon
;
2209 unsigned int count
= io_parms
->length
;
2213 cifs_dbg(FYI
, "write2 at %lld %d bytes\n", (long long)offset
, count
);
2215 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2219 if ((offset
>> 32) > 0) {
2220 /* can not handle big offset for old srv */
2224 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
);
2228 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
2229 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
2231 /* tcon and ses pointer are checked in smb_init */
2232 if (tcon
->ses
->server
== NULL
)
2233 return -ECONNABORTED
;
2235 pSMB
->AndXCommand
= 0xFF; /* none */
2237 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
2239 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
2240 pSMB
->Reserved
= 0xFFFFFFFF;
2241 pSMB
->WriteMode
= 0;
2242 pSMB
->Remaining
= 0;
2245 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2247 pSMB
->DataLengthLow
= cpu_to_le16(count
& 0xFFFF);
2248 pSMB
->DataLengthHigh
= cpu_to_le16(count
>> 16);
2249 /* header + 1 byte pad */
2250 smb_hdr_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 1;
2252 inc_rfc1001_len(pSMB
, count
+ 1);
2253 else /* wct == 12 */
2254 inc_rfc1001_len(pSMB
, count
+ 5); /* smb data starts later */
2256 pSMB
->ByteCount
= cpu_to_le16(count
+ 1);
2257 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2258 struct smb_com_writex_req
*pSMBW
=
2259 (struct smb_com_writex_req
*)pSMB
;
2260 pSMBW
->ByteCount
= cpu_to_le16(count
+ 5);
2262 iov
[0].iov_base
= pSMB
;
2264 iov
[0].iov_len
= smb_hdr_len
+ 4;
2265 else /* wct == 12 pad bigger by four bytes */
2266 iov
[0].iov_len
= smb_hdr_len
+ 8;
2269 rc
= SendReceive2(xid
, tcon
->ses
, iov
, n_vec
+ 1, &resp_buf_type
, 0);
2270 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2272 cifs_dbg(FYI
, "Send error Write2 = %d\n", rc
);
2273 } else if (resp_buf_type
== 0) {
2274 /* presumably this can not happen, but best to be safe */
2277 WRITE_RSP
*pSMBr
= (WRITE_RSP
*)iov
[0].iov_base
;
2278 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2279 *nbytes
= (*nbytes
) << 16;
2280 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2283 * Mask off high 16 bits when bytes written as returned by the
2284 * server is greater than bytes requested by the client. OS/2
2285 * servers are known to set incorrect CountHigh values.
2287 if (*nbytes
> count
)
2291 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2292 free_rsp_buf(resp_buf_type
, iov
[0].iov_base
);
2294 /* Note: On -EAGAIN error only caller can retry on handle based calls
2295 since file handle passed in no longer valid */
2300 int cifs_lockv(const unsigned int xid
, struct cifs_tcon
*tcon
,
2301 const __u16 netfid
, const __u8 lock_type
, const __u32 num_unlock
,
2302 const __u32 num_lock
, LOCKING_ANDX_RANGE
*buf
)
2305 LOCK_REQ
*pSMB
= NULL
;
2310 cifs_dbg(FYI
, "cifs_lockv num lock %d num unlock %d\n",
2311 num_lock
, num_unlock
);
2313 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2318 pSMB
->NumberOfLocks
= cpu_to_le16(num_lock
);
2319 pSMB
->NumberOfUnlocks
= cpu_to_le16(num_unlock
);
2320 pSMB
->LockType
= lock_type
;
2321 pSMB
->AndXCommand
= 0xFF; /* none */
2322 pSMB
->Fid
= netfid
; /* netfid stays le */
2324 count
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2325 inc_rfc1001_len(pSMB
, count
);
2326 pSMB
->ByteCount
= cpu_to_le16(count
);
2328 iov
[0].iov_base
= (char *)pSMB
;
2329 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4 -
2330 (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2331 iov
[1].iov_base
= (char *)buf
;
2332 iov
[1].iov_len
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2334 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2335 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 2, &resp_buf_type
, CIFS_NO_RESP
);
2337 cifs_dbg(FYI
, "Send error in cifs_lockv = %d\n", rc
);
2343 CIFSSMBLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2344 const __u16 smb_file_id
, const __u32 netpid
, const __u64 len
,
2345 const __u64 offset
, const __u32 numUnlock
,
2346 const __u32 numLock
, const __u8 lockType
,
2347 const bool waitFlag
, const __u8 oplock_level
)
2350 LOCK_REQ
*pSMB
= NULL
;
2351 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2356 cifs_dbg(FYI
, "CIFSSMBLock timeout %d numLock %d\n",
2357 (int)waitFlag
, numLock
);
2358 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2363 if (lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
2364 /* no response expected */
2365 flags
= CIFS_ASYNC_OP
| CIFS_OBREAK_OP
;
2367 } else if (waitFlag
) {
2368 flags
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2369 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
2374 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
2375 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
2376 pSMB
->LockType
= lockType
;
2377 pSMB
->OplockLevel
= oplock_level
;
2378 pSMB
->AndXCommand
= 0xFF; /* none */
2379 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
2381 if ((numLock
!= 0) || (numUnlock
!= 0)) {
2382 pSMB
->Locks
[0].Pid
= cpu_to_le16(netpid
);
2383 /* BB where to store pid high? */
2384 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
2385 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
2386 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
2387 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
2388 count
= sizeof(LOCKING_ANDX_RANGE
);
2393 inc_rfc1001_len(pSMB
, count
);
2394 pSMB
->ByteCount
= cpu_to_le16(count
);
2397 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2398 (struct smb_hdr
*) pSMB
, &bytes_returned
);
2399 cifs_small_buf_release(pSMB
);
2401 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)pSMB
, flags
);
2402 /* SMB buffer freed by function above */
2404 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2406 cifs_dbg(FYI
, "Send error in Lock = %d\n", rc
);
2408 /* Note: On -EAGAIN error only caller can retry on handle based calls
2409 since file handle passed in no longer valid */
2414 CIFSSMBPosixLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2415 const __u16 smb_file_id
, const __u32 netpid
,
2416 const loff_t start_offset
, const __u64 len
,
2417 struct file_lock
*pLockData
, const __u16 lock_type
,
2418 const bool waitFlag
)
2420 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2421 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2422 struct cifs_posix_lock
*parm_data
;
2425 int bytes_returned
= 0;
2426 int resp_buf_type
= 0;
2427 __u16 params
, param_offset
, offset
, byte_count
, count
;
2430 cifs_dbg(FYI
, "Posix Lock\n");
2432 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
2437 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)pSMB
;
2440 pSMB
->MaxSetupCount
= 0;
2443 pSMB
->Reserved2
= 0;
2444 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2445 offset
= param_offset
+ params
;
2447 count
= sizeof(struct cifs_posix_lock
);
2448 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2449 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2450 pSMB
->SetupCount
= 1;
2451 pSMB
->Reserved3
= 0;
2453 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
2455 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2456 byte_count
= 3 /* pad */ + params
+ count
;
2457 pSMB
->DataCount
= cpu_to_le16(count
);
2458 pSMB
->ParameterCount
= cpu_to_le16(params
);
2459 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2460 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2461 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2462 parm_data
= (struct cifs_posix_lock
*)
2463 (((char *) &pSMB
->hdr
.Protocol
) + offset
);
2465 parm_data
->lock_type
= cpu_to_le16(lock_type
);
2467 timeout
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2468 parm_data
->lock_flags
= cpu_to_le16(1);
2469 pSMB
->Timeout
= cpu_to_le32(-1);
2473 parm_data
->pid
= cpu_to_le32(netpid
);
2474 parm_data
->start
= cpu_to_le64(start_offset
);
2475 parm_data
->length
= cpu_to_le64(len
); /* normalize negative numbers */
2477 pSMB
->DataOffset
= cpu_to_le16(offset
);
2478 pSMB
->Fid
= smb_file_id
;
2479 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_LOCK
);
2480 pSMB
->Reserved4
= 0;
2481 inc_rfc1001_len(pSMB
, byte_count
);
2482 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2484 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2485 (struct smb_hdr
*) pSMBr
, &bytes_returned
);
2487 iov
[0].iov_base
= (char *)pSMB
;
2488 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
2489 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
2490 &resp_buf_type
, timeout
);
2491 pSMB
= NULL
; /* request buf already freed by SendReceive2. Do
2492 not try to free it twice below on exit */
2493 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)iov
[0].iov_base
;
2497 cifs_dbg(FYI
, "Send error in Posix Lock = %d\n", rc
);
2498 } else if (pLockData
) {
2499 /* lock structure can be returned on get */
2502 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2504 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(*parm_data
)) {
2505 rc
= -EIO
; /* bad smb */
2508 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
2509 data_count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2510 if (data_count
< sizeof(struct cifs_posix_lock
)) {
2514 parm_data
= (struct cifs_posix_lock
*)
2515 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2516 if (parm_data
->lock_type
== cpu_to_le16(CIFS_UNLCK
))
2517 pLockData
->fl_type
= F_UNLCK
;
2519 if (parm_data
->lock_type
==
2520 cpu_to_le16(CIFS_RDLCK
))
2521 pLockData
->fl_type
= F_RDLCK
;
2522 else if (parm_data
->lock_type
==
2523 cpu_to_le16(CIFS_WRLCK
))
2524 pLockData
->fl_type
= F_WRLCK
;
2526 pLockData
->fl_start
= le64_to_cpu(parm_data
->start
);
2527 pLockData
->fl_end
= pLockData
->fl_start
+
2528 le64_to_cpu(parm_data
->length
) - 1;
2529 pLockData
->fl_pid
= le32_to_cpu(parm_data
->pid
);
2535 cifs_small_buf_release(pSMB
);
2537 free_rsp_buf(resp_buf_type
, iov
[0].iov_base
);
2539 /* Note: On -EAGAIN error only caller can retry on handle based calls
2540 since file handle passed in no longer valid */
2547 CIFSSMBClose(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2550 CLOSE_REQ
*pSMB
= NULL
;
2551 cifs_dbg(FYI
, "In CIFSSMBClose\n");
2553 /* do not retry on dead session on close */
2554 rc
= small_smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
);
2560 pSMB
->FileID
= (__u16
) smb_file_id
;
2561 pSMB
->LastWriteTime
= 0xFFFFFFFF;
2562 pSMB
->ByteCount
= 0;
2563 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2564 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_closes
);
2567 /* EINTR is expected when user ctl-c to kill app */
2568 cifs_dbg(VFS
, "Send error in Close = %d\n", rc
);
2572 /* Since session is dead, file will be closed on server already */
2580 CIFSSMBFlush(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2583 FLUSH_REQ
*pSMB
= NULL
;
2584 cifs_dbg(FYI
, "In CIFSSMBFlush\n");
2586 rc
= small_smb_init(SMB_COM_FLUSH
, 1, tcon
, (void **) &pSMB
);
2590 pSMB
->FileID
= (__u16
) smb_file_id
;
2591 pSMB
->ByteCount
= 0;
2592 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2593 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_flushes
);
2595 cifs_dbg(VFS
, "Send error in Flush = %d\n", rc
);
2601 CIFSSMBRename(const unsigned int xid
, struct cifs_tcon
*tcon
,
2602 const char *from_name
, const char *to_name
,
2603 struct cifs_sb_info
*cifs_sb
)
2606 RENAME_REQ
*pSMB
= NULL
;
2607 RENAME_RSP
*pSMBr
= NULL
;
2609 int name_len
, name_len2
;
2611 int remap
= cifs_remap(cifs_sb
);
2613 cifs_dbg(FYI
, "In CIFSSMBRename\n");
2615 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
2620 pSMB
->BufferFormat
= 0x04;
2621 pSMB
->SearchAttributes
=
2622 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2625 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2626 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2627 from_name
, PATH_MAX
,
2628 cifs_sb
->local_nls
, remap
);
2629 name_len
++; /* trailing null */
2631 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2632 /* protocol requires ASCII signature byte on Unicode string */
2633 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2635 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2636 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2638 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2639 name_len2
*= 2; /* convert to bytes */
2640 } else { /* BB improve the check for buffer overruns BB */
2641 name_len
= strnlen(from_name
, PATH_MAX
);
2642 name_len
++; /* trailing null */
2643 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
2644 name_len2
= strnlen(to_name
, PATH_MAX
);
2645 name_len2
++; /* trailing null */
2646 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2647 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
2648 name_len2
++; /* trailing null */
2649 name_len2
++; /* signature byte */
2652 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2653 inc_rfc1001_len(pSMB
, count
);
2654 pSMB
->ByteCount
= cpu_to_le16(count
);
2656 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2657 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2658 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_renames
);
2660 cifs_dbg(FYI
, "Send error in rename = %d\n", rc
);
2662 cifs_buf_release(pSMB
);
2670 int CIFSSMBRenameOpenFile(const unsigned int xid
, struct cifs_tcon
*pTcon
,
2671 int netfid
, const char *target_name
,
2672 const struct nls_table
*nls_codepage
, int remap
)
2674 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2675 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2676 struct set_file_rename
*rename_info
;
2678 char dummy_string
[30];
2680 int bytes_returned
= 0;
2682 __u16 params
, param_offset
, offset
, count
, byte_count
;
2684 cifs_dbg(FYI
, "Rename to File by handle\n");
2685 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
2691 pSMB
->MaxSetupCount
= 0;
2695 pSMB
->Reserved2
= 0;
2696 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2697 offset
= param_offset
+ params
;
2699 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2700 rename_info
= (struct set_file_rename
*) data_offset
;
2701 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2702 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2703 pSMB
->SetupCount
= 1;
2704 pSMB
->Reserved3
= 0;
2705 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2706 byte_count
= 3 /* pad */ + params
;
2707 pSMB
->ParameterCount
= cpu_to_le16(params
);
2708 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2709 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2710 pSMB
->DataOffset
= cpu_to_le16(offset
);
2711 /* construct random name ".cifs_tmp<inodenum><mid>" */
2712 rename_info
->overwrite
= cpu_to_le32(1);
2713 rename_info
->root_fid
= 0;
2714 /* unicode only call */
2715 if (target_name
== NULL
) {
2716 sprintf(dummy_string
, "cifs%x", pSMB
->hdr
.Mid
);
2718 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2719 dummy_string
, 24, nls_codepage
, remap
);
2722 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2723 target_name
, PATH_MAX
, nls_codepage
,
2726 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
2727 count
= 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str
);
2728 byte_count
+= count
;
2729 pSMB
->DataCount
= cpu_to_le16(count
);
2730 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2732 pSMB
->InformationLevel
=
2733 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
2734 pSMB
->Reserved4
= 0;
2735 inc_rfc1001_len(pSMB
, byte_count
);
2736 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2737 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
2738 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2739 cifs_stats_inc(&pTcon
->stats
.cifs_stats
.num_t2renames
);
2741 cifs_dbg(FYI
, "Send error in Rename (by file handle) = %d\n",
2744 cifs_buf_release(pSMB
);
2746 /* Note: On -EAGAIN error only caller can retry on handle based calls
2747 since file handle passed in no longer valid */
2753 CIFSSMBCopy(const unsigned int xid
, struct cifs_tcon
*tcon
,
2754 const char *fromName
, const __u16 target_tid
, const char *toName
,
2755 const int flags
, const struct nls_table
*nls_codepage
, int remap
)
2758 COPY_REQ
*pSMB
= NULL
;
2759 COPY_RSP
*pSMBr
= NULL
;
2761 int name_len
, name_len2
;
2764 cifs_dbg(FYI
, "In CIFSSMBCopy\n");
2766 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
2771 pSMB
->BufferFormat
= 0x04;
2772 pSMB
->Tid2
= target_tid
;
2774 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
2776 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2777 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2778 fromName
, PATH_MAX
, nls_codepage
,
2780 name_len
++; /* trailing null */
2782 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2783 /* protocol requires ASCII signature byte on Unicode string */
2784 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2786 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2787 toName
, PATH_MAX
, nls_codepage
, remap
);
2788 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2789 name_len2
*= 2; /* convert to bytes */
2790 } else { /* BB improve the check for buffer overruns BB */
2791 name_len
= strnlen(fromName
, PATH_MAX
);
2792 name_len
++; /* trailing null */
2793 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
2794 name_len2
= strnlen(toName
, PATH_MAX
);
2795 name_len2
++; /* trailing null */
2796 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2797 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
2798 name_len2
++; /* trailing null */
2799 name_len2
++; /* signature byte */
2802 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2803 inc_rfc1001_len(pSMB
, count
);
2804 pSMB
->ByteCount
= cpu_to_le16(count
);
2806 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2807 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2809 cifs_dbg(FYI
, "Send error in copy = %d with %d files copied\n",
2810 rc
, le16_to_cpu(pSMBr
->CopyCount
));
2812 cifs_buf_release(pSMB
);
2821 CIFSUnixCreateSymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2822 const char *fromName
, const char *toName
,
2823 const struct nls_table
*nls_codepage
, int remap
)
2825 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2826 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2829 int name_len_target
;
2831 int bytes_returned
= 0;
2832 __u16 params
, param_offset
, offset
, byte_count
;
2834 cifs_dbg(FYI
, "In Symlink Unix style\n");
2836 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2841 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2843 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fromName
,
2844 /* find define for this maxpathcomponent */
2845 PATH_MAX
, nls_codepage
, remap
);
2846 name_len
++; /* trailing null */
2849 } else { /* BB improve the check for buffer overruns BB */
2850 name_len
= strnlen(fromName
, PATH_MAX
);
2851 name_len
++; /* trailing null */
2852 strncpy(pSMB
->FileName
, fromName
, name_len
);
2854 params
= 6 + name_len
;
2855 pSMB
->MaxSetupCount
= 0;
2859 pSMB
->Reserved2
= 0;
2860 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2861 InformationLevel
) - 4;
2862 offset
= param_offset
+ params
;
2864 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2865 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2867 cifsConvertToUTF16((__le16
*) data_offset
, toName
,
2868 /* find define for this maxpathcomponent */
2869 PATH_MAX
, nls_codepage
, remap
);
2870 name_len_target
++; /* trailing null */
2871 name_len_target
*= 2;
2872 } else { /* BB improve the check for buffer overruns BB */
2873 name_len_target
= strnlen(toName
, PATH_MAX
);
2874 name_len_target
++; /* trailing null */
2875 strncpy(data_offset
, toName
, name_len_target
);
2878 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2879 /* BB find exact max on data count below from sess */
2880 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2881 pSMB
->SetupCount
= 1;
2882 pSMB
->Reserved3
= 0;
2883 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2884 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2885 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2886 pSMB
->ParameterCount
= cpu_to_le16(params
);
2887 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2888 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2889 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2890 pSMB
->DataOffset
= cpu_to_le16(offset
);
2891 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
2892 pSMB
->Reserved4
= 0;
2893 inc_rfc1001_len(pSMB
, byte_count
);
2894 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2895 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2896 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2897 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_symlinks
);
2899 cifs_dbg(FYI
, "Send error in SetPathInfo create symlink = %d\n",
2902 cifs_buf_release(pSMB
);
2905 goto createSymLinkRetry
;
2911 CIFSUnixCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2912 const char *fromName
, const char *toName
,
2913 const struct nls_table
*nls_codepage
, int remap
)
2915 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2916 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2919 int name_len_target
;
2921 int bytes_returned
= 0;
2922 __u16 params
, param_offset
, offset
, byte_count
;
2924 cifs_dbg(FYI
, "In Create Hard link Unix style\n");
2925 createHardLinkRetry
:
2926 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2931 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2932 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->FileName
, toName
,
2933 PATH_MAX
, nls_codepage
, remap
);
2934 name_len
++; /* trailing null */
2937 } else { /* BB improve the check for buffer overruns BB */
2938 name_len
= strnlen(toName
, PATH_MAX
);
2939 name_len
++; /* trailing null */
2940 strncpy(pSMB
->FileName
, toName
, name_len
);
2942 params
= 6 + name_len
;
2943 pSMB
->MaxSetupCount
= 0;
2947 pSMB
->Reserved2
= 0;
2948 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2949 InformationLevel
) - 4;
2950 offset
= param_offset
+ params
;
2952 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2953 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2955 cifsConvertToUTF16((__le16
*) data_offset
, fromName
,
2956 PATH_MAX
, nls_codepage
, remap
);
2957 name_len_target
++; /* trailing null */
2958 name_len_target
*= 2;
2959 } else { /* BB improve the check for buffer overruns BB */
2960 name_len_target
= strnlen(fromName
, PATH_MAX
);
2961 name_len_target
++; /* trailing null */
2962 strncpy(data_offset
, fromName
, name_len_target
);
2965 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2966 /* BB find exact max on data count below from sess*/
2967 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2968 pSMB
->SetupCount
= 1;
2969 pSMB
->Reserved3
= 0;
2970 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2971 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2972 pSMB
->ParameterCount
= cpu_to_le16(params
);
2973 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2974 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2975 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2976 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2977 pSMB
->DataOffset
= cpu_to_le16(offset
);
2978 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
2979 pSMB
->Reserved4
= 0;
2980 inc_rfc1001_len(pSMB
, byte_count
);
2981 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2982 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2983 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2984 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
2986 cifs_dbg(FYI
, "Send error in SetPathInfo (hard link) = %d\n",
2989 cifs_buf_release(pSMB
);
2991 goto createHardLinkRetry
;
2997 CIFSCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2998 const char *from_name
, const char *to_name
,
2999 struct cifs_sb_info
*cifs_sb
)
3002 NT_RENAME_REQ
*pSMB
= NULL
;
3003 RENAME_RSP
*pSMBr
= NULL
;
3005 int name_len
, name_len2
;
3007 int remap
= cifs_remap(cifs_sb
);
3009 cifs_dbg(FYI
, "In CIFSCreateHardLink\n");
3010 winCreateHardLinkRetry
:
3012 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
3017 pSMB
->SearchAttributes
=
3018 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
3020 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
3021 pSMB
->ClusterCount
= 0;
3023 pSMB
->BufferFormat
= 0x04;
3025 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3027 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, from_name
,
3028 PATH_MAX
, cifs_sb
->local_nls
, remap
);
3029 name_len
++; /* trailing null */
3032 /* protocol specifies ASCII buffer format (0x04) for unicode */
3033 pSMB
->OldFileName
[name_len
] = 0x04;
3034 pSMB
->OldFileName
[name_len
+ 1] = 0x00; /* pad */
3036 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
3037 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
3039 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
3040 name_len2
*= 2; /* convert to bytes */
3041 } else { /* BB improve the check for buffer overruns BB */
3042 name_len
= strnlen(from_name
, PATH_MAX
);
3043 name_len
++; /* trailing null */
3044 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
3045 name_len2
= strnlen(to_name
, PATH_MAX
);
3046 name_len2
++; /* trailing null */
3047 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
3048 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
3049 name_len2
++; /* trailing null */
3050 name_len2
++; /* signature byte */
3053 count
= 1 /* string type byte */ + name_len
+ name_len2
;
3054 inc_rfc1001_len(pSMB
, count
);
3055 pSMB
->ByteCount
= cpu_to_le16(count
);
3057 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3058 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3059 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3061 cifs_dbg(FYI
, "Send error in hard link (NT rename) = %d\n", rc
);
3063 cifs_buf_release(pSMB
);
3065 goto winCreateHardLinkRetry
;
3071 CIFSSMBUnixQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3072 const unsigned char *searchName
, char **symlinkinfo
,
3073 const struct nls_table
*nls_codepage
, int remap
)
3075 /* SMB_QUERY_FILE_UNIX_LINK */
3076 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3077 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3081 __u16 params
, byte_count
;
3084 cifs_dbg(FYI
, "In QPathSymLinkInfo (Unix) for path %s\n", searchName
);
3087 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3092 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3094 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3095 searchName
, PATH_MAX
, nls_codepage
,
3097 name_len
++; /* trailing null */
3099 } else { /* BB improve the check for buffer overruns BB */
3100 name_len
= strnlen(searchName
, PATH_MAX
);
3101 name_len
++; /* trailing null */
3102 strncpy(pSMB
->FileName
, searchName
, name_len
);
3105 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3106 pSMB
->TotalDataCount
= 0;
3107 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3108 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3109 pSMB
->MaxSetupCount
= 0;
3113 pSMB
->Reserved2
= 0;
3114 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3115 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3116 pSMB
->DataCount
= 0;
3117 pSMB
->DataOffset
= 0;
3118 pSMB
->SetupCount
= 1;
3119 pSMB
->Reserved3
= 0;
3120 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3121 byte_count
= params
+ 1 /* pad */ ;
3122 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3123 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3124 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
3125 pSMB
->Reserved4
= 0;
3126 inc_rfc1001_len(pSMB
, byte_count
);
3127 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3129 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3130 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3132 cifs_dbg(FYI
, "Send error in QuerySymLinkInfo = %d\n", rc
);
3134 /* decode response */
3136 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3137 /* BB also check enough total bytes returned */
3138 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3142 u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3144 data_start
= ((char *) &pSMBr
->hdr
.Protocol
) +
3145 le16_to_cpu(pSMBr
->t2
.DataOffset
);
3147 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3152 /* BB FIXME investigate remapping reserved chars here */
3153 *symlinkinfo
= cifs_strndup_from_utf16(data_start
,
3154 count
, is_unicode
, nls_codepage
);
3159 cifs_buf_release(pSMB
);
3161 goto querySymLinkRetry
;
3166 * Recent Windows versions now create symlinks more frequently
3167 * and they use the "reparse point" mechanism below. We can of course
3168 * do symlinks nicely to Samba and other servers which support the
3169 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3170 * "MF" symlinks optionally, but for recent Windows we really need to
3171 * reenable the code below and fix the cifs_symlink callers to handle this.
3172 * In the interim this code has been moved to its own config option so
3173 * it is not compiled in by default until callers fixed up and more tested.
3176 CIFSSMBQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3177 __u16 fid
, char **symlinkinfo
,
3178 const struct nls_table
*nls_codepage
)
3182 struct smb_com_transaction_ioctl_req
*pSMB
;
3183 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3185 unsigned int sub_len
;
3187 struct reparse_symlink_data
*reparse_buf
;
3188 struct reparse_posix_data
*posix_buf
;
3189 __u32 data_offset
, data_count
;
3192 cifs_dbg(FYI
, "In Windows reparse style QueryLink for fid %u\n", fid
);
3193 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3198 pSMB
->TotalParameterCount
= 0 ;
3199 pSMB
->TotalDataCount
= 0;
3200 pSMB
->MaxParameterCount
= cpu_to_le32(2);
3201 /* BB find exact data count max from sess structure BB */
3202 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3203 pSMB
->MaxSetupCount
= 4;
3205 pSMB
->ParameterOffset
= 0;
3206 pSMB
->DataCount
= 0;
3207 pSMB
->DataOffset
= 0;
3208 pSMB
->SetupCount
= 4;
3209 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3210 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3211 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
3212 pSMB
->IsFsctl
= 1; /* FSCTL */
3213 pSMB
->IsRootFlag
= 0;
3214 pSMB
->Fid
= fid
; /* file handle always le */
3215 pSMB
->ByteCount
= 0;
3217 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3218 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3220 cifs_dbg(FYI
, "Send error in QueryReparseLinkInfo = %d\n", rc
);
3224 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3225 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3226 if (get_bcc(&pSMBr
->hdr
) < 2 || data_offset
> 512) {
3227 /* BB also check enough total bytes returned */
3228 rc
= -EIO
; /* bad smb */
3231 if (!data_count
|| (data_count
> 2048)) {
3233 cifs_dbg(FYI
, "Invalid return data count on get reparse info ioctl\n");
3236 end_of_smb
= 2 + get_bcc(&pSMBr
->hdr
) + (char *)&pSMBr
->ByteCount
;
3237 reparse_buf
= (struct reparse_symlink_data
*)
3238 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
3239 if ((char *)reparse_buf
>= end_of_smb
) {
3243 if (reparse_buf
->ReparseTag
== cpu_to_le32(IO_REPARSE_TAG_NFS
)) {
3244 cifs_dbg(FYI
, "NFS style reparse tag\n");
3245 posix_buf
= (struct reparse_posix_data
*)reparse_buf
;
3247 if (posix_buf
->InodeType
!= cpu_to_le64(NFS_SPECFILE_LNK
)) {
3248 cifs_dbg(FYI
, "unsupported file type 0x%llx\n",
3249 le64_to_cpu(posix_buf
->InodeType
));
3254 sub_len
= le16_to_cpu(reparse_buf
->ReparseDataLength
);
3255 if (posix_buf
->PathBuffer
+ sub_len
> end_of_smb
) {
3256 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3260 *symlinkinfo
= cifs_strndup_from_utf16(posix_buf
->PathBuffer
,
3261 sub_len
, is_unicode
, nls_codepage
);
3263 } else if (reparse_buf
->ReparseTag
!=
3264 cpu_to_le32(IO_REPARSE_TAG_SYMLINK
)) {
3269 /* Reparse tag is NTFS symlink */
3270 sub_start
= le16_to_cpu(reparse_buf
->SubstituteNameOffset
) +
3271 reparse_buf
->PathBuffer
;
3272 sub_len
= le16_to_cpu(reparse_buf
->SubstituteNameLength
);
3273 if (sub_start
+ sub_len
> end_of_smb
) {
3274 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3278 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3283 /* BB FIXME investigate remapping reserved chars here */
3284 *symlinkinfo
= cifs_strndup_from_utf16(sub_start
, sub_len
, is_unicode
,
3289 cifs_buf_release(pSMB
);
3292 * Note: On -EAGAIN error only caller can retry on handle based calls
3293 * since file handle passed in no longer valid.
3299 CIFSSMB_set_compression(const unsigned int xid
, struct cifs_tcon
*tcon
,
3304 struct smb_com_transaction_compr_ioctl_req
*pSMB
;
3305 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3307 cifs_dbg(FYI
, "Set compression for %u\n", fid
);
3308 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3313 pSMB
->compression_state
= cpu_to_le16(COMPRESSION_FORMAT_DEFAULT
);
3315 pSMB
->TotalParameterCount
= 0;
3316 pSMB
->TotalDataCount
= cpu_to_le32(2);
3317 pSMB
->MaxParameterCount
= 0;
3318 pSMB
->MaxDataCount
= 0;
3319 pSMB
->MaxSetupCount
= 4;
3321 pSMB
->ParameterOffset
= 0;
3322 pSMB
->DataCount
= cpu_to_le32(2);
3324 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req
,
3325 compression_state
) - 4); /* 84 */
3326 pSMB
->SetupCount
= 4;
3327 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3328 pSMB
->ParameterCount
= 0;
3329 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_SET_COMPRESSION
);
3330 pSMB
->IsFsctl
= 1; /* FSCTL */
3331 pSMB
->IsRootFlag
= 0;
3332 pSMB
->Fid
= fid
; /* file handle always le */
3333 /* 3 byte pad, followed by 2 byte compress state */
3334 pSMB
->ByteCount
= cpu_to_le16(5);
3335 inc_rfc1001_len(pSMB
, 5);
3337 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3338 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3340 cifs_dbg(FYI
, "Send error in SetCompression = %d\n", rc
);
3342 cifs_buf_release(pSMB
);
3345 * Note: On -EAGAIN error only caller can retry on handle based calls
3346 * since file handle passed in no longer valid.
3352 #ifdef CONFIG_CIFS_POSIX
3354 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3355 static void cifs_convert_ace(struct posix_acl_xattr_entry
*ace
,
3356 struct cifs_posix_ace
*cifs_ace
)
3358 /* u8 cifs fields do not need le conversion */
3359 ace
->e_perm
= cpu_to_le16(cifs_ace
->cifs_e_perm
);
3360 ace
->e_tag
= cpu_to_le16(cifs_ace
->cifs_e_tag
);
3361 ace
->e_id
= cpu_to_le32(le64_to_cpu(cifs_ace
->cifs_uid
));
3363 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3364 ace->e_perm, ace->e_tag, ace->e_id);
3370 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3371 static int cifs_copy_posix_acl(char *trgt
, char *src
, const int buflen
,
3372 const int acl_type
, const int size_of_data_area
)
3377 struct cifs_posix_ace
*pACE
;
3378 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)src
;
3379 struct posix_acl_xattr_header
*local_acl
= (void *)trgt
;
3381 if (le16_to_cpu(cifs_acl
->version
) != CIFS_ACL_VERSION
)
3384 if (acl_type
== ACL_TYPE_ACCESS
) {
3385 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3386 pACE
= &cifs_acl
->ace_array
[0];
3387 size
= sizeof(struct cifs_posix_acl
);
3388 size
+= sizeof(struct cifs_posix_ace
) * count
;
3389 /* check if we would go beyond end of SMB */
3390 if (size_of_data_area
< size
) {
3391 cifs_dbg(FYI
, "bad CIFS POSIX ACL size %d vs. %d\n",
3392 size_of_data_area
, size
);
3395 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3396 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3397 size
= sizeof(struct cifs_posix_acl
);
3398 size
+= sizeof(struct cifs_posix_ace
) * count
;
3399 /* skip past access ACEs to get to default ACEs */
3400 pACE
= &cifs_acl
->ace_array
[count
];
3401 count
= le16_to_cpu(cifs_acl
->default_entry_count
);
3402 size
+= sizeof(struct cifs_posix_ace
) * count
;
3403 /* check if we would go beyond end of SMB */
3404 if (size_of_data_area
< size
)
3411 size
= posix_acl_xattr_size(count
);
3412 if ((buflen
== 0) || (local_acl
== NULL
)) {
3413 /* used to query ACL EA size */
3414 } else if (size
> buflen
) {
3416 } else /* buffer big enough */ {
3417 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3419 local_acl
->a_version
= cpu_to_le32(POSIX_ACL_XATTR_VERSION
);
3420 for (i
= 0; i
< count
; i
++) {
3421 cifs_convert_ace(&ace
[i
], pACE
);
3428 static __u16
convert_ace_to_cifs_ace(struct cifs_posix_ace
*cifs_ace
,
3429 const struct posix_acl_xattr_entry
*local_ace
)
3431 __u16 rc
= 0; /* 0 = ACL converted ok */
3433 cifs_ace
->cifs_e_perm
= le16_to_cpu(local_ace
->e_perm
);
3434 cifs_ace
->cifs_e_tag
= le16_to_cpu(local_ace
->e_tag
);
3435 /* BB is there a better way to handle the large uid? */
3436 if (local_ace
->e_id
== cpu_to_le32(-1)) {
3437 /* Probably no need to le convert -1 on any arch but can not hurt */
3438 cifs_ace
->cifs_uid
= cpu_to_le64(-1);
3440 cifs_ace
->cifs_uid
= cpu_to_le64(le32_to_cpu(local_ace
->e_id
));
3442 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3443 ace->e_perm, ace->e_tag, ace->e_id);
3448 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3449 static __u16
ACL_to_cifs_posix(char *parm_data
, const char *pACL
,
3450 const int buflen
, const int acl_type
)
3453 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)parm_data
;
3454 struct posix_acl_xattr_header
*local_acl
= (void *)pACL
;
3455 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3459 if ((buflen
== 0) || (pACL
== NULL
) || (cifs_acl
== NULL
))
3462 count
= posix_acl_xattr_count((size_t)buflen
);
3463 cifs_dbg(FYI
, "setting acl with %d entries from buf of length %d and version of %d\n",
3464 count
, buflen
, le32_to_cpu(local_acl
->a_version
));
3465 if (le32_to_cpu(local_acl
->a_version
) != 2) {
3466 cifs_dbg(FYI
, "unknown POSIX ACL version %d\n",
3467 le32_to_cpu(local_acl
->a_version
));
3470 cifs_acl
->version
= cpu_to_le16(1);
3471 if (acl_type
== ACL_TYPE_ACCESS
) {
3472 cifs_acl
->access_entry_count
= cpu_to_le16(count
);
3473 cifs_acl
->default_entry_count
= cpu_to_le16(0xFFFF);
3474 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3475 cifs_acl
->default_entry_count
= cpu_to_le16(count
);
3476 cifs_acl
->access_entry_count
= cpu_to_le16(0xFFFF);
3478 cifs_dbg(FYI
, "unknown ACL type %d\n", acl_type
);
3481 for (i
= 0; i
< count
; i
++) {
3482 rc
= convert_ace_to_cifs_ace(&cifs_acl
->ace_array
[i
], &ace
[i
]);
3484 /* ACE not converted */
3489 rc
= (__u16
)(count
* sizeof(struct cifs_posix_ace
));
3490 rc
+= sizeof(struct cifs_posix_acl
);
3491 /* BB add check to make sure ACL does not overflow SMB */
3497 CIFSSMBGetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3498 const unsigned char *searchName
,
3499 char *acl_inf
, const int buflen
, const int acl_type
,
3500 const struct nls_table
*nls_codepage
, int remap
)
3502 /* SMB_QUERY_POSIX_ACL */
3503 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3504 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3508 __u16 params
, byte_count
;
3510 cifs_dbg(FYI
, "In GetPosixACL (Unix) for path %s\n", searchName
);
3513 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3518 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3520 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3521 searchName
, PATH_MAX
, nls_codepage
,
3523 name_len
++; /* trailing null */
3525 pSMB
->FileName
[name_len
] = 0;
3526 pSMB
->FileName
[name_len
+1] = 0;
3527 } else { /* BB improve the check for buffer overruns BB */
3528 name_len
= strnlen(searchName
, PATH_MAX
);
3529 name_len
++; /* trailing null */
3530 strncpy(pSMB
->FileName
, searchName
, name_len
);
3533 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3534 pSMB
->TotalDataCount
= 0;
3535 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3536 /* BB find exact max data count below from sess structure BB */
3537 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3538 pSMB
->MaxSetupCount
= 0;
3542 pSMB
->Reserved2
= 0;
3543 pSMB
->ParameterOffset
= cpu_to_le16(
3544 offsetof(struct smb_com_transaction2_qpi_req
,
3545 InformationLevel
) - 4);
3546 pSMB
->DataCount
= 0;
3547 pSMB
->DataOffset
= 0;
3548 pSMB
->SetupCount
= 1;
3549 pSMB
->Reserved3
= 0;
3550 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3551 byte_count
= params
+ 1 /* pad */ ;
3552 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3553 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3554 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_ACL
);
3555 pSMB
->Reserved4
= 0;
3556 inc_rfc1001_len(pSMB
, byte_count
);
3557 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3559 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3560 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3561 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3563 cifs_dbg(FYI
, "Send error in Query POSIX ACL = %d\n", rc
);
3565 /* decode response */
3567 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3568 /* BB also check enough total bytes returned */
3569 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3570 rc
= -EIO
; /* bad smb */
3572 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3573 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3574 rc
= cifs_copy_posix_acl(acl_inf
,
3575 (char *)&pSMBr
->hdr
.Protocol
+data_offset
,
3576 buflen
, acl_type
, count
);
3579 cifs_buf_release(pSMB
);
3586 CIFSSMBSetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3587 const unsigned char *fileName
,
3588 const char *local_acl
, const int buflen
,
3590 const struct nls_table
*nls_codepage
, int remap
)
3592 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3593 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3597 int bytes_returned
= 0;
3598 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
3600 cifs_dbg(FYI
, "In SetPosixACL (Unix) for path %s\n", fileName
);
3602 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3606 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3608 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
3609 PATH_MAX
, nls_codepage
, remap
);
3610 name_len
++; /* trailing null */
3612 } else { /* BB improve the check for buffer overruns BB */
3613 name_len
= strnlen(fileName
, PATH_MAX
);
3614 name_len
++; /* trailing null */
3615 strncpy(pSMB
->FileName
, fileName
, name_len
);
3617 params
= 6 + name_len
;
3618 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3619 /* BB find max SMB size from sess */
3620 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3621 pSMB
->MaxSetupCount
= 0;
3625 pSMB
->Reserved2
= 0;
3626 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3627 InformationLevel
) - 4;
3628 offset
= param_offset
+ params
;
3629 parm_data
= ((char *) &pSMB
->hdr
.Protocol
) + offset
;
3630 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3632 /* convert to on the wire format for POSIX ACL */
3633 data_count
= ACL_to_cifs_posix(parm_data
, local_acl
, buflen
, acl_type
);
3635 if (data_count
== 0) {
3637 goto setACLerrorExit
;
3639 pSMB
->DataOffset
= cpu_to_le16(offset
);
3640 pSMB
->SetupCount
= 1;
3641 pSMB
->Reserved3
= 0;
3642 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3643 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_ACL
);
3644 byte_count
= 3 /* pad */ + params
+ data_count
;
3645 pSMB
->DataCount
= cpu_to_le16(data_count
);
3646 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3647 pSMB
->ParameterCount
= cpu_to_le16(params
);
3648 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3649 pSMB
->Reserved4
= 0;
3650 inc_rfc1001_len(pSMB
, byte_count
);
3651 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3652 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3653 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3655 cifs_dbg(FYI
, "Set POSIX ACL returned %d\n", rc
);
3658 cifs_buf_release(pSMB
);
3664 /* BB fix tabs in this function FIXME BB */
3666 CIFSGetExtAttr(const unsigned int xid
, struct cifs_tcon
*tcon
,
3667 const int netfid
, __u64
*pExtAttrBits
, __u64
*pMask
)
3670 struct smb_t2_qfi_req
*pSMB
= NULL
;
3671 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3673 __u16 params
, byte_count
;
3675 cifs_dbg(FYI
, "In GetExtAttr\n");
3680 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3685 params
= 2 /* level */ + 2 /* fid */;
3686 pSMB
->t2
.TotalDataCount
= 0;
3687 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3688 /* BB find exact max data count below from sess structure BB */
3689 pSMB
->t2
.MaxDataCount
= cpu_to_le16(4000);
3690 pSMB
->t2
.MaxSetupCount
= 0;
3691 pSMB
->t2
.Reserved
= 0;
3693 pSMB
->t2
.Timeout
= 0;
3694 pSMB
->t2
.Reserved2
= 0;
3695 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3697 pSMB
->t2
.DataCount
= 0;
3698 pSMB
->t2
.DataOffset
= 0;
3699 pSMB
->t2
.SetupCount
= 1;
3700 pSMB
->t2
.Reserved3
= 0;
3701 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3702 byte_count
= params
+ 1 /* pad */ ;
3703 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3704 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3705 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_ATTR_FLAGS
);
3708 inc_rfc1001_len(pSMB
, byte_count
);
3709 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3711 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3712 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3714 cifs_dbg(FYI
, "error %d in GetExtAttr\n", rc
);
3716 /* decode response */
3717 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3718 /* BB also check enough total bytes returned */
3719 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3720 /* If rc should we check for EOPNOSUPP and
3721 disable the srvino flag? or in caller? */
3722 rc
= -EIO
; /* bad smb */
3724 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3725 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3726 struct file_chattr_info
*pfinfo
;
3727 /* BB Do we need a cast or hash here ? */
3729 cifs_dbg(FYI
, "Illegal size ret in GetExtAttr\n");
3733 pfinfo
= (struct file_chattr_info
*)
3734 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
3735 *pExtAttrBits
= le64_to_cpu(pfinfo
->mode
);
3736 *pMask
= le64_to_cpu(pfinfo
->mask
);
3740 cifs_buf_release(pSMB
);
3742 goto GetExtAttrRetry
;
3746 #endif /* CONFIG_POSIX */
3748 #ifdef CONFIG_CIFS_ACL
3750 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3751 * all NT TRANSACTS that we init here have total parm and data under about 400
3752 * bytes (to fit in small cifs buffer size), which is the case so far, it
3753 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3754 * returned setup area) and MaxParameterCount (returned parms size) must be set
3758 smb_init_nttransact(const __u16 sub_command
, const int setup_count
,
3759 const int parm_len
, struct cifs_tcon
*tcon
,
3764 struct smb_com_ntransact_req
*pSMB
;
3766 rc
= small_smb_init(SMB_COM_NT_TRANSACT
, 19 + setup_count
, tcon
,
3770 *ret_buf
= (void *)pSMB
;
3772 pSMB
->TotalParameterCount
= cpu_to_le32(parm_len
);
3773 pSMB
->TotalDataCount
= 0;
3774 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3775 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3776 pSMB
->DataCount
= pSMB
->TotalDataCount
;
3777 temp_offset
= offsetof(struct smb_com_ntransact_req
, Parms
) +
3778 (setup_count
* 2) - 4 /* for rfc1001 length itself */;
3779 pSMB
->ParameterOffset
= cpu_to_le32(temp_offset
);
3780 pSMB
->DataOffset
= cpu_to_le32(temp_offset
+ parm_len
);
3781 pSMB
->SetupCount
= setup_count
; /* no need to le convert byte fields */
3782 pSMB
->SubCommand
= cpu_to_le16(sub_command
);
3787 validate_ntransact(char *buf
, char **ppparm
, char **ppdata
,
3788 __u32
*pparmlen
, __u32
*pdatalen
)
3791 __u32 data_count
, data_offset
, parm_count
, parm_offset
;
3792 struct smb_com_ntransact_rsp
*pSMBr
;
3801 pSMBr
= (struct smb_com_ntransact_rsp
*)buf
;
3803 bcc
= get_bcc(&pSMBr
->hdr
);
3804 end_of_smb
= 2 /* sizeof byte count */ + bcc
+
3805 (char *)&pSMBr
->ByteCount
;
3807 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3808 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3809 parm_offset
= le32_to_cpu(pSMBr
->ParameterOffset
);
3810 parm_count
= le32_to_cpu(pSMBr
->ParameterCount
);
3812 *ppparm
= (char *)&pSMBr
->hdr
.Protocol
+ parm_offset
;
3813 *ppdata
= (char *)&pSMBr
->hdr
.Protocol
+ data_offset
;
3815 /* should we also check that parm and data areas do not overlap? */
3816 if (*ppparm
> end_of_smb
) {
3817 cifs_dbg(FYI
, "parms start after end of smb\n");
3819 } else if (parm_count
+ *ppparm
> end_of_smb
) {
3820 cifs_dbg(FYI
, "parm end after end of smb\n");
3822 } else if (*ppdata
> end_of_smb
) {
3823 cifs_dbg(FYI
, "data starts after end of smb\n");
3825 } else if (data_count
+ *ppdata
> end_of_smb
) {
3826 cifs_dbg(FYI
, "data %p + count %d (%p) past smb end %p start %p\n",
3827 *ppdata
, data_count
, (data_count
+ *ppdata
),
3830 } else if (parm_count
+ data_count
> bcc
) {
3831 cifs_dbg(FYI
, "parm count and data count larger than SMB\n");
3834 *pdatalen
= data_count
;
3835 *pparmlen
= parm_count
;
3839 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3841 CIFSSMBGetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3842 struct cifs_ntsd
**acl_inf
, __u32
*pbuflen
)
3846 QUERY_SEC_DESC_REQ
*pSMB
;
3849 cifs_dbg(FYI
, "GetCifsACL\n");
3854 rc
= smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC
, 0,
3855 8 /* parm len */, tcon
, (void **) &pSMB
);
3859 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3860 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3861 pSMB
->MaxSetupCount
= 0;
3862 pSMB
->Fid
= fid
; /* file handle always le */
3863 pSMB
->AclFlags
= cpu_to_le32(CIFS_ACL_OWNER
| CIFS_ACL_GROUP
|
3865 pSMB
->ByteCount
= cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3866 inc_rfc1001_len(pSMB
, 11);
3867 iov
[0].iov_base
= (char *)pSMB
;
3868 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
3870 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovec */, &buf_type
,
3872 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3874 cifs_dbg(FYI
, "Send error in QuerySecDesc = %d\n", rc
);
3875 } else { /* decode response */
3879 struct smb_com_ntransact_rsp
*pSMBr
;
3882 /* validate_nttransact */
3883 rc
= validate_ntransact(iov
[0].iov_base
, (char **)&parm
,
3884 &pdata
, &parm_len
, pbuflen
);
3887 pSMBr
= (struct smb_com_ntransact_rsp
*)iov
[0].iov_base
;
3889 cifs_dbg(FYI
, "smb %p parm %p data %p\n",
3890 pSMBr
, parm
, *acl_inf
);
3892 if (le32_to_cpu(pSMBr
->ParameterCount
) != 4) {
3893 rc
= -EIO
; /* bad smb */
3898 /* BB check that data area is minimum length and as big as acl_len */
3900 acl_len
= le32_to_cpu(*parm
);
3901 if (acl_len
!= *pbuflen
) {
3902 cifs_dbg(VFS
, "acl length %d does not match %d\n",
3904 if (*pbuflen
> acl_len
)
3908 /* check if buffer is big enough for the acl
3909 header followed by the smallest SID */
3910 if ((*pbuflen
< sizeof(struct cifs_ntsd
) + 8) ||
3911 (*pbuflen
>= 64 * 1024)) {
3912 cifs_dbg(VFS
, "bad acl length %d\n", *pbuflen
);
3916 *acl_inf
= kmemdup(pdata
, *pbuflen
, GFP_KERNEL
);
3917 if (*acl_inf
== NULL
) {
3924 free_rsp_buf(buf_type
, iov
[0].iov_base
);
3925 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3930 CIFSSMBSetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3931 struct cifs_ntsd
*pntsd
, __u32 acllen
, int aclflag
)
3933 __u16 byte_count
, param_count
, data_count
, param_offset
, data_offset
;
3935 int bytes_returned
= 0;
3936 SET_SEC_DESC_REQ
*pSMB
= NULL
;
3940 rc
= smb_init(SMB_COM_NT_TRANSACT
, 19, tcon
, (void **) &pSMB
, &pSMBr
);
3944 pSMB
->MaxSetupCount
= 0;
3948 param_offset
= offsetof(struct smb_com_transaction_ssec_req
, Fid
) - 4;
3949 data_count
= acllen
;
3950 data_offset
= param_offset
+ param_count
;
3951 byte_count
= 3 /* pad */ + param_count
;
3953 pSMB
->DataCount
= cpu_to_le32(data_count
);
3954 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3955 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3956 pSMB
->MaxDataCount
= cpu_to_le32(16384);
3957 pSMB
->ParameterCount
= cpu_to_le32(param_count
);
3958 pSMB
->ParameterOffset
= cpu_to_le32(param_offset
);
3959 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3960 pSMB
->DataOffset
= cpu_to_le32(data_offset
);
3961 pSMB
->SetupCount
= 0;
3962 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC
);
3963 pSMB
->ByteCount
= cpu_to_le16(byte_count
+data_count
);
3965 pSMB
->Fid
= fid
; /* file handle always le */
3966 pSMB
->Reserved2
= 0;
3967 pSMB
->AclFlags
= cpu_to_le32(aclflag
);
3969 if (pntsd
&& acllen
) {
3970 memcpy((char *)pSMBr
+ offsetof(struct smb_hdr
, Protocol
) +
3971 data_offset
, pntsd
, acllen
);
3972 inc_rfc1001_len(pSMB
, byte_count
+ data_count
);
3974 inc_rfc1001_len(pSMB
, byte_count
);
3976 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3977 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3979 cifs_dbg(FYI
, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3980 bytes_returned
, rc
);
3982 cifs_dbg(FYI
, "Set CIFS ACL returned %d\n", rc
);
3983 cifs_buf_release(pSMB
);
3986 goto setCifsAclRetry
;
3991 #endif /* CONFIG_CIFS_ACL */
3993 /* Legacy Query Path Information call for lookup to old servers such
3996 SMBQueryInformation(const unsigned int xid
, struct cifs_tcon
*tcon
,
3997 const char *search_name
, FILE_ALL_INFO
*data
,
3998 const struct nls_table
*nls_codepage
, int remap
)
4000 QUERY_INFORMATION_REQ
*pSMB
;
4001 QUERY_INFORMATION_RSP
*pSMBr
;
4006 cifs_dbg(FYI
, "In SMBQPath path %s\n", search_name
);
4008 rc
= smb_init(SMB_COM_QUERY_INFORMATION
, 0, tcon
, (void **) &pSMB
,
4013 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4015 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4016 search_name
, PATH_MAX
, nls_codepage
,
4018 name_len
++; /* trailing null */
4021 name_len
= strnlen(search_name
, PATH_MAX
);
4022 name_len
++; /* trailing null */
4023 strncpy(pSMB
->FileName
, search_name
, name_len
);
4025 pSMB
->BufferFormat
= 0x04;
4026 name_len
++; /* account for buffer type byte */
4027 inc_rfc1001_len(pSMB
, (__u16
)name_len
);
4028 pSMB
->ByteCount
= cpu_to_le16(name_len
);
4030 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4031 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4033 cifs_dbg(FYI
, "Send error in QueryInfo = %d\n", rc
);
4036 __u32 time
= le32_to_cpu(pSMBr
->last_write_time
);
4038 /* decode response */
4039 /* BB FIXME - add time zone adjustment BB */
4040 memset(data
, 0, sizeof(FILE_ALL_INFO
));
4043 /* decode time fields */
4044 data
->ChangeTime
= cpu_to_le64(cifs_UnixTimeToNT(ts
));
4045 data
->LastWriteTime
= data
->ChangeTime
;
4046 data
->LastAccessTime
= 0;
4047 data
->AllocationSize
=
4048 cpu_to_le64(le32_to_cpu(pSMBr
->size
));
4049 data
->EndOfFile
= data
->AllocationSize
;
4051 cpu_to_le32(le16_to_cpu(pSMBr
->attr
));
4053 rc
= -EIO
; /* bad buffer passed in */
4055 cifs_buf_release(pSMB
);
4064 CIFSSMBQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4065 u16 netfid
, FILE_ALL_INFO
*pFindData
)
4067 struct smb_t2_qfi_req
*pSMB
= NULL
;
4068 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4071 __u16 params
, byte_count
;
4074 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4079 params
= 2 /* level */ + 2 /* fid */;
4080 pSMB
->t2
.TotalDataCount
= 0;
4081 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4082 /* BB find exact max data count below from sess structure BB */
4083 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4084 pSMB
->t2
.MaxSetupCount
= 0;
4085 pSMB
->t2
.Reserved
= 0;
4087 pSMB
->t2
.Timeout
= 0;
4088 pSMB
->t2
.Reserved2
= 0;
4089 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4091 pSMB
->t2
.DataCount
= 0;
4092 pSMB
->t2
.DataOffset
= 0;
4093 pSMB
->t2
.SetupCount
= 1;
4094 pSMB
->t2
.Reserved3
= 0;
4095 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4096 byte_count
= params
+ 1 /* pad */ ;
4097 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4098 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4099 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4102 inc_rfc1001_len(pSMB
, byte_count
);
4103 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4105 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4106 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4108 cifs_dbg(FYI
, "Send error in QFileInfo = %d", rc
);
4109 } else { /* decode response */
4110 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4112 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4114 else if (get_bcc(&pSMBr
->hdr
) < 40)
4115 rc
= -EIO
; /* bad smb */
4116 else if (pFindData
) {
4117 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4118 memcpy((char *) pFindData
,
4119 (char *) &pSMBr
->hdr
.Protocol
+
4120 data_offset
, sizeof(FILE_ALL_INFO
));
4124 cifs_buf_release(pSMB
);
4126 goto QFileInfoRetry
;
4132 CIFSSMBQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4133 const char *search_name
, FILE_ALL_INFO
*data
,
4134 int legacy
/* old style infolevel */,
4135 const struct nls_table
*nls_codepage
, int remap
)
4137 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4138 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4139 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4143 __u16 params
, byte_count
;
4145 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4147 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4152 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4154 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, search_name
,
4155 PATH_MAX
, nls_codepage
, remap
);
4156 name_len
++; /* trailing null */
4158 } else { /* BB improve the check for buffer overruns BB */
4159 name_len
= strnlen(search_name
, PATH_MAX
);
4160 name_len
++; /* trailing null */
4161 strncpy(pSMB
->FileName
, search_name
, name_len
);
4164 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4165 pSMB
->TotalDataCount
= 0;
4166 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4167 /* BB find exact max SMB PDU from sess structure BB */
4168 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4169 pSMB
->MaxSetupCount
= 0;
4173 pSMB
->Reserved2
= 0;
4174 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4175 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4176 pSMB
->DataCount
= 0;
4177 pSMB
->DataOffset
= 0;
4178 pSMB
->SetupCount
= 1;
4179 pSMB
->Reserved3
= 0;
4180 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4181 byte_count
= params
+ 1 /* pad */ ;
4182 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4183 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4185 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
4187 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4188 pSMB
->Reserved4
= 0;
4189 inc_rfc1001_len(pSMB
, byte_count
);
4190 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4192 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4193 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4195 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4196 } else { /* decode response */
4197 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4199 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4201 else if (!legacy
&& get_bcc(&pSMBr
->hdr
) < 40)
4202 rc
= -EIO
; /* bad smb */
4203 else if (legacy
&& get_bcc(&pSMBr
->hdr
) < 24)
4204 rc
= -EIO
; /* 24 or 26 expected but we do not read
4208 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4211 * On legacy responses we do not read the last field,
4212 * EAsize, fortunately since it varies by subdialect and
4213 * also note it differs on Set vs Get, ie two bytes or 4
4214 * bytes depending but we don't care here.
4217 size
= sizeof(FILE_INFO_STANDARD
);
4219 size
= sizeof(FILE_ALL_INFO
);
4220 memcpy((char *) data
, (char *) &pSMBr
->hdr
.Protocol
+
4225 cifs_buf_release(pSMB
);
4227 goto QPathInfoRetry
;
4233 CIFSSMBUnixQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4234 u16 netfid
, FILE_UNIX_BASIC_INFO
*pFindData
)
4236 struct smb_t2_qfi_req
*pSMB
= NULL
;
4237 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4240 __u16 params
, byte_count
;
4243 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4248 params
= 2 /* level */ + 2 /* fid */;
4249 pSMB
->t2
.TotalDataCount
= 0;
4250 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4251 /* BB find exact max data count below from sess structure BB */
4252 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4253 pSMB
->t2
.MaxSetupCount
= 0;
4254 pSMB
->t2
.Reserved
= 0;
4256 pSMB
->t2
.Timeout
= 0;
4257 pSMB
->t2
.Reserved2
= 0;
4258 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4260 pSMB
->t2
.DataCount
= 0;
4261 pSMB
->t2
.DataOffset
= 0;
4262 pSMB
->t2
.SetupCount
= 1;
4263 pSMB
->t2
.Reserved3
= 0;
4264 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4265 byte_count
= params
+ 1 /* pad */ ;
4266 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4267 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4268 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4271 inc_rfc1001_len(pSMB
, byte_count
);
4272 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4274 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4275 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4277 cifs_dbg(FYI
, "Send error in UnixQFileInfo = %d", rc
);
4278 } else { /* decode response */
4279 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4281 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4282 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4283 rc
= -EIO
; /* bad smb */
4285 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4286 memcpy((char *) pFindData
,
4287 (char *) &pSMBr
->hdr
.Protocol
+
4289 sizeof(FILE_UNIX_BASIC_INFO
));
4293 cifs_buf_release(pSMB
);
4295 goto UnixQFileInfoRetry
;
4301 CIFSSMBUnixQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4302 const unsigned char *searchName
,
4303 FILE_UNIX_BASIC_INFO
*pFindData
,
4304 const struct nls_table
*nls_codepage
, int remap
)
4306 /* SMB_QUERY_FILE_UNIX_BASIC */
4307 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4308 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4310 int bytes_returned
= 0;
4312 __u16 params
, byte_count
;
4314 cifs_dbg(FYI
, "In QPathInfo (Unix) the path %s\n", searchName
);
4316 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4321 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4323 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4324 PATH_MAX
, nls_codepage
, remap
);
4325 name_len
++; /* trailing null */
4327 } else { /* BB improve the check for buffer overruns BB */
4328 name_len
= strnlen(searchName
, PATH_MAX
);
4329 name_len
++; /* trailing null */
4330 strncpy(pSMB
->FileName
, searchName
, name_len
);
4333 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4334 pSMB
->TotalDataCount
= 0;
4335 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4336 /* BB find exact max SMB PDU from sess structure BB */
4337 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4338 pSMB
->MaxSetupCount
= 0;
4342 pSMB
->Reserved2
= 0;
4343 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4344 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4345 pSMB
->DataCount
= 0;
4346 pSMB
->DataOffset
= 0;
4347 pSMB
->SetupCount
= 1;
4348 pSMB
->Reserved3
= 0;
4349 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4350 byte_count
= params
+ 1 /* pad */ ;
4351 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4352 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4353 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4354 pSMB
->Reserved4
= 0;
4355 inc_rfc1001_len(pSMB
, byte_count
);
4356 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4358 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4359 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4361 cifs_dbg(FYI
, "Send error in UnixQPathInfo = %d", rc
);
4362 } else { /* decode response */
4363 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4365 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4366 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4367 rc
= -EIO
; /* bad smb */
4369 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4370 memcpy((char *) pFindData
,
4371 (char *) &pSMBr
->hdr
.Protocol
+
4373 sizeof(FILE_UNIX_BASIC_INFO
));
4376 cifs_buf_release(pSMB
);
4378 goto UnixQPathInfoRetry
;
4383 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4385 CIFSFindFirst(const unsigned int xid
, struct cifs_tcon
*tcon
,
4386 const char *searchName
, struct cifs_sb_info
*cifs_sb
,
4387 __u16
*pnetfid
, __u16 search_flags
,
4388 struct cifs_search_info
*psrch_inf
, bool msearch
)
4390 /* level 257 SMB_ */
4391 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
4392 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
4393 T2_FFIRST_RSP_PARMS
*parms
;
4395 int bytes_returned
= 0;
4396 int name_len
, remap
;
4397 __u16 params
, byte_count
;
4398 struct nls_table
*nls_codepage
;
4400 cifs_dbg(FYI
, "In FindFirst for %s\n", searchName
);
4403 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4408 nls_codepage
= cifs_sb
->local_nls
;
4409 remap
= cifs_remap(cifs_sb
);
4411 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4413 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4414 PATH_MAX
, nls_codepage
, remap
);
4415 /* We can not add the asterik earlier in case
4416 it got remapped to 0xF03A as if it were part of the
4417 directory name instead of a wildcard */
4420 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4421 pSMB
->FileName
[name_len
+1] = 0;
4422 pSMB
->FileName
[name_len
+2] = '*';
4423 pSMB
->FileName
[name_len
+3] = 0;
4424 name_len
+= 4; /* now the trailing null */
4425 /* null terminate just in case */
4426 pSMB
->FileName
[name_len
] = 0;
4427 pSMB
->FileName
[name_len
+1] = 0;
4430 } else { /* BB add check for overrun of SMB buf BB */
4431 name_len
= strnlen(searchName
, PATH_MAX
);
4432 /* BB fix here and in unicode clause above ie
4433 if (name_len > buffersize-header)
4434 free buffer exit; BB */
4435 strncpy(pSMB
->FileName
, searchName
, name_len
);
4437 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4438 pSMB
->FileName
[name_len
+1] = '*';
4439 pSMB
->FileName
[name_len
+2] = 0;
4444 params
= 12 + name_len
/* includes null */ ;
4445 pSMB
->TotalDataCount
= 0; /* no EAs */
4446 pSMB
->MaxParameterCount
= cpu_to_le16(10);
4447 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4448 pSMB
->MaxSetupCount
= 0;
4452 pSMB
->Reserved2
= 0;
4453 byte_count
= params
+ 1 /* pad */ ;
4454 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4455 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4456 pSMB
->ParameterOffset
= cpu_to_le16(
4457 offsetof(struct smb_com_transaction2_ffirst_req
, SearchAttributes
)
4459 pSMB
->DataCount
= 0;
4460 pSMB
->DataOffset
= 0;
4461 pSMB
->SetupCount
= 1; /* one byte, no need to make endian neutral */
4462 pSMB
->Reserved3
= 0;
4463 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
4464 pSMB
->SearchAttributes
=
4465 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
4467 pSMB
->SearchCount
= cpu_to_le16(CIFSMaxBufSize
/sizeof(FILE_UNIX_INFO
));
4468 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4469 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4471 /* BB what should we set StorageType to? Does it matter? BB */
4472 pSMB
->SearchStorageType
= 0;
4473 inc_rfc1001_len(pSMB
, byte_count
);
4474 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4476 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4477 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4478 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_ffirst
);
4480 if (rc
) {/* BB add logic to retry regular search if Unix search
4481 rejected unexpectedly by server */
4482 /* BB Add code to handle unsupported level rc */
4483 cifs_dbg(FYI
, "Error in FindFirst = %d\n", rc
);
4485 cifs_buf_release(pSMB
);
4487 /* BB eventually could optimize out free and realloc of buf */
4490 goto findFirstRetry
;
4491 } else { /* decode response */
4492 /* BB remember to free buffer if error BB */
4493 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4497 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4498 psrch_inf
->unicode
= true;
4500 psrch_inf
->unicode
= false;
4502 psrch_inf
->ntwrk_buf_start
= (char *)pSMBr
;
4503 psrch_inf
->smallBuf
= 0;
4504 psrch_inf
->srch_entries_start
=
4505 (char *) &pSMBr
->hdr
.Protocol
+
4506 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4507 parms
= (T2_FFIRST_RSP_PARMS
*)((char *) &pSMBr
->hdr
.Protocol
+
4508 le16_to_cpu(pSMBr
->t2
.ParameterOffset
));
4510 if (parms
->EndofSearch
)
4511 psrch_inf
->endOfSearch
= true;
4513 psrch_inf
->endOfSearch
= false;
4515 psrch_inf
->entries_in_buffer
=
4516 le16_to_cpu(parms
->SearchCount
);
4517 psrch_inf
->index_of_last_entry
= 2 /* skip . and .. */ +
4518 psrch_inf
->entries_in_buffer
;
4519 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4520 if (CIFSMaxBufSize
< lnoff
) {
4521 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4522 psrch_inf
->last_entry
= NULL
;
4526 psrch_inf
->last_entry
= psrch_inf
->srch_entries_start
+
4530 *pnetfid
= parms
->SearchHandle
;
4532 cifs_buf_release(pSMB
);
4539 int CIFSFindNext(const unsigned int xid
, struct cifs_tcon
*tcon
,
4540 __u16 searchHandle
, __u16 search_flags
,
4541 struct cifs_search_info
*psrch_inf
)
4543 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
4544 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
4545 T2_FNEXT_RSP_PARMS
*parms
;
4546 char *response_data
;
4549 unsigned int name_len
;
4550 __u16 params
, byte_count
;
4552 cifs_dbg(FYI
, "In FindNext\n");
4554 if (psrch_inf
->endOfSearch
)
4557 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4562 params
= 14; /* includes 2 bytes of null string, converted to LE below*/
4564 pSMB
->TotalDataCount
= 0; /* no EAs */
4565 pSMB
->MaxParameterCount
= cpu_to_le16(8);
4566 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4567 pSMB
->MaxSetupCount
= 0;
4571 pSMB
->Reserved2
= 0;
4572 pSMB
->ParameterOffset
= cpu_to_le16(
4573 offsetof(struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
4574 pSMB
->DataCount
= 0;
4575 pSMB
->DataOffset
= 0;
4576 pSMB
->SetupCount
= 1;
4577 pSMB
->Reserved3
= 0;
4578 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
4579 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
4581 cpu_to_le16(CIFSMaxBufSize
/ sizeof(FILE_UNIX_INFO
));
4582 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4583 pSMB
->ResumeKey
= psrch_inf
->resume_key
;
4584 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4586 name_len
= psrch_inf
->resume_name_len
;
4588 if (name_len
< PATH_MAX
) {
4589 memcpy(pSMB
->ResumeFileName
, psrch_inf
->presume_name
, name_len
);
4590 byte_count
+= name_len
;
4591 /* 14 byte parm len above enough for 2 byte null terminator */
4592 pSMB
->ResumeFileName
[name_len
] = 0;
4593 pSMB
->ResumeFileName
[name_len
+1] = 0;
4596 goto FNext2_err_exit
;
4598 byte_count
= params
+ 1 /* pad */ ;
4599 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4600 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4601 inc_rfc1001_len(pSMB
, byte_count
);
4602 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4604 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4605 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4606 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fnext
);
4609 psrch_inf
->endOfSearch
= true;
4610 cifs_buf_release(pSMB
);
4611 rc
= 0; /* search probably was closed at end of search*/
4613 cifs_dbg(FYI
, "FindNext returned = %d\n", rc
);
4614 } else { /* decode response */
4615 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4620 /* BB fixme add lock for file (srch_info) struct here */
4621 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4622 psrch_inf
->unicode
= true;
4624 psrch_inf
->unicode
= false;
4625 response_data
= (char *) &pSMBr
->hdr
.Protocol
+
4626 le16_to_cpu(pSMBr
->t2
.ParameterOffset
);
4627 parms
= (T2_FNEXT_RSP_PARMS
*)response_data
;
4628 response_data
= (char *)&pSMBr
->hdr
.Protocol
+
4629 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4630 if (psrch_inf
->smallBuf
)
4631 cifs_small_buf_release(
4632 psrch_inf
->ntwrk_buf_start
);
4634 cifs_buf_release(psrch_inf
->ntwrk_buf_start
);
4635 psrch_inf
->srch_entries_start
= response_data
;
4636 psrch_inf
->ntwrk_buf_start
= (char *)pSMB
;
4637 psrch_inf
->smallBuf
= 0;
4638 if (parms
->EndofSearch
)
4639 psrch_inf
->endOfSearch
= true;
4641 psrch_inf
->endOfSearch
= false;
4642 psrch_inf
->entries_in_buffer
=
4643 le16_to_cpu(parms
->SearchCount
);
4644 psrch_inf
->index_of_last_entry
+=
4645 psrch_inf
->entries_in_buffer
;
4646 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4647 if (CIFSMaxBufSize
< lnoff
) {
4648 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4649 psrch_inf
->last_entry
= NULL
;
4652 psrch_inf
->last_entry
=
4653 psrch_inf
->srch_entries_start
+ lnoff
;
4655 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4656 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4658 /* BB fixme add unlock here */
4663 /* BB On error, should we leave previous search buf (and count and
4664 last entry fields) intact or free the previous one? */
4666 /* Note: On -EAGAIN error only caller can retry on handle based calls
4667 since file handle passed in no longer valid */
4670 cifs_buf_release(pSMB
);
4675 CIFSFindClose(const unsigned int xid
, struct cifs_tcon
*tcon
,
4676 const __u16 searchHandle
)
4679 FINDCLOSE_REQ
*pSMB
= NULL
;
4681 cifs_dbg(FYI
, "In CIFSSMBFindClose\n");
4682 rc
= small_smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **)&pSMB
);
4684 /* no sense returning error if session restarted
4685 as file handle has been closed */
4691 pSMB
->FileID
= searchHandle
;
4692 pSMB
->ByteCount
= 0;
4693 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
4695 cifs_dbg(VFS
, "Send error in FindClose = %d\n", rc
);
4697 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fclose
);
4699 /* Since session is dead, search handle closed on server already */
4707 CIFSGetSrvInodeNumber(const unsigned int xid
, struct cifs_tcon
*tcon
,
4708 const char *search_name
, __u64
*inode_number
,
4709 const struct nls_table
*nls_codepage
, int remap
)
4712 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4713 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4714 int name_len
, bytes_returned
;
4715 __u16 params
, byte_count
;
4717 cifs_dbg(FYI
, "In GetSrvInodeNum for %s\n", search_name
);
4721 GetInodeNumberRetry
:
4722 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4727 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4729 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4730 search_name
, PATH_MAX
, nls_codepage
,
4732 name_len
++; /* trailing null */
4734 } else { /* BB improve the check for buffer overruns BB */
4735 name_len
= strnlen(search_name
, PATH_MAX
);
4736 name_len
++; /* trailing null */
4737 strncpy(pSMB
->FileName
, search_name
, name_len
);
4740 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
4741 pSMB
->TotalDataCount
= 0;
4742 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4743 /* BB find exact max data count below from sess structure BB */
4744 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4745 pSMB
->MaxSetupCount
= 0;
4749 pSMB
->Reserved2
= 0;
4750 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4751 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4752 pSMB
->DataCount
= 0;
4753 pSMB
->DataOffset
= 0;
4754 pSMB
->SetupCount
= 1;
4755 pSMB
->Reserved3
= 0;
4756 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4757 byte_count
= params
+ 1 /* pad */ ;
4758 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4759 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4760 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO
);
4761 pSMB
->Reserved4
= 0;
4762 inc_rfc1001_len(pSMB
, byte_count
);
4763 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4765 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4766 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4768 cifs_dbg(FYI
, "error %d in QueryInternalInfo\n", rc
);
4770 /* decode response */
4771 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4772 /* BB also check enough total bytes returned */
4773 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
4774 /* If rc should we check for EOPNOSUPP and
4775 disable the srvino flag? or in caller? */
4776 rc
= -EIO
; /* bad smb */
4778 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4779 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
4780 struct file_internal_info
*pfinfo
;
4781 /* BB Do we need a cast or hash here ? */
4783 cifs_dbg(FYI
, "Illegal size ret in QryIntrnlInf\n");
4785 goto GetInodeNumOut
;
4787 pfinfo
= (struct file_internal_info
*)
4788 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
4789 *inode_number
= le64_to_cpu(pfinfo
->UniqueId
);
4793 cifs_buf_release(pSMB
);
4795 goto GetInodeNumberRetry
;
4799 /* parses DFS refferal V3 structure
4800 * caller is responsible for freeing target_nodes
4803 * on failure - errno
4806 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
,
4807 unsigned int *num_of_nodes
,
4808 struct dfs_info3_param
**target_nodes
,
4809 const struct nls_table
*nls_codepage
, int remap
,
4810 const char *searchName
)
4815 struct dfs_referral_level_3
*ref
;
4817 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4821 *num_of_nodes
= le16_to_cpu(pSMBr
->NumberOfReferrals
);
4823 if (*num_of_nodes
< 1) {
4824 cifs_dbg(VFS
, "num_referrals: must be at least > 0, but we get num_referrals = %d\n",
4827 goto parse_DFS_referrals_exit
;
4830 ref
= (struct dfs_referral_level_3
*) &(pSMBr
->referrals
);
4831 if (ref
->VersionNumber
!= cpu_to_le16(3)) {
4832 cifs_dbg(VFS
, "Referrals of V%d version are not supported, should be V3\n",
4833 le16_to_cpu(ref
->VersionNumber
));
4835 goto parse_DFS_referrals_exit
;
4838 /* get the upper boundary of the resp buffer */
4839 data_end
= (char *)(&(pSMBr
->PathConsumed
)) +
4840 le16_to_cpu(pSMBr
->t2
.DataCount
);
4842 cifs_dbg(FYI
, "num_referrals: %d dfs flags: 0x%x ...\n",
4843 *num_of_nodes
, le32_to_cpu(pSMBr
->DFSFlags
));
4845 *target_nodes
= kcalloc(*num_of_nodes
, sizeof(struct dfs_info3_param
),
4847 if (*target_nodes
== NULL
) {
4849 goto parse_DFS_referrals_exit
;
4852 /* collect necessary data from referrals */
4853 for (i
= 0; i
< *num_of_nodes
; i
++) {
4856 struct dfs_info3_param
*node
= (*target_nodes
)+i
;
4858 node
->flags
= le32_to_cpu(pSMBr
->DFSFlags
);
4860 __le16
*tmp
= kmalloc(strlen(searchName
)*2 + 2,
4864 goto parse_DFS_referrals_exit
;
4866 cifsConvertToUTF16((__le16
*) tmp
, searchName
,
4867 PATH_MAX
, nls_codepage
, remap
);
4868 node
->path_consumed
= cifs_utf16_bytes(tmp
,
4869 le16_to_cpu(pSMBr
->PathConsumed
),
4873 node
->path_consumed
= le16_to_cpu(pSMBr
->PathConsumed
);
4875 node
->server_type
= le16_to_cpu(ref
->ServerType
);
4876 node
->ref_flag
= le16_to_cpu(ref
->ReferralEntryFlags
);
4879 temp
= (char *)ref
+ le16_to_cpu(ref
->DfsPathOffset
);
4880 max_len
= data_end
- temp
;
4881 node
->path_name
= cifs_strndup_from_utf16(temp
, max_len
,
4882 is_unicode
, nls_codepage
);
4883 if (!node
->path_name
) {
4885 goto parse_DFS_referrals_exit
;
4888 /* copy link target UNC */
4889 temp
= (char *)ref
+ le16_to_cpu(ref
->NetworkAddressOffset
);
4890 max_len
= data_end
- temp
;
4891 node
->node_name
= cifs_strndup_from_utf16(temp
, max_len
,
4892 is_unicode
, nls_codepage
);
4893 if (!node
->node_name
) {
4895 goto parse_DFS_referrals_exit
;
4901 parse_DFS_referrals_exit
:
4903 free_dfs_info_array(*target_nodes
, *num_of_nodes
);
4904 *target_nodes
= NULL
;
4911 CIFSGetDFSRefer(const unsigned int xid
, struct cifs_ses
*ses
,
4912 const char *search_name
, struct dfs_info3_param
**target_nodes
,
4913 unsigned int *num_of_nodes
,
4914 const struct nls_table
*nls_codepage
, int remap
)
4916 /* TRANS2_GET_DFS_REFERRAL */
4917 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
4918 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
4922 __u16 params
, byte_count
;
4924 *target_nodes
= NULL
;
4926 cifs_dbg(FYI
, "In GetDFSRefer the path %s\n", search_name
);
4930 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, NULL
, (void **) &pSMB
,
4935 /* server pointer checked in called function,
4936 but should never be null here anyway */
4937 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
4938 pSMB
->hdr
.Tid
= ses
->ipc_tid
;
4939 pSMB
->hdr
.Uid
= ses
->Suid
;
4940 if (ses
->capabilities
& CAP_STATUS32
)
4941 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
4942 if (ses
->capabilities
& CAP_DFS
)
4943 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
4945 if (ses
->capabilities
& CAP_UNICODE
) {
4946 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
4948 cifsConvertToUTF16((__le16
*) pSMB
->RequestFileName
,
4949 search_name
, PATH_MAX
, nls_codepage
,
4951 name_len
++; /* trailing null */
4953 } else { /* BB improve the check for buffer overruns BB */
4954 name_len
= strnlen(search_name
, PATH_MAX
);
4955 name_len
++; /* trailing null */
4956 strncpy(pSMB
->RequestFileName
, search_name
, name_len
);
4959 if (ses
->server
->sign
)
4960 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
4962 pSMB
->hdr
.Uid
= ses
->Suid
;
4964 params
= 2 /* level */ + name_len
/*includes null */ ;
4965 pSMB
->TotalDataCount
= 0;
4966 pSMB
->DataCount
= 0;
4967 pSMB
->DataOffset
= 0;
4968 pSMB
->MaxParameterCount
= 0;
4969 /* BB find exact max SMB PDU from sess structure BB */
4970 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4971 pSMB
->MaxSetupCount
= 0;
4975 pSMB
->Reserved2
= 0;
4976 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4977 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
4978 pSMB
->SetupCount
= 1;
4979 pSMB
->Reserved3
= 0;
4980 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
4981 byte_count
= params
+ 3 /* pad */ ;
4982 pSMB
->ParameterCount
= cpu_to_le16(params
);
4983 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4984 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
4985 inc_rfc1001_len(pSMB
, byte_count
);
4986 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4988 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
4989 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4991 cifs_dbg(FYI
, "Send error in GetDFSRefer = %d\n", rc
);
4994 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4996 /* BB Also check if enough total bytes returned? */
4997 if (rc
|| get_bcc(&pSMBr
->hdr
) < 17) {
4998 rc
= -EIO
; /* bad smb */
5002 cifs_dbg(FYI
, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
5003 get_bcc(&pSMBr
->hdr
), le16_to_cpu(pSMBr
->t2
.DataOffset
));
5005 /* parse returned result into more usable form */
5006 rc
= parse_DFS_referrals(pSMBr
, num_of_nodes
,
5007 target_nodes
, nls_codepage
, remap
,
5011 cifs_buf_release(pSMB
);
5019 /* Query File System Info such as free space to old servers such as Win 9x */
5021 SMBOldQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5022 struct kstatfs
*FSData
)
5024 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
5025 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5026 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5027 FILE_SYSTEM_ALLOC_INFO
*response_data
;
5029 int bytes_returned
= 0;
5030 __u16 params
, byte_count
;
5032 cifs_dbg(FYI
, "OldQFSInfo\n");
5034 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5039 params
= 2; /* level */
5040 pSMB
->TotalDataCount
= 0;
5041 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5042 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5043 pSMB
->MaxSetupCount
= 0;
5047 pSMB
->Reserved2
= 0;
5048 byte_count
= params
+ 1 /* pad */ ;
5049 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5050 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5051 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5052 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5053 pSMB
->DataCount
= 0;
5054 pSMB
->DataOffset
= 0;
5055 pSMB
->SetupCount
= 1;
5056 pSMB
->Reserved3
= 0;
5057 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5058 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_ALLOCATION
);
5059 inc_rfc1001_len(pSMB
, byte_count
);
5060 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5062 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5063 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5065 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5066 } else { /* decode response */
5067 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5069 if (rc
|| get_bcc(&pSMBr
->hdr
) < 18)
5070 rc
= -EIO
; /* bad smb */
5072 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5073 cifs_dbg(FYI
, "qfsinf resp BCC: %d Offset %d\n",
5074 get_bcc(&pSMBr
->hdr
), data_offset
);
5076 response_data
= (FILE_SYSTEM_ALLOC_INFO
*)
5077 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
5079 le16_to_cpu(response_data
->BytesPerSector
) *
5080 le32_to_cpu(response_data
->
5081 SectorsPerAllocationUnit
);
5083 le32_to_cpu(response_data
->TotalAllocationUnits
);
5084 FSData
->f_bfree
= FSData
->f_bavail
=
5085 le32_to_cpu(response_data
->FreeAllocationUnits
);
5086 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5087 (unsigned long long)FSData
->f_blocks
,
5088 (unsigned long long)FSData
->f_bfree
,
5092 cifs_buf_release(pSMB
);
5095 goto oldQFSInfoRetry
;
5101 CIFSSMBQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5102 struct kstatfs
*FSData
)
5104 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5105 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5106 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5107 FILE_SYSTEM_INFO
*response_data
;
5109 int bytes_returned
= 0;
5110 __u16 params
, byte_count
;
5112 cifs_dbg(FYI
, "In QFSInfo\n");
5114 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5119 params
= 2; /* level */
5120 pSMB
->TotalDataCount
= 0;
5121 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5122 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5123 pSMB
->MaxSetupCount
= 0;
5127 pSMB
->Reserved2
= 0;
5128 byte_count
= params
+ 1 /* pad */ ;
5129 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5130 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5131 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5132 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5133 pSMB
->DataCount
= 0;
5134 pSMB
->DataOffset
= 0;
5135 pSMB
->SetupCount
= 1;
5136 pSMB
->Reserved3
= 0;
5137 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5138 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
5139 inc_rfc1001_len(pSMB
, byte_count
);
5140 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5142 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5143 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5145 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5146 } else { /* decode response */
5147 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5149 if (rc
|| get_bcc(&pSMBr
->hdr
) < 24)
5150 rc
= -EIO
; /* bad smb */
5152 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5156 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5159 le32_to_cpu(response_data
->BytesPerSector
) *
5160 le32_to_cpu(response_data
->
5161 SectorsPerAllocationUnit
);
5163 le64_to_cpu(response_data
->TotalAllocationUnits
);
5164 FSData
->f_bfree
= FSData
->f_bavail
=
5165 le64_to_cpu(response_data
->FreeAllocationUnits
);
5166 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5167 (unsigned long long)FSData
->f_blocks
,
5168 (unsigned long long)FSData
->f_bfree
,
5172 cifs_buf_release(pSMB
);
5181 CIFSSMBQFSAttributeInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5183 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5184 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5185 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5186 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
5188 int bytes_returned
= 0;
5189 __u16 params
, byte_count
;
5191 cifs_dbg(FYI
, "In QFSAttributeInfo\n");
5193 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5198 params
= 2; /* level */
5199 pSMB
->TotalDataCount
= 0;
5200 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5201 /* BB find exact max SMB PDU from sess structure BB */
5202 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5203 pSMB
->MaxSetupCount
= 0;
5207 pSMB
->Reserved2
= 0;
5208 byte_count
= params
+ 1 /* pad */ ;
5209 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5210 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5211 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5212 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5213 pSMB
->DataCount
= 0;
5214 pSMB
->DataOffset
= 0;
5215 pSMB
->SetupCount
= 1;
5216 pSMB
->Reserved3
= 0;
5217 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5218 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
5219 inc_rfc1001_len(pSMB
, byte_count
);
5220 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5222 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5223 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5225 cifs_dbg(VFS
, "Send error in QFSAttributeInfo = %d\n", rc
);
5226 } else { /* decode response */
5227 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5229 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5230 /* BB also check if enough bytes returned */
5231 rc
= -EIO
; /* bad smb */
5233 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5235 (FILE_SYSTEM_ATTRIBUTE_INFO
5236 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5238 memcpy(&tcon
->fsAttrInfo
, response_data
,
5239 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO
));
5242 cifs_buf_release(pSMB
);
5245 goto QFSAttributeRetry
;
5251 CIFSSMBQFSDeviceInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5253 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5254 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5255 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5256 FILE_SYSTEM_DEVICE_INFO
*response_data
;
5258 int bytes_returned
= 0;
5259 __u16 params
, byte_count
;
5261 cifs_dbg(FYI
, "In QFSDeviceInfo\n");
5263 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5268 params
= 2; /* level */
5269 pSMB
->TotalDataCount
= 0;
5270 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5271 /* BB find exact max SMB PDU from sess structure BB */
5272 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5273 pSMB
->MaxSetupCount
= 0;
5277 pSMB
->Reserved2
= 0;
5278 byte_count
= params
+ 1 /* pad */ ;
5279 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5280 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5281 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5282 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5284 pSMB
->DataCount
= 0;
5285 pSMB
->DataOffset
= 0;
5286 pSMB
->SetupCount
= 1;
5287 pSMB
->Reserved3
= 0;
5288 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5289 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
5290 inc_rfc1001_len(pSMB
, byte_count
);
5291 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5293 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5294 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5296 cifs_dbg(FYI
, "Send error in QFSDeviceInfo = %d\n", rc
);
5297 } else { /* decode response */
5298 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5300 if (rc
|| get_bcc(&pSMBr
->hdr
) <
5301 sizeof(FILE_SYSTEM_DEVICE_INFO
))
5302 rc
= -EIO
; /* bad smb */
5304 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5306 (FILE_SYSTEM_DEVICE_INFO
*)
5307 (((char *) &pSMBr
->hdr
.Protocol
) +
5309 memcpy(&tcon
->fsDevInfo
, response_data
,
5310 sizeof(FILE_SYSTEM_DEVICE_INFO
));
5313 cifs_buf_release(pSMB
);
5316 goto QFSDeviceRetry
;
5322 CIFSSMBQFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5324 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5325 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5326 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5327 FILE_SYSTEM_UNIX_INFO
*response_data
;
5329 int bytes_returned
= 0;
5330 __u16 params
, byte_count
;
5332 cifs_dbg(FYI
, "In QFSUnixInfo\n");
5334 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5335 (void **) &pSMB
, (void **) &pSMBr
);
5339 params
= 2; /* level */
5340 pSMB
->TotalDataCount
= 0;
5341 pSMB
->DataCount
= 0;
5342 pSMB
->DataOffset
= 0;
5343 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5344 /* BB find exact max SMB PDU from sess structure BB */
5345 pSMB
->MaxDataCount
= cpu_to_le16(100);
5346 pSMB
->MaxSetupCount
= 0;
5350 pSMB
->Reserved2
= 0;
5351 byte_count
= params
+ 1 /* pad */ ;
5352 pSMB
->ParameterCount
= cpu_to_le16(params
);
5353 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5354 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5355 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5356 pSMB
->SetupCount
= 1;
5357 pSMB
->Reserved3
= 0;
5358 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5359 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
5360 inc_rfc1001_len(pSMB
, byte_count
);
5361 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5363 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5364 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5366 cifs_dbg(VFS
, "Send error in QFSUnixInfo = %d\n", rc
);
5367 } else { /* decode response */
5368 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5370 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5371 rc
= -EIO
; /* bad smb */
5373 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5375 (FILE_SYSTEM_UNIX_INFO
5376 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5378 memcpy(&tcon
->fsUnixInfo
, response_data
,
5379 sizeof(FILE_SYSTEM_UNIX_INFO
));
5382 cifs_buf_release(pSMB
);
5392 CIFSSMBSetFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
, __u64 cap
)
5394 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5395 TRANSACTION2_SETFSI_REQ
*pSMB
= NULL
;
5396 TRANSACTION2_SETFSI_RSP
*pSMBr
= NULL
;
5398 int bytes_returned
= 0;
5399 __u16 params
, param_offset
, offset
, byte_count
;
5401 cifs_dbg(FYI
, "In SETFSUnixInfo\n");
5403 /* BB switch to small buf init to save memory */
5404 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5405 (void **) &pSMB
, (void **) &pSMBr
);
5409 params
= 4; /* 2 bytes zero followed by info level. */
5410 pSMB
->MaxSetupCount
= 0;
5414 pSMB
->Reserved2
= 0;
5415 param_offset
= offsetof(struct smb_com_transaction2_setfsi_req
, FileNum
)
5417 offset
= param_offset
+ params
;
5419 pSMB
->MaxParameterCount
= cpu_to_le16(4);
5420 /* BB find exact max SMB PDU from sess structure BB */
5421 pSMB
->MaxDataCount
= cpu_to_le16(100);
5422 pSMB
->SetupCount
= 1;
5423 pSMB
->Reserved3
= 0;
5424 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FS_INFORMATION
);
5425 byte_count
= 1 /* pad */ + params
+ 12;
5427 pSMB
->DataCount
= cpu_to_le16(12);
5428 pSMB
->ParameterCount
= cpu_to_le16(params
);
5429 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5430 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5431 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5432 pSMB
->DataOffset
= cpu_to_le16(offset
);
5436 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_CIFS_UNIX_INFO
);
5439 pSMB
->ClientUnixMajor
= cpu_to_le16(CIFS_UNIX_MAJOR_VERSION
);
5440 pSMB
->ClientUnixMinor
= cpu_to_le16(CIFS_UNIX_MINOR_VERSION
);
5441 pSMB
->ClientUnixCap
= cpu_to_le64(cap
);
5443 inc_rfc1001_len(pSMB
, byte_count
);
5444 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5446 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5447 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5449 cifs_dbg(VFS
, "Send error in SETFSUnixInfo = %d\n", rc
);
5450 } else { /* decode response */
5451 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5453 rc
= -EIO
; /* bad smb */
5455 cifs_buf_release(pSMB
);
5458 goto SETFSUnixRetry
;
5466 CIFSSMBQFSPosixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5467 struct kstatfs
*FSData
)
5469 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5470 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5471 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5472 FILE_SYSTEM_POSIX_INFO
*response_data
;
5474 int bytes_returned
= 0;
5475 __u16 params
, byte_count
;
5477 cifs_dbg(FYI
, "In QFSPosixInfo\n");
5479 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5484 params
= 2; /* level */
5485 pSMB
->TotalDataCount
= 0;
5486 pSMB
->DataCount
= 0;
5487 pSMB
->DataOffset
= 0;
5488 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5489 /* BB find exact max SMB PDU from sess structure BB */
5490 pSMB
->MaxDataCount
= cpu_to_le16(100);
5491 pSMB
->MaxSetupCount
= 0;
5495 pSMB
->Reserved2
= 0;
5496 byte_count
= params
+ 1 /* pad */ ;
5497 pSMB
->ParameterCount
= cpu_to_le16(params
);
5498 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5499 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5500 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5501 pSMB
->SetupCount
= 1;
5502 pSMB
->Reserved3
= 0;
5503 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5504 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_FS_INFO
);
5505 inc_rfc1001_len(pSMB
, byte_count
);
5506 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5508 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5509 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5511 cifs_dbg(FYI
, "Send error in QFSUnixInfo = %d\n", rc
);
5512 } else { /* decode response */
5513 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5515 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5516 rc
= -EIO
; /* bad smb */
5518 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5520 (FILE_SYSTEM_POSIX_INFO
5521 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5524 le32_to_cpu(response_data
->BlockSize
);
5526 le64_to_cpu(response_data
->TotalBlocks
);
5528 le64_to_cpu(response_data
->BlocksAvail
);
5529 if (response_data
->UserBlocksAvail
== cpu_to_le64(-1)) {
5530 FSData
->f_bavail
= FSData
->f_bfree
;
5533 le64_to_cpu(response_data
->UserBlocksAvail
);
5535 if (response_data
->TotalFileNodes
!= cpu_to_le64(-1))
5537 le64_to_cpu(response_data
->TotalFileNodes
);
5538 if (response_data
->FreeFileNodes
!= cpu_to_le64(-1))
5540 le64_to_cpu(response_data
->FreeFileNodes
);
5543 cifs_buf_release(pSMB
);
5553 * We can not use write of zero bytes trick to set file size due to need for
5554 * large file support. Also note that this SetPathInfo is preferred to
5555 * SetFileInfo based method in next routine which is only needed to work around
5556 * a sharing violation bugin Samba which this routine can run into.
5559 CIFSSMBSetEOF(const unsigned int xid
, struct cifs_tcon
*tcon
,
5560 const char *file_name
, __u64 size
, struct cifs_sb_info
*cifs_sb
,
5561 bool set_allocation
)
5563 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5564 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5565 struct file_end_of_file_info
*parm_data
;
5568 int bytes_returned
= 0;
5569 int remap
= cifs_remap(cifs_sb
);
5571 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
5573 cifs_dbg(FYI
, "In SetEOF\n");
5575 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5580 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5582 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5583 PATH_MAX
, cifs_sb
->local_nls
, remap
);
5584 name_len
++; /* trailing null */
5586 } else { /* BB improve the check for buffer overruns BB */
5587 name_len
= strnlen(file_name
, PATH_MAX
);
5588 name_len
++; /* trailing null */
5589 strncpy(pSMB
->FileName
, file_name
, name_len
);
5591 params
= 6 + name_len
;
5592 data_count
= sizeof(struct file_end_of_file_info
);
5593 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5594 pSMB
->MaxDataCount
= cpu_to_le16(4100);
5595 pSMB
->MaxSetupCount
= 0;
5599 pSMB
->Reserved2
= 0;
5600 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5601 InformationLevel
) - 4;
5602 offset
= param_offset
+ params
;
5603 if (set_allocation
) {
5604 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5605 pSMB
->InformationLevel
=
5606 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5608 pSMB
->InformationLevel
=
5609 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5610 } else /* Set File Size */ {
5611 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5612 pSMB
->InformationLevel
=
5613 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5615 pSMB
->InformationLevel
=
5616 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5620 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
5622 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5623 pSMB
->DataOffset
= cpu_to_le16(offset
);
5624 pSMB
->SetupCount
= 1;
5625 pSMB
->Reserved3
= 0;
5626 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5627 byte_count
= 3 /* pad */ + params
+ data_count
;
5628 pSMB
->DataCount
= cpu_to_le16(data_count
);
5629 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5630 pSMB
->ParameterCount
= cpu_to_le16(params
);
5631 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5632 pSMB
->Reserved4
= 0;
5633 inc_rfc1001_len(pSMB
, byte_count
);
5634 parm_data
->FileSize
= cpu_to_le64(size
);
5635 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5636 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5637 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5639 cifs_dbg(FYI
, "SetPathInfo (file size) returned %d\n", rc
);
5641 cifs_buf_release(pSMB
);
5650 CIFSSMBSetFileSize(const unsigned int xid
, struct cifs_tcon
*tcon
,
5651 struct cifsFileInfo
*cfile
, __u64 size
, bool set_allocation
)
5653 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5654 struct file_end_of_file_info
*parm_data
;
5656 __u16 params
, param_offset
, offset
, byte_count
, count
;
5658 cifs_dbg(FYI
, "SetFileSize (via SetFileInfo) %lld\n",
5660 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5665 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)cfile
->pid
);
5666 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(cfile
->pid
>> 16));
5669 pSMB
->MaxSetupCount
= 0;
5673 pSMB
->Reserved2
= 0;
5674 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5675 offset
= param_offset
+ params
;
5677 count
= sizeof(struct file_end_of_file_info
);
5678 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5679 /* BB find exact max SMB PDU from sess structure BB */
5680 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5681 pSMB
->SetupCount
= 1;
5682 pSMB
->Reserved3
= 0;
5683 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5684 byte_count
= 3 /* pad */ + params
+ count
;
5685 pSMB
->DataCount
= cpu_to_le16(count
);
5686 pSMB
->ParameterCount
= cpu_to_le16(params
);
5687 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5688 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5689 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5691 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
)
5693 pSMB
->DataOffset
= cpu_to_le16(offset
);
5694 parm_data
->FileSize
= cpu_to_le64(size
);
5695 pSMB
->Fid
= cfile
->fid
.netfid
;
5696 if (set_allocation
) {
5697 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5698 pSMB
->InformationLevel
=
5699 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5701 pSMB
->InformationLevel
=
5702 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5703 } else /* Set File Size */ {
5704 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5705 pSMB
->InformationLevel
=
5706 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5708 pSMB
->InformationLevel
=
5709 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5711 pSMB
->Reserved4
= 0;
5712 inc_rfc1001_len(pSMB
, byte_count
);
5713 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5714 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5716 cifs_dbg(FYI
, "Send error in SetFileInfo (SetFileSize) = %d\n",
5720 /* Note: On -EAGAIN error only caller can retry on handle based calls
5721 since file handle passed in no longer valid */
5726 /* Some legacy servers such as NT4 require that the file times be set on
5727 an open handle, rather than by pathname - this is awkward due to
5728 potential access conflicts on the open, but it is unavoidable for these
5729 old servers since the only other choice is to go from 100 nanosecond DCE
5730 time and resort to the original setpathinfo level which takes the ancient
5731 DOS time format with 2 second granularity */
5733 CIFSSMBSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5734 const FILE_BASIC_INFO
*data
, __u16 fid
, __u32 pid_of_opener
)
5736 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5739 __u16 params
, param_offset
, offset
, byte_count
, count
;
5741 cifs_dbg(FYI
, "Set Times (via SetFileInfo)\n");
5742 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5747 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5748 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5751 pSMB
->MaxSetupCount
= 0;
5755 pSMB
->Reserved2
= 0;
5756 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5757 offset
= param_offset
+ params
;
5759 data_offset
= (char *)pSMB
+
5760 offsetof(struct smb_hdr
, Protocol
) + offset
;
5762 count
= sizeof(FILE_BASIC_INFO
);
5763 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5764 /* BB find max SMB PDU from sess */
5765 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5766 pSMB
->SetupCount
= 1;
5767 pSMB
->Reserved3
= 0;
5768 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5769 byte_count
= 3 /* pad */ + params
+ count
;
5770 pSMB
->DataCount
= cpu_to_le16(count
);
5771 pSMB
->ParameterCount
= cpu_to_le16(params
);
5772 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5773 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5774 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5775 pSMB
->DataOffset
= cpu_to_le16(offset
);
5777 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5778 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5780 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5781 pSMB
->Reserved4
= 0;
5782 inc_rfc1001_len(pSMB
, byte_count
);
5783 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5784 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5785 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5787 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5790 /* Note: On -EAGAIN error only caller can retry on handle based calls
5791 since file handle passed in no longer valid */
5797 CIFSSMBSetFileDisposition(const unsigned int xid
, struct cifs_tcon
*tcon
,
5798 bool delete_file
, __u16 fid
, __u32 pid_of_opener
)
5800 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5803 __u16 params
, param_offset
, offset
, byte_count
, count
;
5805 cifs_dbg(FYI
, "Set File Disposition (via SetFileInfo)\n");
5806 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5811 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5812 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5815 pSMB
->MaxSetupCount
= 0;
5819 pSMB
->Reserved2
= 0;
5820 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5821 offset
= param_offset
+ params
;
5823 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5826 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5827 /* BB find max SMB PDU from sess */
5828 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5829 pSMB
->SetupCount
= 1;
5830 pSMB
->Reserved3
= 0;
5831 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5832 byte_count
= 3 /* pad */ + params
+ count
;
5833 pSMB
->DataCount
= cpu_to_le16(count
);
5834 pSMB
->ParameterCount
= cpu_to_le16(params
);
5835 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5836 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5837 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5838 pSMB
->DataOffset
= cpu_to_le16(offset
);
5840 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO
);
5841 pSMB
->Reserved4
= 0;
5842 inc_rfc1001_len(pSMB
, byte_count
);
5843 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5844 *data_offset
= delete_file
? 1 : 0;
5845 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5847 cifs_dbg(FYI
, "Send error in SetFileDisposition = %d\n", rc
);
5853 CIFSSMBSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5854 const char *fileName
, const FILE_BASIC_INFO
*data
,
5855 const struct nls_table
*nls_codepage
, int remap
)
5857 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5858 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5861 int bytes_returned
= 0;
5863 __u16 params
, param_offset
, offset
, byte_count
, count
;
5865 cifs_dbg(FYI
, "In SetTimes\n");
5868 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5873 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5875 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5876 PATH_MAX
, nls_codepage
, remap
);
5877 name_len
++; /* trailing null */
5879 } else { /* BB improve the check for buffer overruns BB */
5880 name_len
= strnlen(fileName
, PATH_MAX
);
5881 name_len
++; /* trailing null */
5882 strncpy(pSMB
->FileName
, fileName
, name_len
);
5885 params
= 6 + name_len
;
5886 count
= sizeof(FILE_BASIC_INFO
);
5887 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5888 /* BB find max SMB PDU from sess structure BB */
5889 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5890 pSMB
->MaxSetupCount
= 0;
5894 pSMB
->Reserved2
= 0;
5895 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5896 InformationLevel
) - 4;
5897 offset
= param_offset
+ params
;
5898 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5899 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5900 pSMB
->DataOffset
= cpu_to_le16(offset
);
5901 pSMB
->SetupCount
= 1;
5902 pSMB
->Reserved3
= 0;
5903 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5904 byte_count
= 3 /* pad */ + params
+ count
;
5906 pSMB
->DataCount
= cpu_to_le16(count
);
5907 pSMB
->ParameterCount
= cpu_to_le16(params
);
5908 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5909 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5910 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5911 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5913 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5914 pSMB
->Reserved4
= 0;
5915 inc_rfc1001_len(pSMB
, byte_count
);
5916 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5917 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5918 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5919 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5921 cifs_dbg(FYI
, "SetPathInfo (times) returned %d\n", rc
);
5923 cifs_buf_release(pSMB
);
5931 /* Can not be used to set time stamps yet (due to old DOS time format) */
5932 /* Can be used to set attributes */
5933 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5934 handling it anyway and NT4 was what we thought it would be needed for
5935 Do not delete it until we prove whether needed for Win9x though */
5937 CIFSSMBSetAttrLegacy(unsigned int xid
, struct cifs_tcon
*tcon
, char *fileName
,
5938 __u16 dos_attrs
, const struct nls_table
*nls_codepage
)
5940 SETATTR_REQ
*pSMB
= NULL
;
5941 SETATTR_RSP
*pSMBr
= NULL
;
5946 cifs_dbg(FYI
, "In SetAttrLegacy\n");
5949 rc
= smb_init(SMB_COM_SETATTR
, 8, tcon
, (void **) &pSMB
,
5954 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5956 ConvertToUTF16((__le16
*) pSMB
->fileName
, fileName
,
5957 PATH_MAX
, nls_codepage
);
5958 name_len
++; /* trailing null */
5960 } else { /* BB improve the check for buffer overruns BB */
5961 name_len
= strnlen(fileName
, PATH_MAX
);
5962 name_len
++; /* trailing null */
5963 strncpy(pSMB
->fileName
, fileName
, name_len
);
5965 pSMB
->attr
= cpu_to_le16(dos_attrs
);
5966 pSMB
->BufferFormat
= 0x04;
5967 inc_rfc1001_len(pSMB
, name_len
+ 1);
5968 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
5969 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5970 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5972 cifs_dbg(FYI
, "Error in LegacySetAttr = %d\n", rc
);
5974 cifs_buf_release(pSMB
);
5977 goto SetAttrLgcyRetry
;
5981 #endif /* temporarily unneeded SetAttr legacy function */
5984 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO
*data_offset
,
5985 const struct cifs_unix_set_info_args
*args
)
5987 u64 uid
= NO_CHANGE_64
, gid
= NO_CHANGE_64
;
5988 u64 mode
= args
->mode
;
5990 if (uid_valid(args
->uid
))
5991 uid
= from_kuid(&init_user_ns
, args
->uid
);
5992 if (gid_valid(args
->gid
))
5993 gid
= from_kgid(&init_user_ns
, args
->gid
);
5996 * Samba server ignores set of file size to zero due to bugs in some
5997 * older clients, but we should be precise - we use SetFileSize to
5998 * set file size and do not want to truncate file size to zero
5999 * accidentally as happened on one Samba server beta by putting
6000 * zero instead of -1 here
6002 data_offset
->EndOfFile
= cpu_to_le64(NO_CHANGE_64
);
6003 data_offset
->NumOfBytes
= cpu_to_le64(NO_CHANGE_64
);
6004 data_offset
->LastStatusChange
= cpu_to_le64(args
->ctime
);
6005 data_offset
->LastAccessTime
= cpu_to_le64(args
->atime
);
6006 data_offset
->LastModificationTime
= cpu_to_le64(args
->mtime
);
6007 data_offset
->Uid
= cpu_to_le64(uid
);
6008 data_offset
->Gid
= cpu_to_le64(gid
);
6009 /* better to leave device as zero when it is */
6010 data_offset
->DevMajor
= cpu_to_le64(MAJOR(args
->device
));
6011 data_offset
->DevMinor
= cpu_to_le64(MINOR(args
->device
));
6012 data_offset
->Permissions
= cpu_to_le64(mode
);
6015 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
6016 else if (S_ISDIR(mode
))
6017 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
6018 else if (S_ISLNK(mode
))
6019 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
6020 else if (S_ISCHR(mode
))
6021 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
6022 else if (S_ISBLK(mode
))
6023 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
6024 else if (S_ISFIFO(mode
))
6025 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
6026 else if (S_ISSOCK(mode
))
6027 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
6031 CIFSSMBUnixSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6032 const struct cifs_unix_set_info_args
*args
,
6033 u16 fid
, u32 pid_of_opener
)
6035 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
6038 u16 params
, param_offset
, offset
, byte_count
, count
;
6040 cifs_dbg(FYI
, "Set Unix Info (via SetFileInfo)\n");
6041 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
6046 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
6047 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
6050 pSMB
->MaxSetupCount
= 0;
6054 pSMB
->Reserved2
= 0;
6055 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
6056 offset
= param_offset
+ params
;
6058 data_offset
= (char *)pSMB
+
6059 offsetof(struct smb_hdr
, Protocol
) + offset
;
6061 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6063 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6064 /* BB find max SMB PDU from sess */
6065 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6066 pSMB
->SetupCount
= 1;
6067 pSMB
->Reserved3
= 0;
6068 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
6069 byte_count
= 3 /* pad */ + params
+ count
;
6070 pSMB
->DataCount
= cpu_to_le16(count
);
6071 pSMB
->ParameterCount
= cpu_to_le16(params
);
6072 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6073 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6074 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6075 pSMB
->DataOffset
= cpu_to_le16(offset
);
6077 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6078 pSMB
->Reserved4
= 0;
6079 inc_rfc1001_len(pSMB
, byte_count
);
6080 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6082 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO
*)data_offset
, args
);
6084 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
6086 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
6089 /* Note: On -EAGAIN error only caller can retry on handle based calls
6090 since file handle passed in no longer valid */
6096 CIFSSMBUnixSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6097 const char *file_name
,
6098 const struct cifs_unix_set_info_args
*args
,
6099 const struct nls_table
*nls_codepage
, int remap
)
6101 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
6102 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
6105 int bytes_returned
= 0;
6106 FILE_UNIX_BASIC_INFO
*data_offset
;
6107 __u16 params
, param_offset
, offset
, count
, byte_count
;
6109 cifs_dbg(FYI
, "In SetUID/GID/Mode\n");
6111 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6116 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6118 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
6119 PATH_MAX
, nls_codepage
, remap
);
6120 name_len
++; /* trailing null */
6122 } else { /* BB improve the check for buffer overruns BB */
6123 name_len
= strnlen(file_name
, PATH_MAX
);
6124 name_len
++; /* trailing null */
6125 strncpy(pSMB
->FileName
, file_name
, name_len
);
6128 params
= 6 + name_len
;
6129 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6130 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6131 /* BB find max SMB PDU from sess structure BB */
6132 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6133 pSMB
->MaxSetupCount
= 0;
6137 pSMB
->Reserved2
= 0;
6138 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6139 InformationLevel
) - 4;
6140 offset
= param_offset
+ params
;
6142 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
6144 memset(data_offset
, 0, count
);
6145 pSMB
->DataOffset
= cpu_to_le16(offset
);
6146 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6147 pSMB
->SetupCount
= 1;
6148 pSMB
->Reserved3
= 0;
6149 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6150 byte_count
= 3 /* pad */ + params
+ count
;
6151 pSMB
->ParameterCount
= cpu_to_le16(params
);
6152 pSMB
->DataCount
= cpu_to_le16(count
);
6153 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6154 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6155 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6156 pSMB
->Reserved4
= 0;
6157 inc_rfc1001_len(pSMB
, byte_count
);
6159 cifs_fill_unix_set_info(data_offset
, args
);
6161 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6162 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6163 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6165 cifs_dbg(FYI
, "SetPathInfo (perms) returned %d\n", rc
);
6167 cifs_buf_release(pSMB
);
6173 #ifdef CONFIG_CIFS_XATTR
6175 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6176 * function used by listxattr and getxattr type calls. When ea_name is set,
6177 * it looks for that attribute name and stuffs that value into the EAData
6178 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6179 * buffer. In both cases, the return value is either the length of the
6180 * resulting data or a negative error code. If EAData is a NULL pointer then
6181 * the data isn't copied to it, but the length is returned.
6184 CIFSSMBQAllEAs(const unsigned int xid
, struct cifs_tcon
*tcon
,
6185 const unsigned char *searchName
, const unsigned char *ea_name
,
6186 char *EAData
, size_t buf_size
,
6187 const struct nls_table
*nls_codepage
, int remap
)
6189 /* BB assumes one setup word */
6190 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
6191 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
6195 struct fealist
*ea_response_data
;
6196 struct fea
*temp_fea
;
6199 __u16 params
, byte_count
, data_offset
;
6200 unsigned int ea_name_len
= ea_name
? strlen(ea_name
) : 0;
6202 cifs_dbg(FYI
, "In Query All EAs path %s\n", searchName
);
6204 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6209 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6211 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
6212 PATH_MAX
, nls_codepage
, remap
);
6213 list_len
++; /* trailing null */
6215 } else { /* BB improve the check for buffer overruns BB */
6216 list_len
= strnlen(searchName
, PATH_MAX
);
6217 list_len
++; /* trailing null */
6218 strncpy(pSMB
->FileName
, searchName
, list_len
);
6221 params
= 2 /* level */ + 4 /* reserved */ + list_len
/* includes NUL */;
6222 pSMB
->TotalDataCount
= 0;
6223 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6224 /* BB find exact max SMB PDU from sess structure BB */
6225 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
6226 pSMB
->MaxSetupCount
= 0;
6230 pSMB
->Reserved2
= 0;
6231 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
6232 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
6233 pSMB
->DataCount
= 0;
6234 pSMB
->DataOffset
= 0;
6235 pSMB
->SetupCount
= 1;
6236 pSMB
->Reserved3
= 0;
6237 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
6238 byte_count
= params
+ 1 /* pad */ ;
6239 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
6240 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6241 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
6242 pSMB
->Reserved4
= 0;
6243 inc_rfc1001_len(pSMB
, byte_count
);
6244 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6246 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6247 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6249 cifs_dbg(FYI
, "Send error in QueryAllEAs = %d\n", rc
);
6254 /* BB also check enough total bytes returned */
6255 /* BB we need to improve the validity checking
6256 of these trans2 responses */
6258 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
6259 if (rc
|| get_bcc(&pSMBr
->hdr
) < 4) {
6260 rc
= -EIO
; /* bad smb */
6264 /* check that length of list is not more than bcc */
6265 /* check that each entry does not go beyond length
6267 /* check that each element of each entry does not
6268 go beyond end of list */
6269 /* validate_trans2_offsets() */
6270 /* BB check if start of smb + data_offset > &bcc+ bcc */
6272 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
6273 ea_response_data
= (struct fealist
*)
6274 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
6276 list_len
= le32_to_cpu(ea_response_data
->list_len
);
6277 cifs_dbg(FYI
, "ea length %d\n", list_len
);
6278 if (list_len
<= 8) {
6279 cifs_dbg(FYI
, "empty EA list returned from server\n");
6280 /* didn't find the named attribute */
6286 /* make sure list_len doesn't go past end of SMB */
6287 end_of_smb
= (char *)pByteArea(&pSMBr
->hdr
) + get_bcc(&pSMBr
->hdr
);
6288 if ((char *)ea_response_data
+ list_len
> end_of_smb
) {
6289 cifs_dbg(FYI
, "EA list appears to go beyond SMB\n");
6294 /* account for ea list len */
6296 temp_fea
= ea_response_data
->list
;
6297 temp_ptr
= (char *)temp_fea
;
6298 while (list_len
> 0) {
6299 unsigned int name_len
;
6304 /* make sure we can read name_len and value_len */
6306 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6311 name_len
= temp_fea
->name_len
;
6312 value_len
= le16_to_cpu(temp_fea
->value_len
);
6313 list_len
-= name_len
+ 1 + value_len
;
6315 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6321 if (ea_name_len
== name_len
&&
6322 memcmp(ea_name
, temp_ptr
, name_len
) == 0) {
6323 temp_ptr
+= name_len
+ 1;
6327 if ((size_t)value_len
> buf_size
) {
6331 memcpy(EAData
, temp_ptr
, value_len
);
6335 /* account for prefix user. and trailing null */
6336 rc
+= (5 + 1 + name_len
);
6337 if (rc
< (int) buf_size
) {
6338 memcpy(EAData
, "user.", 5);
6340 memcpy(EAData
, temp_ptr
, name_len
);
6342 /* null terminate name */
6345 } else if (buf_size
== 0) {
6346 /* skip copy - calc size only */
6348 /* stop before overrun buffer */
6353 temp_ptr
+= name_len
+ 1 + value_len
;
6354 temp_fea
= (struct fea
*)temp_ptr
;
6357 /* didn't find the named attribute */
6362 cifs_buf_release(pSMB
);
6370 CIFSSMBSetEA(const unsigned int xid
, struct cifs_tcon
*tcon
,
6371 const char *fileName
, const char *ea_name
, const void *ea_value
,
6372 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
,
6375 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
6376 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
6377 struct fealist
*parm_data
;
6380 int bytes_returned
= 0;
6381 __u16 params
, param_offset
, byte_count
, offset
, count
;
6383 cifs_dbg(FYI
, "In SetEA\n");
6385 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6390 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6392 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
6393 PATH_MAX
, nls_codepage
, remap
);
6394 name_len
++; /* trailing null */
6396 } else { /* BB improve the check for buffer overruns BB */
6397 name_len
= strnlen(fileName
, PATH_MAX
);
6398 name_len
++; /* trailing null */
6399 strncpy(pSMB
->FileName
, fileName
, name_len
);
6402 params
= 6 + name_len
;
6404 /* done calculating parms using name_len of file name,
6405 now use name_len to calculate length of ea name
6406 we are going to create in the inode xattrs */
6407 if (ea_name
== NULL
)
6410 name_len
= strnlen(ea_name
, 255);
6412 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
;
6413 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6414 /* BB find max SMB PDU from sess */
6415 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6416 pSMB
->MaxSetupCount
= 0;
6420 pSMB
->Reserved2
= 0;
6421 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6422 InformationLevel
) - 4;
6423 offset
= param_offset
+ params
;
6424 pSMB
->InformationLevel
=
6425 cpu_to_le16(SMB_SET_FILE_EA
);
6427 parm_data
= (void *)pSMB
+ offsetof(struct smb_hdr
, Protocol
) + offset
;
6428 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6429 pSMB
->DataOffset
= cpu_to_le16(offset
);
6430 pSMB
->SetupCount
= 1;
6431 pSMB
->Reserved3
= 0;
6432 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6433 byte_count
= 3 /* pad */ + params
+ count
;
6434 pSMB
->DataCount
= cpu_to_le16(count
);
6435 parm_data
->list_len
= cpu_to_le32(count
);
6436 parm_data
->list
[0].EA_flags
= 0;
6437 /* we checked above that name len is less than 255 */
6438 parm_data
->list
[0].name_len
= (__u8
)name_len
;
6439 /* EA names are always ASCII */
6441 strncpy(parm_data
->list
[0].name
, ea_name
, name_len
);
6442 parm_data
->list
[0].name
[name_len
] = 0;
6443 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
6444 /* caller ensures that ea_value_len is less than 64K but
6445 we need to ensure that it fits within the smb */
6447 /*BB add length check to see if it would fit in
6448 negotiated SMB buffer size BB */
6449 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6451 memcpy(parm_data
->list
[0].name
+name_len
+1,
6452 ea_value
, ea_value_len
);
6454 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6455 pSMB
->ParameterCount
= cpu_to_le16(params
);
6456 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6457 pSMB
->Reserved4
= 0;
6458 inc_rfc1001_len(pSMB
, byte_count
);
6459 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6460 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6461 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6463 cifs_dbg(FYI
, "SetPathInfo (EA) returned %d\n", rc
);
6465 cifs_buf_release(pSMB
);
6474 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6476 * Years ago the kernel added a "dnotify" function for Samba server,
6477 * to allow network clients (such as Windows) to display updated
6478 * lists of files in directory listings automatically when
6479 * files are added by one user when another user has the
6480 * same directory open on their desktop. The Linux cifs kernel
6481 * client hooked into the kernel side of this interface for
6482 * the same reason, but ironically when the VFS moved from
6483 * "dnotify" to "inotify" it became harder to plug in Linux
6484 * network file system clients (the most obvious use case
6485 * for notify interfaces is when multiple users can update
6486 * the contents of the same directory - exactly what network
6487 * file systems can do) although the server (Samba) could
6488 * still use it. For the short term we leave the worker
6489 * function ifdeffed out (below) until inotify is fixed
6490 * in the VFS to make it easier to plug in network file
6491 * system clients. If inotify turns out to be permanently
6492 * incompatible for network fs clients, we could instead simply
6493 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6495 int CIFSSMBNotify(const unsigned int xid
, struct cifs_tcon
*tcon
,
6496 const int notify_subdirs
, const __u16 netfid
,
6497 __u32 filter
, struct file
*pfile
, int multishot
,
6498 const struct nls_table
*nls_codepage
)
6501 struct smb_com_transaction_change_notify_req
*pSMB
= NULL
;
6502 struct smb_com_ntransaction_change_notify_rsp
*pSMBr
= NULL
;
6503 struct dir_notify_req
*dnotify_req
;
6506 cifs_dbg(FYI
, "In CIFSSMBNotify for file handle %d\n", (int)netfid
);
6507 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
6512 pSMB
->TotalParameterCount
= 0 ;
6513 pSMB
->TotalDataCount
= 0;
6514 pSMB
->MaxParameterCount
= cpu_to_le32(2);
6515 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
6516 pSMB
->MaxSetupCount
= 4;
6518 pSMB
->ParameterOffset
= 0;
6519 pSMB
->DataCount
= 0;
6520 pSMB
->DataOffset
= 0;
6521 pSMB
->SetupCount
= 4; /* single byte does not need le conversion */
6522 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE
);
6523 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6525 pSMB
->WatchTree
= 1; /* one byte - no le conversion needed */
6526 pSMB
->Reserved2
= 0;
6527 pSMB
->CompletionFilter
= cpu_to_le32(filter
);
6528 pSMB
->Fid
= netfid
; /* file handle always le */
6529 pSMB
->ByteCount
= 0;
6531 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6532 (struct smb_hdr
*)pSMBr
, &bytes_returned
,
6535 cifs_dbg(FYI
, "Error in Notify = %d\n", rc
);
6537 /* Add file to outstanding requests */
6538 /* BB change to kmem cache alloc */
6539 dnotify_req
= kmalloc(
6540 sizeof(struct dir_notify_req
),
6543 dnotify_req
->Pid
= pSMB
->hdr
.Pid
;
6544 dnotify_req
->PidHigh
= pSMB
->hdr
.PidHigh
;
6545 dnotify_req
->Mid
= pSMB
->hdr
.Mid
;
6546 dnotify_req
->Tid
= pSMB
->hdr
.Tid
;
6547 dnotify_req
->Uid
= pSMB
->hdr
.Uid
;
6548 dnotify_req
->netfid
= netfid
;
6549 dnotify_req
->pfile
= pfile
;
6550 dnotify_req
->filter
= filter
;
6551 dnotify_req
->multishot
= multishot
;
6552 spin_lock(&GlobalMid_Lock
);
6553 list_add_tail(&dnotify_req
->lhead
,
6554 &GlobalDnotifyReqList
);
6555 spin_unlock(&GlobalMid_Lock
);
6559 cifs_buf_release(pSMB
);
6562 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */