4 * Copyright (C) International Business Machines Corp., 2002,2010
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Contains the routines for constructing the SMB PDUs themselves
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
25 /* These are mostly routines that operate on a pathname, or on a tree id */
26 /* (mounted volume), but there are eight handle based routines which must be */
27 /* treated slightly differently for reconnection purposes since we never */
28 /* want to reuse a stale file handle and only the caller knows the file info */
31 #include <linux/kernel.h>
32 #include <linux/vfs.h>
33 #include <linux/slab.h>
34 #include <linux/posix_acl_xattr.h>
35 #include <linux/pagemap.h>
36 #include <linux/swap.h>
37 #include <linux/task_io_accounting_ops.h>
38 #include <asm/uaccess.h>
42 #include "cifsproto.h"
43 #include "cifs_unicode.h"
44 #include "cifs_debug.h"
47 #ifdef CONFIG_CIFS_POSIX
52 #ifdef CONFIG_CIFS_WEAK_PW_HASH
53 {LANMAN_PROT
, "\2LM1.2X002"},
54 {LANMAN2_PROT
, "\2LANMAN2.1"},
55 #endif /* weak password hashing for legacy clients */
56 {CIFS_PROT
, "\2NT LM 0.12"},
57 {POSIX_PROT
, "\2POSIX 2"},
65 #ifdef CONFIG_CIFS_WEAK_PW_HASH
66 {LANMAN_PROT
, "\2LM1.2X002"},
67 {LANMAN2_PROT
, "\2LANMAN2.1"},
68 #endif /* weak password hashing for legacy clients */
69 {CIFS_PROT
, "\2NT LM 0.12"},
74 /* define the number of elements in the cifs dialect array */
75 #ifdef CONFIG_CIFS_POSIX
76 #ifdef CONFIG_CIFS_WEAK_PW_HASH
77 #define CIFS_NUM_PROT 4
79 #define CIFS_NUM_PROT 2
80 #endif /* CIFS_WEAK_PW_HASH */
82 #ifdef CONFIG_CIFS_WEAK_PW_HASH
83 #define CIFS_NUM_PROT 3
85 #define CIFS_NUM_PROT 1
86 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
87 #endif /* CIFS_POSIX */
90 * Mark as invalid, all open files on tree connections since they
91 * were closed when session to server was lost.
94 cifs_mark_open_files_invalid(struct cifs_tcon
*tcon
)
96 struct cifsFileInfo
*open_file
= NULL
;
97 struct list_head
*tmp
;
98 struct list_head
*tmp1
;
100 /* list all files open on tree connection and mark them invalid */
101 spin_lock(&cifs_file_list_lock
);
102 list_for_each_safe(tmp
, tmp1
, &tcon
->openFileList
) {
103 open_file
= list_entry(tmp
, struct cifsFileInfo
, tlist
);
104 open_file
->invalidHandle
= true;
105 open_file
->oplock_break_cancelled
= true;
107 spin_unlock(&cifs_file_list_lock
);
109 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
114 /* reconnect the socket, tcon, and smb session if needed */
116 cifs_reconnect_tcon(struct cifs_tcon
*tcon
, int smb_command
)
119 struct cifs_ses
*ses
;
120 struct TCP_Server_Info
*server
;
121 struct nls_table
*nls_codepage
;
124 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
125 * tcp and smb session status done differently for those three - in the
132 server
= ses
->server
;
135 * only tree disconnect, open, and write, (and ulogoff which does not
136 * have tcon) are allowed as we start force umount
138 if (tcon
->tidStatus
== CifsExiting
) {
139 if (smb_command
!= SMB_COM_WRITE_ANDX
&&
140 smb_command
!= SMB_COM_OPEN_ANDX
&&
141 smb_command
!= SMB_COM_TREE_DISCONNECT
) {
142 cifs_dbg(FYI
, "can not send cmd %d while umounting\n",
149 * Give demultiplex thread up to 10 seconds to reconnect, should be
150 * greater than cifs socket timeout which is 7 seconds
152 while (server
->tcpStatus
== CifsNeedReconnect
) {
153 wait_event_interruptible_timeout(server
->response_q
,
154 (server
->tcpStatus
!= CifsNeedReconnect
), 10 * HZ
);
156 /* are we still trying to reconnect? */
157 if (server
->tcpStatus
!= CifsNeedReconnect
)
161 * on "soft" mounts we wait once. Hard mounts keep
162 * retrying until process is killed or server comes
166 cifs_dbg(FYI
, "gave up waiting on reconnect in smb_init\n");
171 if (!ses
->need_reconnect
&& !tcon
->need_reconnect
)
174 nls_codepage
= load_nls_default();
177 * need to prevent multiple threads trying to simultaneously
178 * reconnect the same SMB session
180 mutex_lock(&ses
->session_mutex
);
181 rc
= cifs_negotiate_protocol(0, ses
);
182 if (rc
== 0 && ses
->need_reconnect
)
183 rc
= cifs_setup_session(0, ses
, nls_codepage
);
185 /* do we need to reconnect tcon? */
186 if (rc
|| !tcon
->need_reconnect
) {
187 mutex_unlock(&ses
->session_mutex
);
191 cifs_mark_open_files_invalid(tcon
);
192 rc
= CIFSTCon(0, ses
, tcon
->treeName
, tcon
, nls_codepage
);
193 mutex_unlock(&ses
->session_mutex
);
194 cifs_dbg(FYI
, "reconnect tcon rc = %d\n", rc
);
199 atomic_inc(&tconInfoReconnectCount
);
201 /* tell server Unix caps we support */
202 if (ses
->capabilities
& CAP_UNIX
)
203 reset_cifs_unix_caps(0, tcon
, NULL
, NULL
);
206 * Removed call to reopen open files here. It is safer (and faster) to
207 * reopen files one at a time as needed in read and write.
209 * FIXME: what about file locks? don't we need to reclaim them ASAP?
214 * Check if handle based operation so we know whether we can continue
215 * or not without returning to caller to reset file handle
217 switch (smb_command
) {
218 case SMB_COM_READ_ANDX
:
219 case SMB_COM_WRITE_ANDX
:
221 case SMB_COM_FIND_CLOSE2
:
222 case SMB_COM_LOCKING_ANDX
:
226 unload_nls(nls_codepage
);
230 /* Allocate and return pointer to an SMB request buffer, and set basic
231 SMB information in the SMB header. If the return code is zero, this
232 function must have filled in request_buf pointer */
234 small_smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
239 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
243 *request_buf
= cifs_small_buf_get();
244 if (*request_buf
== NULL
) {
245 /* BB should we add a retry in here if not a writepage? */
249 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
,
253 cifs_stats_inc(&tcon
->num_smbs_sent
);
259 small_smb_init_no_tc(const int smb_command
, const int wct
,
260 struct cifs_ses
*ses
, void **request_buf
)
263 struct smb_hdr
*buffer
;
265 rc
= small_smb_init(smb_command
, wct
, NULL
, request_buf
);
269 buffer
= (struct smb_hdr
*)*request_buf
;
270 buffer
->Mid
= get_next_mid(ses
->server
);
271 if (ses
->capabilities
& CAP_UNICODE
)
272 buffer
->Flags2
|= SMBFLG2_UNICODE
;
273 if (ses
->capabilities
& CAP_STATUS32
)
274 buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
276 /* uid, tid can stay at zero as set in header assemble */
278 /* BB add support for turning on the signing when
279 this function is used after 1st of session setup requests */
284 /* If the return code is zero, this function must fill in request_buf pointer */
286 __smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
287 void **request_buf
, void **response_buf
)
289 *request_buf
= cifs_buf_get();
290 if (*request_buf
== NULL
) {
291 /* BB should we add a retry in here if not a writepage? */
294 /* Although the original thought was we needed the response buf for */
295 /* potential retries of smb operations it turns out we can determine */
296 /* from the mid flags when the request buffer can be resent without */
297 /* having to use a second distinct buffer for the response */
299 *response_buf
= *request_buf
;
301 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
, tcon
,
305 cifs_stats_inc(&tcon
->num_smbs_sent
);
310 /* If the return code is zero, this function must fill in request_buf pointer */
312 smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
313 void **request_buf
, void **response_buf
)
317 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
321 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
325 smb_init_no_reconnect(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
326 void **request_buf
, void **response_buf
)
328 if (tcon
->ses
->need_reconnect
|| tcon
->need_reconnect
)
331 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
334 static int validate_t2(struct smb_t2_rsp
*pSMB
)
336 unsigned int total_size
;
338 /* check for plausible wct */
339 if (pSMB
->hdr
.WordCount
< 10)
342 /* check for parm and data offset going beyond end of smb */
343 if (get_unaligned_le16(&pSMB
->t2_rsp
.ParameterOffset
) > 1024 ||
344 get_unaligned_le16(&pSMB
->t2_rsp
.DataOffset
) > 1024)
347 total_size
= get_unaligned_le16(&pSMB
->t2_rsp
.ParameterCount
);
348 if (total_size
>= 512)
351 /* check that bcc is at least as big as parms + data, and that it is
352 * less than negotiated smb buffer
354 total_size
+= get_unaligned_le16(&pSMB
->t2_rsp
.DataCount
);
355 if (total_size
> get_bcc(&pSMB
->hdr
) ||
356 total_size
>= CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
)
361 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB
,
362 sizeof(struct smb_t2_rsp
) + 16);
367 decode_ext_sec_blob(struct cifs_ses
*ses
, NEGOTIATE_RSP
*pSMBr
)
371 char *guid
= pSMBr
->u
.extended_response
.GUID
;
372 struct TCP_Server_Info
*server
= ses
->server
;
374 count
= get_bcc(&pSMBr
->hdr
);
375 if (count
< SMB1_CLIENT_GUID_SIZE
)
378 spin_lock(&cifs_tcp_ses_lock
);
379 if (server
->srv_count
> 1) {
380 spin_unlock(&cifs_tcp_ses_lock
);
381 if (memcmp(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
) != 0) {
382 cifs_dbg(FYI
, "server UID changed\n");
383 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
386 spin_unlock(&cifs_tcp_ses_lock
);
387 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
390 if (count
== SMB1_CLIENT_GUID_SIZE
) {
391 server
->sec_ntlmssp
= true;
393 count
-= SMB1_CLIENT_GUID_SIZE
;
394 rc
= decode_negTokenInit(
395 pSMBr
->u
.extended_response
.SecurityBlob
, count
, server
);
404 cifs_enable_signing(struct TCP_Server_Info
*server
, bool mnt_sign_required
)
406 bool srv_sign_required
= server
->sec_mode
& server
->vals
->signing_required
;
407 bool srv_sign_enabled
= server
->sec_mode
& server
->vals
->signing_enabled
;
408 bool mnt_sign_enabled
= global_secflags
& CIFSSEC_MAY_SIGN
;
411 * Is signing required by mnt options? If not then check
412 * global_secflags to see if it is there.
414 if (!mnt_sign_required
)
415 mnt_sign_required
= ((global_secflags
& CIFSSEC_MUST_SIGN
) ==
419 * If signing is required then it's automatically enabled too,
420 * otherwise, check to see if the secflags allow it.
422 mnt_sign_enabled
= mnt_sign_required
? mnt_sign_required
:
423 (global_secflags
& CIFSSEC_MAY_SIGN
);
425 /* If server requires signing, does client allow it? */
426 if (srv_sign_required
) {
427 if (!mnt_sign_enabled
) {
428 cifs_dbg(VFS
, "Server requires signing, but it's disabled in SecurityFlags!");
434 /* If client requires signing, does server allow it? */
435 if (mnt_sign_required
) {
436 if (!srv_sign_enabled
) {
437 cifs_dbg(VFS
, "Server does not support signing!");
446 #ifdef CONFIG_CIFS_WEAK_PW_HASH
448 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
451 struct lanman_neg_rsp
*rsp
= (struct lanman_neg_rsp
*)pSMBr
;
453 if (server
->dialect
!= LANMAN_PROT
&& server
->dialect
!= LANMAN2_PROT
)
456 server
->sec_mode
= le16_to_cpu(rsp
->SecurityMode
);
457 server
->maxReq
= min_t(unsigned int,
458 le16_to_cpu(rsp
->MaxMpxCount
),
460 set_credits(server
, server
->maxReq
);
461 server
->maxBuf
= le16_to_cpu(rsp
->MaxBufSize
);
462 /* even though we do not use raw we might as well set this
463 accurately, in case we ever find a need for it */
464 if ((le16_to_cpu(rsp
->RawMode
) & RAW_ENABLE
) == RAW_ENABLE
) {
465 server
->max_rw
= 0xFF00;
466 server
->capabilities
= CAP_MPX_MODE
| CAP_RAW_MODE
;
468 server
->max_rw
= 0;/* do not need to use raw anyway */
469 server
->capabilities
= CAP_MPX_MODE
;
471 tmp
= (__s16
)le16_to_cpu(rsp
->ServerTimeZone
);
473 /* OS/2 often does not set timezone therefore
474 * we must use server time to calc time zone.
475 * Could deviate slightly from the right zone.
476 * Smallest defined timezone difference is 15 minutes
477 * (i.e. Nepal). Rounding up/down is done to match
480 int val
, seconds
, remain
, result
;
481 struct timespec ts
, utc
;
483 ts
= cnvrtDosUnixTm(rsp
->SrvTime
.Date
,
484 rsp
->SrvTime
.Time
, 0);
485 cifs_dbg(FYI
, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
486 (int)ts
.tv_sec
, (int)utc
.tv_sec
,
487 (int)(utc
.tv_sec
- ts
.tv_sec
));
488 val
= (int)(utc
.tv_sec
- ts
.tv_sec
);
490 result
= (seconds
/ MIN_TZ_ADJ
) * MIN_TZ_ADJ
;
491 remain
= seconds
% MIN_TZ_ADJ
;
492 if (remain
>= (MIN_TZ_ADJ
/ 2))
493 result
+= MIN_TZ_ADJ
;
496 server
->timeAdj
= result
;
498 server
->timeAdj
= (int)tmp
;
499 server
->timeAdj
*= 60; /* also in seconds */
501 cifs_dbg(FYI
, "server->timeAdj: %d seconds\n", server
->timeAdj
);
504 /* BB get server time for time conversions and add
505 code to use it and timezone since this is not UTC */
507 if (rsp
->EncryptionKeyLength
==
508 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE
)) {
509 memcpy(server
->cryptkey
, rsp
->EncryptionKey
,
510 CIFS_CRYPTO_KEY_SIZE
);
511 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
512 return -EIO
; /* need cryptkey unless plain text */
515 cifs_dbg(FYI
, "LANMAN negotiated\n");
520 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
522 cifs_dbg(VFS
, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
528 should_set_ext_sec_flag(enum securityEnum sectype
)
535 if (global_secflags
&
536 (CIFSSEC_MAY_KRB5
| CIFSSEC_MAY_NTLMSSP
))
545 CIFSSMBNegotiate(const unsigned int xid
, struct cifs_ses
*ses
)
548 NEGOTIATE_RSP
*pSMBr
;
552 struct TCP_Server_Info
*server
= ses
->server
;
556 WARN(1, "%s: server is NULL!\n", __func__
);
560 rc
= smb_init(SMB_COM_NEGOTIATE
, 0, NULL
/* no tcon yet */ ,
561 (void **) &pSMB
, (void **) &pSMBr
);
565 pSMB
->hdr
.Mid
= get_next_mid(server
);
566 pSMB
->hdr
.Flags2
|= (SMBFLG2_UNICODE
| SMBFLG2_ERR_STATUS
);
568 if (should_set_ext_sec_flag(ses
->sectype
)) {
569 cifs_dbg(FYI
, "Requesting extended security.");
570 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
574 for (i
= 0; i
< CIFS_NUM_PROT
; i
++) {
575 strncpy(pSMB
->DialectsArray
+count
, protocols
[i
].name
, 16);
576 count
+= strlen(protocols
[i
].name
) + 1;
577 /* null at end of source and target buffers anyway */
579 inc_rfc1001_len(pSMB
, count
);
580 pSMB
->ByteCount
= cpu_to_le16(count
);
582 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
583 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
587 server
->dialect
= le16_to_cpu(pSMBr
->DialectIndex
);
588 cifs_dbg(FYI
, "Dialect: %d\n", server
->dialect
);
589 /* Check wct = 1 error case */
590 if ((pSMBr
->hdr
.WordCount
< 13) || (server
->dialect
== BAD_PROT
)) {
591 /* core returns wct = 1, but we do not ask for core - otherwise
592 small wct just comes when dialect index is -1 indicating we
593 could not negotiate a common dialect */
596 } else if (pSMBr
->hdr
.WordCount
== 13) {
597 server
->negflavor
= CIFS_NEGFLAVOR_LANMAN
;
598 rc
= decode_lanman_negprot_rsp(server
, pSMBr
);
600 } else if (pSMBr
->hdr
.WordCount
!= 17) {
605 /* else wct == 17, NTLM or better */
607 server
->sec_mode
= pSMBr
->SecurityMode
;
608 if ((server
->sec_mode
& SECMODE_USER
) == 0)
609 cifs_dbg(FYI
, "share mode security\n");
611 /* one byte, so no need to convert this or EncryptionKeyLen from
613 server
->maxReq
= min_t(unsigned int, le16_to_cpu(pSMBr
->MaxMpxCount
),
615 set_credits(server
, server
->maxReq
);
616 /* probably no need to store and check maxvcs */
617 server
->maxBuf
= le32_to_cpu(pSMBr
->MaxBufferSize
);
618 server
->max_rw
= le32_to_cpu(pSMBr
->MaxRawSize
);
619 cifs_dbg(NOISY
, "Max buf = %d\n", ses
->server
->maxBuf
);
620 server
->capabilities
= le32_to_cpu(pSMBr
->Capabilities
);
621 server
->timeAdj
= (int)(__s16
)le16_to_cpu(pSMBr
->ServerTimeZone
);
622 server
->timeAdj
*= 60;
624 if (pSMBr
->EncryptionKeyLength
== CIFS_CRYPTO_KEY_SIZE
) {
625 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
626 memcpy(ses
->server
->cryptkey
, pSMBr
->u
.EncryptionKey
,
627 CIFS_CRYPTO_KEY_SIZE
);
628 } else if ((pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
||
629 server
->capabilities
& CAP_EXTENDED_SECURITY
) &&
630 (pSMBr
->EncryptionKeyLength
== 0)) {
631 server
->negflavor
= CIFS_NEGFLAVOR_EXTENDED
;
632 rc
= decode_ext_sec_blob(ses
, pSMBr
);
633 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
634 rc
= -EIO
; /* no crypt key only if plain text pwd */
636 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
637 server
->capabilities
&= ~CAP_EXTENDED_SECURITY
;
642 rc
= cifs_enable_signing(server
, ses
->sign
);
644 cifs_buf_release(pSMB
);
646 cifs_dbg(FYI
, "negprot rc %d\n", rc
);
651 CIFSSMBTDis(const unsigned int xid
, struct cifs_tcon
*tcon
)
653 struct smb_hdr
*smb_buffer
;
656 cifs_dbg(FYI
, "In tree disconnect\n");
658 /* BB: do we need to check this? These should never be NULL. */
659 if ((tcon
->ses
== NULL
) || (tcon
->ses
->server
== NULL
))
663 * No need to return error on this operation if tid invalidated and
664 * closed on server already e.g. due to tcp session crashing. Also,
665 * the tcon is no longer on the list, so no need to take lock before
668 if ((tcon
->need_reconnect
) || (tcon
->ses
->need_reconnect
))
671 rc
= small_smb_init(SMB_COM_TREE_DISCONNECT
, 0, tcon
,
672 (void **)&smb_buffer
);
676 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)smb_buffer
, 0);
678 cifs_dbg(FYI
, "Tree disconnect failed %d\n", rc
);
680 /* No need to return error on this operation if tid invalidated and
681 closed on server already e.g. due to tcp session crashing */
689 * This is a no-op for now. We're not really interested in the reply, but
690 * rather in the fact that the server sent one and that server->lstrp
693 * FIXME: maybe we should consider checking that the reply matches request?
696 cifs_echo_callback(struct mid_q_entry
*mid
)
698 struct TCP_Server_Info
*server
= mid
->callback_data
;
700 DeleteMidQEntry(mid
);
701 add_credits(server
, 1, CIFS_ECHO_OP
);
705 CIFSSMBEcho(struct TCP_Server_Info
*server
)
710 struct smb_rqst rqst
= { .rq_iov
= &iov
,
713 cifs_dbg(FYI
, "In echo request\n");
715 rc
= small_smb_init(SMB_COM_ECHO
, 0, NULL
, (void **)&smb
);
719 /* set up echo request */
720 smb
->hdr
.Tid
= 0xffff;
721 smb
->hdr
.WordCount
= 1;
722 put_unaligned_le16(1, &smb
->EchoCount
);
723 put_bcc(1, &smb
->hdr
);
725 inc_rfc1001_len(smb
, 3);
727 iov
.iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4;
729 rc
= cifs_call_async(server
, &rqst
, NULL
, cifs_echo_callback
,
730 server
, CIFS_ASYNC_OP
| CIFS_ECHO_OP
);
732 cifs_dbg(FYI
, "Echo request failed: %d\n", rc
);
734 cifs_small_buf_release(smb
);
740 CIFSSMBLogoff(const unsigned int xid
, struct cifs_ses
*ses
)
742 LOGOFF_ANDX_REQ
*pSMB
;
745 cifs_dbg(FYI
, "In SMBLogoff for session disconnect\n");
748 * BB: do we need to check validity of ses and server? They should
749 * always be valid since we have an active reference. If not, that
750 * should probably be a BUG()
752 if (!ses
|| !ses
->server
)
755 mutex_lock(&ses
->session_mutex
);
756 if (ses
->need_reconnect
)
757 goto session_already_dead
; /* no need to send SMBlogoff if uid
758 already closed due to reconnect */
759 rc
= small_smb_init(SMB_COM_LOGOFF_ANDX
, 2, NULL
, (void **)&pSMB
);
761 mutex_unlock(&ses
->session_mutex
);
765 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
767 if (ses
->server
->sign
)
768 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
770 pSMB
->hdr
.Uid
= ses
->Suid
;
772 pSMB
->AndXCommand
= 0xFF;
773 rc
= SendReceiveNoRsp(xid
, ses
, (char *) pSMB
, 0);
774 session_already_dead
:
775 mutex_unlock(&ses
->session_mutex
);
777 /* if session dead then we do not need to do ulogoff,
778 since server closed smb session, no sense reporting
786 CIFSPOSIXDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
,
787 const char *fileName
, __u16 type
,
788 const struct nls_table
*nls_codepage
, int remap
)
790 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
791 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
792 struct unlink_psx_rq
*pRqD
;
795 int bytes_returned
= 0;
796 __u16 params
, param_offset
, offset
, byte_count
;
798 cifs_dbg(FYI
, "In POSIX delete\n");
800 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
805 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
807 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
808 PATH_MAX
, nls_codepage
, remap
);
809 name_len
++; /* trailing null */
811 } else { /* BB add path length overrun check */
812 name_len
= strnlen(fileName
, PATH_MAX
);
813 name_len
++; /* trailing null */
814 strncpy(pSMB
->FileName
, fileName
, name_len
);
817 params
= 6 + name_len
;
818 pSMB
->MaxParameterCount
= cpu_to_le16(2);
819 pSMB
->MaxDataCount
= 0; /* BB double check this with jra */
820 pSMB
->MaxSetupCount
= 0;
825 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
826 InformationLevel
) - 4;
827 offset
= param_offset
+ params
;
829 /* Setup pointer to Request Data (inode type) */
830 pRqD
= (struct unlink_psx_rq
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
831 pRqD
->type
= cpu_to_le16(type
);
832 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
833 pSMB
->DataOffset
= cpu_to_le16(offset
);
834 pSMB
->SetupCount
= 1;
836 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
837 byte_count
= 3 /* pad */ + params
+ sizeof(struct unlink_psx_rq
);
839 pSMB
->DataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
840 pSMB
->TotalDataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
841 pSMB
->ParameterCount
= cpu_to_le16(params
);
842 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
843 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_UNLINK
);
845 inc_rfc1001_len(pSMB
, byte_count
);
846 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
847 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
848 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
850 cifs_dbg(FYI
, "Posix delete returned %d\n", rc
);
851 cifs_buf_release(pSMB
);
853 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
862 CIFSSMBDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
863 struct cifs_sb_info
*cifs_sb
)
865 DELETE_FILE_REQ
*pSMB
= NULL
;
866 DELETE_FILE_RSP
*pSMBr
= NULL
;
870 int remap
= cifs_remap(cifs_sb
);
873 rc
= smb_init(SMB_COM_DELETE
, 1, tcon
, (void **) &pSMB
,
878 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
879 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->fileName
, name
,
880 PATH_MAX
, cifs_sb
->local_nls
,
882 name_len
++; /* trailing null */
884 } else { /* BB improve check for buffer overruns BB */
885 name_len
= strnlen(name
, PATH_MAX
);
886 name_len
++; /* trailing null */
887 strncpy(pSMB
->fileName
, name
, name_len
);
889 pSMB
->SearchAttributes
=
890 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
);
891 pSMB
->BufferFormat
= 0x04;
892 inc_rfc1001_len(pSMB
, name_len
+ 1);
893 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
894 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
895 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
896 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
898 cifs_dbg(FYI
, "Error in RMFile = %d\n", rc
);
900 cifs_buf_release(pSMB
);
908 CIFSSMBRmDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
909 struct cifs_sb_info
*cifs_sb
)
911 DELETE_DIRECTORY_REQ
*pSMB
= NULL
;
912 DELETE_DIRECTORY_RSP
*pSMBr
= NULL
;
916 int remap
= cifs_remap(cifs_sb
);
918 cifs_dbg(FYI
, "In CIFSSMBRmDir\n");
920 rc
= smb_init(SMB_COM_DELETE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
925 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
926 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
927 PATH_MAX
, cifs_sb
->local_nls
,
929 name_len
++; /* trailing null */
931 } else { /* BB improve check for buffer overruns BB */
932 name_len
= strnlen(name
, PATH_MAX
);
933 name_len
++; /* trailing null */
934 strncpy(pSMB
->DirName
, name
, name_len
);
937 pSMB
->BufferFormat
= 0x04;
938 inc_rfc1001_len(pSMB
, name_len
+ 1);
939 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
940 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
941 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
942 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_rmdirs
);
944 cifs_dbg(FYI
, "Error in RMDir = %d\n", rc
);
946 cifs_buf_release(pSMB
);
953 CIFSSMBMkDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
954 struct cifs_sb_info
*cifs_sb
)
957 CREATE_DIRECTORY_REQ
*pSMB
= NULL
;
958 CREATE_DIRECTORY_RSP
*pSMBr
= NULL
;
961 int remap
= cifs_remap(cifs_sb
);
963 cifs_dbg(FYI
, "In CIFSSMBMkDir\n");
965 rc
= smb_init(SMB_COM_CREATE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
970 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
971 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
972 PATH_MAX
, cifs_sb
->local_nls
,
974 name_len
++; /* trailing null */
976 } else { /* BB improve check for buffer overruns BB */
977 name_len
= strnlen(name
, PATH_MAX
);
978 name_len
++; /* trailing null */
979 strncpy(pSMB
->DirName
, name
, name_len
);
982 pSMB
->BufferFormat
= 0x04;
983 inc_rfc1001_len(pSMB
, name_len
+ 1);
984 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
985 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
986 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
987 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_mkdirs
);
989 cifs_dbg(FYI
, "Error in Mkdir = %d\n", rc
);
991 cifs_buf_release(pSMB
);
998 CIFSPOSIXCreate(const unsigned int xid
, struct cifs_tcon
*tcon
,
999 __u32 posix_flags
, __u64 mode
, __u16
*netfid
,
1000 FILE_UNIX_BASIC_INFO
*pRetData
, __u32
*pOplock
,
1001 const char *name
, const struct nls_table
*nls_codepage
,
1004 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
1005 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
1008 int bytes_returned
= 0;
1009 __u16 params
, param_offset
, offset
, byte_count
, count
;
1010 OPEN_PSX_REQ
*pdata
;
1011 OPEN_PSX_RSP
*psx_rsp
;
1013 cifs_dbg(FYI
, "In POSIX Create\n");
1015 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1020 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1022 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, name
,
1023 PATH_MAX
, nls_codepage
, remap
);
1024 name_len
++; /* trailing null */
1026 } else { /* BB improve the check for buffer overruns BB */
1027 name_len
= strnlen(name
, PATH_MAX
);
1028 name_len
++; /* trailing null */
1029 strncpy(pSMB
->FileName
, name
, name_len
);
1032 params
= 6 + name_len
;
1033 count
= sizeof(OPEN_PSX_REQ
);
1034 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1035 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* large enough */
1036 pSMB
->MaxSetupCount
= 0;
1040 pSMB
->Reserved2
= 0;
1041 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
1042 InformationLevel
) - 4;
1043 offset
= param_offset
+ params
;
1044 pdata
= (OPEN_PSX_REQ
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
1045 pdata
->Level
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
1046 pdata
->Permissions
= cpu_to_le64(mode
);
1047 pdata
->PosixOpenFlags
= cpu_to_le32(posix_flags
);
1048 pdata
->OpenFlags
= cpu_to_le32(*pOplock
);
1049 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
1050 pSMB
->DataOffset
= cpu_to_le16(offset
);
1051 pSMB
->SetupCount
= 1;
1052 pSMB
->Reserved3
= 0;
1053 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
1054 byte_count
= 3 /* pad */ + params
+ count
;
1056 pSMB
->DataCount
= cpu_to_le16(count
);
1057 pSMB
->ParameterCount
= cpu_to_le16(params
);
1058 pSMB
->TotalDataCount
= pSMB
->DataCount
;
1059 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1060 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_OPEN
);
1061 pSMB
->Reserved4
= 0;
1062 inc_rfc1001_len(pSMB
, byte_count
);
1063 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1064 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1065 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1067 cifs_dbg(FYI
, "Posix create returned %d\n", rc
);
1068 goto psx_create_err
;
1071 cifs_dbg(FYI
, "copying inode info\n");
1072 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
1074 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)) {
1075 rc
= -EIO
; /* bad smb */
1076 goto psx_create_err
;
1079 /* copy return information to pRetData */
1080 psx_rsp
= (OPEN_PSX_RSP
*)((char *) &pSMBr
->hdr
.Protocol
1081 + le16_to_cpu(pSMBr
->t2
.DataOffset
));
1083 *pOplock
= le16_to_cpu(psx_rsp
->OplockFlags
);
1085 *netfid
= psx_rsp
->Fid
; /* cifs fid stays in le */
1086 /* Let caller know file was created so we can set the mode. */
1087 /* Do we care about the CreateAction in any other cases? */
1088 if (cpu_to_le32(FILE_CREATE
) == psx_rsp
->CreateAction
)
1089 *pOplock
|= CIFS_CREATE_ACTION
;
1090 /* check to make sure response data is there */
1091 if (psx_rsp
->ReturnedLevel
!= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
)) {
1092 pRetData
->Type
= cpu_to_le32(-1); /* unknown */
1093 cifs_dbg(NOISY
, "unknown type\n");
1095 if (get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)
1096 + sizeof(FILE_UNIX_BASIC_INFO
)) {
1097 cifs_dbg(VFS
, "Open response data too small\n");
1098 pRetData
->Type
= cpu_to_le32(-1);
1099 goto psx_create_err
;
1101 memcpy((char *) pRetData
,
1102 (char *)psx_rsp
+ sizeof(OPEN_PSX_RSP
),
1103 sizeof(FILE_UNIX_BASIC_INFO
));
1107 cifs_buf_release(pSMB
);
1109 if (posix_flags
& SMB_O_DIRECTORY
)
1110 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixmkdirs
);
1112 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixopens
);
1120 static __u16
convert_disposition(int disposition
)
1124 switch (disposition
) {
1125 case FILE_SUPERSEDE
:
1126 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1129 ofun
= SMBOPEN_OAPPEND
;
1132 ofun
= SMBOPEN_OCREATE
;
1135 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OAPPEND
;
1137 case FILE_OVERWRITE
:
1138 ofun
= SMBOPEN_OTRUNC
;
1140 case FILE_OVERWRITE_IF
:
1141 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1144 cifs_dbg(FYI
, "unknown disposition %d\n", disposition
);
1145 ofun
= SMBOPEN_OAPPEND
; /* regular open */
1151 access_flags_to_smbopen_mode(const int access_flags
)
1153 int masked_flags
= access_flags
& (GENERIC_READ
| GENERIC_WRITE
);
1155 if (masked_flags
== GENERIC_READ
)
1156 return SMBOPEN_READ
;
1157 else if (masked_flags
== GENERIC_WRITE
)
1158 return SMBOPEN_WRITE
;
1160 /* just go for read/write */
1161 return SMBOPEN_READWRITE
;
1165 SMBLegacyOpen(const unsigned int xid
, struct cifs_tcon
*tcon
,
1166 const char *fileName
, const int openDisposition
,
1167 const int access_flags
, const int create_options
, __u16
*netfid
,
1168 int *pOplock
, FILE_ALL_INFO
*pfile_info
,
1169 const struct nls_table
*nls_codepage
, int remap
)
1172 OPENX_REQ
*pSMB
= NULL
;
1173 OPENX_RSP
*pSMBr
= NULL
;
1179 rc
= smb_init(SMB_COM_OPEN_ANDX
, 15, tcon
, (void **) &pSMB
,
1184 pSMB
->AndXCommand
= 0xFF; /* none */
1186 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1187 count
= 1; /* account for one byte pad to word boundary */
1189 cifsConvertToUTF16((__le16
*) (pSMB
->fileName
+ 1),
1190 fileName
, PATH_MAX
, nls_codepage
, remap
);
1191 name_len
++; /* trailing null */
1193 } else { /* BB improve check for buffer overruns BB */
1194 count
= 0; /* no pad */
1195 name_len
= strnlen(fileName
, PATH_MAX
);
1196 name_len
++; /* trailing null */
1197 strncpy(pSMB
->fileName
, fileName
, name_len
);
1199 if (*pOplock
& REQ_OPLOCK
)
1200 pSMB
->OpenFlags
= cpu_to_le16(REQ_OPLOCK
);
1201 else if (*pOplock
& REQ_BATCHOPLOCK
)
1202 pSMB
->OpenFlags
= cpu_to_le16(REQ_BATCHOPLOCK
);
1204 pSMB
->OpenFlags
|= cpu_to_le16(REQ_MORE_INFO
);
1205 pSMB
->Mode
= cpu_to_le16(access_flags_to_smbopen_mode(access_flags
));
1206 pSMB
->Mode
|= cpu_to_le16(0x40); /* deny none */
1207 /* set file as system file if special file such
1208 as fifo and server expecting SFU style and
1209 no Unix extensions */
1211 if (create_options
& CREATE_OPTION_SPECIAL
)
1212 pSMB
->FileAttributes
= cpu_to_le16(ATTR_SYSTEM
);
1213 else /* BB FIXME BB */
1214 pSMB
->FileAttributes
= cpu_to_le16(0/*ATTR_NORMAL*/);
1216 if (create_options
& CREATE_OPTION_READONLY
)
1217 pSMB
->FileAttributes
|= cpu_to_le16(ATTR_READONLY
);
1220 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1221 CREATE_OPTIONS_MASK); */
1222 /* BB FIXME END BB */
1224 pSMB
->Sattr
= cpu_to_le16(ATTR_HIDDEN
| ATTR_SYSTEM
| ATTR_DIRECTORY
);
1225 pSMB
->OpenFunction
= cpu_to_le16(convert_disposition(openDisposition
));
1227 inc_rfc1001_len(pSMB
, count
);
1229 pSMB
->ByteCount
= cpu_to_le16(count
);
1230 /* long_op set to 1 to allow for oplock break timeouts */
1231 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1232 (struct smb_hdr
*)pSMBr
, &bytes_returned
, 0);
1233 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1235 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1237 /* BB verify if wct == 15 */
1239 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1241 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
1242 /* Let caller know file was created so we can set the mode. */
1243 /* Do we care about the CreateAction in any other cases? */
1245 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1246 *pOplock |= CIFS_CREATE_ACTION; */
1250 pfile_info
->CreationTime
= 0; /* BB convert CreateTime*/
1251 pfile_info
->LastAccessTime
= 0; /* BB fixme */
1252 pfile_info
->LastWriteTime
= 0; /* BB fixme */
1253 pfile_info
->ChangeTime
= 0; /* BB fixme */
1254 pfile_info
->Attributes
=
1255 cpu_to_le32(le16_to_cpu(pSMBr
->FileAttributes
));
1256 /* the file_info buf is endian converted by caller */
1257 pfile_info
->AllocationSize
=
1258 cpu_to_le64(le32_to_cpu(pSMBr
->EndOfFile
));
1259 pfile_info
->EndOfFile
= pfile_info
->AllocationSize
;
1260 pfile_info
->NumberOfLinks
= cpu_to_le32(1);
1261 pfile_info
->DeletePending
= 0;
1265 cifs_buf_release(pSMB
);
1272 CIFS_open(const unsigned int xid
, struct cifs_open_parms
*oparms
, int *oplock
,
1276 OPEN_REQ
*req
= NULL
;
1277 OPEN_RSP
*rsp
= NULL
;
1281 struct cifs_sb_info
*cifs_sb
= oparms
->cifs_sb
;
1282 struct cifs_tcon
*tcon
= oparms
->tcon
;
1283 int remap
= cifs_remap(cifs_sb
);
1284 const struct nls_table
*nls
= cifs_sb
->local_nls
;
1285 int create_options
= oparms
->create_options
;
1286 int desired_access
= oparms
->desired_access
;
1287 int disposition
= oparms
->disposition
;
1288 const char *path
= oparms
->path
;
1291 rc
= smb_init(SMB_COM_NT_CREATE_ANDX
, 24, tcon
, (void **)&req
,
1296 /* no commands go after this */
1297 req
->AndXCommand
= 0xFF;
1299 if (req
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1300 /* account for one byte pad to word boundary */
1302 name_len
= cifsConvertToUTF16((__le16
*)(req
->fileName
+ 1),
1303 path
, PATH_MAX
, nls
, remap
);
1307 req
->NameLength
= cpu_to_le16(name_len
);
1309 /* BB improve check for buffer overruns BB */
1312 name_len
= strnlen(path
, PATH_MAX
);
1315 req
->NameLength
= cpu_to_le16(name_len
);
1316 strncpy(req
->fileName
, path
, name_len
);
1319 if (*oplock
& REQ_OPLOCK
)
1320 req
->OpenFlags
= cpu_to_le32(REQ_OPLOCK
);
1321 else if (*oplock
& REQ_BATCHOPLOCK
)
1322 req
->OpenFlags
= cpu_to_le32(REQ_BATCHOPLOCK
);
1324 req
->DesiredAccess
= cpu_to_le32(desired_access
);
1325 req
->AllocationSize
= 0;
1328 * Set file as system file if special file such as fifo and server
1329 * expecting SFU style and no Unix extensions.
1331 if (create_options
& CREATE_OPTION_SPECIAL
)
1332 req
->FileAttributes
= cpu_to_le32(ATTR_SYSTEM
);
1334 req
->FileAttributes
= cpu_to_le32(ATTR_NORMAL
);
1337 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1338 * sensitive checks for other servers such as Samba.
1340 if (tcon
->ses
->capabilities
& CAP_UNIX
)
1341 req
->FileAttributes
|= cpu_to_le32(ATTR_POSIX_SEMANTICS
);
1343 if (create_options
& CREATE_OPTION_READONLY
)
1344 req
->FileAttributes
|= cpu_to_le32(ATTR_READONLY
);
1346 req
->ShareAccess
= cpu_to_le32(FILE_SHARE_ALL
);
1347 req
->CreateDisposition
= cpu_to_le32(disposition
);
1348 req
->CreateOptions
= cpu_to_le32(create_options
& CREATE_OPTIONS_MASK
);
1350 /* BB Expirement with various impersonation levels and verify */
1351 req
->ImpersonationLevel
= cpu_to_le32(SECURITY_IMPERSONATION
);
1352 req
->SecurityFlags
= SECURITY_CONTEXT_TRACKING
|SECURITY_EFFECTIVE_ONLY
;
1355 inc_rfc1001_len(req
, count
);
1357 req
->ByteCount
= cpu_to_le16(count
);
1358 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*)req
,
1359 (struct smb_hdr
*)rsp
, &bytes_returned
, 0);
1360 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1362 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1363 cifs_buf_release(req
);
1369 /* 1 byte no need to le_to_cpu */
1370 *oplock
= rsp
->OplockLevel
;
1371 /* cifs fid stays in le */
1372 oparms
->fid
->netfid
= rsp
->Fid
;
1374 /* Let caller know file was created so we can set the mode. */
1375 /* Do we care about the CreateAction in any other cases? */
1376 if (cpu_to_le32(FILE_CREATE
) == rsp
->CreateAction
)
1377 *oplock
|= CIFS_CREATE_ACTION
;
1380 /* copy from CreationTime to Attributes */
1381 memcpy((char *)buf
, (char *)&rsp
->CreationTime
, 36);
1382 /* the file_info buf is endian converted by caller */
1383 buf
->AllocationSize
= rsp
->AllocationSize
;
1384 buf
->EndOfFile
= rsp
->EndOfFile
;
1385 buf
->NumberOfLinks
= cpu_to_le32(1);
1386 buf
->DeletePending
= 0;
1389 cifs_buf_release(req
);
1394 * Discard any remaining data in the current SMB. To do this, we borrow the
1398 discard_remaining_data(struct TCP_Server_Info
*server
)
1400 unsigned int rfclen
= get_rfc1002_length(server
->smallbuf
);
1401 int remaining
= rfclen
+ 4 - server
->total_read
;
1403 while (remaining
> 0) {
1406 length
= cifs_read_from_socket(server
, server
->bigbuf
,
1407 min_t(unsigned int, remaining
,
1408 CIFSMaxBufSize
+ MAX_HEADER_SIZE(server
)));
1411 server
->total_read
+= length
;
1412 remaining
-= length
;
1419 cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1422 struct cifs_readdata
*rdata
= mid
->callback_data
;
1424 length
= discard_remaining_data(server
);
1425 dequeue_mid(mid
, rdata
->result
);
1430 cifs_readv_receive(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1433 unsigned int data_offset
, data_len
;
1434 struct cifs_readdata
*rdata
= mid
->callback_data
;
1435 char *buf
= server
->smallbuf
;
1436 unsigned int buflen
= get_rfc1002_length(buf
) + 4;
1438 cifs_dbg(FYI
, "%s: mid=%llu offset=%llu bytes=%u\n",
1439 __func__
, mid
->mid
, rdata
->offset
, rdata
->bytes
);
1442 * read the rest of READ_RSP header (sans Data array), or whatever we
1443 * can if there's not enough data. At this point, we've read down to
1446 len
= min_t(unsigned int, buflen
, server
->vals
->read_rsp_size
) -
1447 HEADER_SIZE(server
) + 1;
1449 rdata
->iov
.iov_base
= buf
+ HEADER_SIZE(server
) - 1;
1450 rdata
->iov
.iov_len
= len
;
1452 length
= cifs_readv_from_socket(server
, &rdata
->iov
, 1, len
);
1455 server
->total_read
+= length
;
1457 if (server
->ops
->is_status_pending
&&
1458 server
->ops
->is_status_pending(buf
, server
, 0)) {
1459 discard_remaining_data(server
);
1463 /* Was the SMB read successful? */
1464 rdata
->result
= server
->ops
->map_error(buf
, false);
1465 if (rdata
->result
!= 0) {
1466 cifs_dbg(FYI
, "%s: server returned error %d\n",
1467 __func__
, rdata
->result
);
1468 return cifs_readv_discard(server
, mid
);
1471 /* Is there enough to get to the rest of the READ_RSP header? */
1472 if (server
->total_read
< server
->vals
->read_rsp_size
) {
1473 cifs_dbg(FYI
, "%s: server returned short header. got=%u expected=%zu\n",
1474 __func__
, server
->total_read
,
1475 server
->vals
->read_rsp_size
);
1476 rdata
->result
= -EIO
;
1477 return cifs_readv_discard(server
, mid
);
1480 data_offset
= server
->ops
->read_data_offset(buf
) + 4;
1481 if (data_offset
< server
->total_read
) {
1483 * win2k8 sometimes sends an offset of 0 when the read
1484 * is beyond the EOF. Treat it as if the data starts just after
1487 cifs_dbg(FYI
, "%s: data offset (%u) inside read response header\n",
1488 __func__
, data_offset
);
1489 data_offset
= server
->total_read
;
1490 } else if (data_offset
> MAX_CIFS_SMALL_BUFFER_SIZE
) {
1491 /* data_offset is beyond the end of smallbuf */
1492 cifs_dbg(FYI
, "%s: data offset (%u) beyond end of smallbuf\n",
1493 __func__
, data_offset
);
1494 rdata
->result
= -EIO
;
1495 return cifs_readv_discard(server
, mid
);
1498 cifs_dbg(FYI
, "%s: total_read=%u data_offset=%u\n",
1499 __func__
, server
->total_read
, data_offset
);
1501 len
= data_offset
- server
->total_read
;
1503 /* read any junk before data into the rest of smallbuf */
1504 rdata
->iov
.iov_base
= buf
+ server
->total_read
;
1505 rdata
->iov
.iov_len
= len
;
1506 length
= cifs_readv_from_socket(server
, &rdata
->iov
, 1, len
);
1509 server
->total_read
+= length
;
1512 /* set up first iov for signature check */
1513 rdata
->iov
.iov_base
= buf
;
1514 rdata
->iov
.iov_len
= server
->total_read
;
1515 cifs_dbg(FYI
, "0: iov_base=%p iov_len=%zu\n",
1516 rdata
->iov
.iov_base
, rdata
->iov
.iov_len
);
1518 /* how much data is in the response? */
1519 data_len
= server
->ops
->read_data_length(buf
);
1520 if (data_offset
+ data_len
> buflen
) {
1521 /* data_len is corrupt -- discard frame */
1522 rdata
->result
= -EIO
;
1523 return cifs_readv_discard(server
, mid
);
1526 length
= rdata
->read_into_pages(server
, rdata
, data_len
);
1530 server
->total_read
+= length
;
1532 cifs_dbg(FYI
, "total_read=%u buflen=%u remaining=%u\n",
1533 server
->total_read
, buflen
, data_len
);
1535 /* discard anything left over */
1536 if (server
->total_read
< buflen
)
1537 return cifs_readv_discard(server
, mid
);
1539 dequeue_mid(mid
, false);
1544 cifs_readv_callback(struct mid_q_entry
*mid
)
1546 struct cifs_readdata
*rdata
= mid
->callback_data
;
1547 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1548 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
1549 struct smb_rqst rqst
= { .rq_iov
= &rdata
->iov
,
1551 .rq_pages
= rdata
->pages
,
1552 .rq_npages
= rdata
->nr_pages
,
1553 .rq_pagesz
= rdata
->pagesz
,
1554 .rq_tailsz
= rdata
->tailsz
};
1556 cifs_dbg(FYI
, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1557 __func__
, mid
->mid
, mid
->mid_state
, rdata
->result
,
1560 switch (mid
->mid_state
) {
1561 case MID_RESPONSE_RECEIVED
:
1562 /* result already set, check signature */
1566 rc
= cifs_verify_signature(&rqst
, server
,
1567 mid
->sequence_number
);
1569 cifs_dbg(VFS
, "SMB signature verification returned error = %d\n",
1572 /* FIXME: should this be counted toward the initiating task? */
1573 task_io_account_read(rdata
->got_bytes
);
1574 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1576 case MID_REQUEST_SUBMITTED
:
1577 case MID_RETRY_NEEDED
:
1578 rdata
->result
= -EAGAIN
;
1579 if (server
->sign
&& rdata
->got_bytes
)
1580 /* reset bytes number since we can not check a sign */
1581 rdata
->got_bytes
= 0;
1582 /* FIXME: should this be counted toward the initiating task? */
1583 task_io_account_read(rdata
->got_bytes
);
1584 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1587 rdata
->result
= -EIO
;
1590 queue_work(cifsiod_wq
, &rdata
->work
);
1591 DeleteMidQEntry(mid
);
1592 add_credits(server
, 1, 0);
1595 /* cifs_async_readv - send an async write, and set up mid to handle result */
1597 cifs_async_readv(struct cifs_readdata
*rdata
)
1600 READ_REQ
*smb
= NULL
;
1602 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1603 struct smb_rqst rqst
= { .rq_iov
= &rdata
->iov
,
1606 cifs_dbg(FYI
, "%s: offset=%llu bytes=%u\n",
1607 __func__
, rdata
->offset
, rdata
->bytes
);
1609 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1612 wct
= 10; /* old style read */
1613 if ((rdata
->offset
>> 32) > 0) {
1614 /* can not handle this big offset for old */
1619 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **)&smb
);
1623 smb
->hdr
.Pid
= cpu_to_le16((__u16
)rdata
->pid
);
1624 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(rdata
->pid
>> 16));
1626 smb
->AndXCommand
= 0xFF; /* none */
1627 smb
->Fid
= rdata
->cfile
->fid
.netfid
;
1628 smb
->OffsetLow
= cpu_to_le32(rdata
->offset
& 0xFFFFFFFF);
1630 smb
->OffsetHigh
= cpu_to_le32(rdata
->offset
>> 32);
1632 smb
->MaxCount
= cpu_to_le16(rdata
->bytes
& 0xFFFF);
1633 smb
->MaxCountHigh
= cpu_to_le32(rdata
->bytes
>> 16);
1637 /* old style read */
1638 struct smb_com_readx_req
*smbr
=
1639 (struct smb_com_readx_req
*)smb
;
1640 smbr
->ByteCount
= 0;
1643 /* 4 for RFC1001 length + 1 for BCC */
1644 rdata
->iov
.iov_base
= smb
;
1645 rdata
->iov
.iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4;
1647 kref_get(&rdata
->refcount
);
1648 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, cifs_readv_receive
,
1649 cifs_readv_callback
, rdata
, 0);
1652 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1654 kref_put(&rdata
->refcount
, cifs_readdata_release
);
1656 cifs_small_buf_release(smb
);
1661 CIFSSMBRead(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1662 unsigned int *nbytes
, char **buf
, int *pbuf_type
)
1665 READ_REQ
*pSMB
= NULL
;
1666 READ_RSP
*pSMBr
= NULL
;
1667 char *pReadData
= NULL
;
1669 int resp_buf_type
= 0;
1671 __u32 pid
= io_parms
->pid
;
1672 __u16 netfid
= io_parms
->netfid
;
1673 __u64 offset
= io_parms
->offset
;
1674 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1675 unsigned int count
= io_parms
->length
;
1677 cifs_dbg(FYI
, "Reading %d bytes on fid %d\n", count
, netfid
);
1678 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1681 wct
= 10; /* old style read */
1682 if ((offset
>> 32) > 0) {
1683 /* can not handle this big offset for old */
1689 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **) &pSMB
);
1693 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1694 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1696 /* tcon and ses pointer are checked in smb_init */
1697 if (tcon
->ses
->server
== NULL
)
1698 return -ECONNABORTED
;
1700 pSMB
->AndXCommand
= 0xFF; /* none */
1702 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1704 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1706 pSMB
->Remaining
= 0;
1707 pSMB
->MaxCount
= cpu_to_le16(count
& 0xFFFF);
1708 pSMB
->MaxCountHigh
= cpu_to_le32(count
>> 16);
1710 pSMB
->ByteCount
= 0; /* no need to do le conversion since 0 */
1712 /* old style read */
1713 struct smb_com_readx_req
*pSMBW
=
1714 (struct smb_com_readx_req
*)pSMB
;
1715 pSMBW
->ByteCount
= 0;
1718 iov
[0].iov_base
= (char *)pSMB
;
1719 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
1720 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
1721 &resp_buf_type
, CIFS_LOG_ERROR
);
1722 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1723 pSMBr
= (READ_RSP
*)iov
[0].iov_base
;
1725 cifs_dbg(VFS
, "Send error in read = %d\n", rc
);
1727 int data_length
= le16_to_cpu(pSMBr
->DataLengthHigh
);
1728 data_length
= data_length
<< 16;
1729 data_length
+= le16_to_cpu(pSMBr
->DataLength
);
1730 *nbytes
= data_length
;
1732 /*check that DataLength would not go beyond end of SMB */
1733 if ((data_length
> CIFSMaxBufSize
)
1734 || (data_length
> count
)) {
1735 cifs_dbg(FYI
, "bad length %d for count %d\n",
1736 data_length
, count
);
1740 pReadData
= (char *) (&pSMBr
->hdr
.Protocol
) +
1741 le16_to_cpu(pSMBr
->DataOffset
);
1742 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1743 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1745 }*/ /* can not use copy_to_user when using page cache*/
1747 memcpy(*buf
, pReadData
, data_length
);
1751 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1753 free_rsp_buf(resp_buf_type
, iov
[0].iov_base
);
1754 } else if (resp_buf_type
!= CIFS_NO_BUFFER
) {
1755 /* return buffer to caller to free */
1756 *buf
= iov
[0].iov_base
;
1757 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1758 *pbuf_type
= CIFS_SMALL_BUFFER
;
1759 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1760 *pbuf_type
= CIFS_LARGE_BUFFER
;
1761 } /* else no valid buffer on return - leave as null */
1763 /* Note: On -EAGAIN error only caller can retry on handle based calls
1764 since file handle passed in no longer valid */
1770 CIFSSMBWrite(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1771 unsigned int *nbytes
, const char *buf
,
1772 const char __user
*ubuf
, const int long_op
)
1775 WRITE_REQ
*pSMB
= NULL
;
1776 WRITE_RSP
*pSMBr
= NULL
;
1777 int bytes_returned
, wct
;
1780 __u32 pid
= io_parms
->pid
;
1781 __u16 netfid
= io_parms
->netfid
;
1782 __u64 offset
= io_parms
->offset
;
1783 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1784 unsigned int count
= io_parms
->length
;
1788 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1789 if (tcon
->ses
== NULL
)
1790 return -ECONNABORTED
;
1792 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1796 if ((offset
>> 32) > 0) {
1797 /* can not handle big offset for old srv */
1802 rc
= smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
,
1807 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1808 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1810 /* tcon and ses pointer are checked in smb_init */
1811 if (tcon
->ses
->server
== NULL
)
1812 return -ECONNABORTED
;
1814 pSMB
->AndXCommand
= 0xFF; /* none */
1816 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1818 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1820 pSMB
->Reserved
= 0xFFFFFFFF;
1821 pSMB
->WriteMode
= 0;
1822 pSMB
->Remaining
= 0;
1824 /* Can increase buffer size if buffer is big enough in some cases ie we
1825 can send more if LARGE_WRITE_X capability returned by the server and if
1826 our buffer is big enough or if we convert to iovecs on socket writes
1827 and eliminate the copy to the CIFS buffer */
1828 if (tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
) {
1829 bytes_sent
= min_t(const unsigned int, CIFSMaxBufSize
, count
);
1831 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
)
1835 if (bytes_sent
> count
)
1838 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1840 memcpy(pSMB
->Data
, buf
, bytes_sent
);
1842 if (copy_from_user(pSMB
->Data
, ubuf
, bytes_sent
)) {
1843 cifs_buf_release(pSMB
);
1846 } else if (count
!= 0) {
1848 cifs_buf_release(pSMB
);
1850 } /* else setting file size with write of zero bytes */
1852 byte_count
= bytes_sent
+ 1; /* pad */
1853 else /* wct == 12 */
1854 byte_count
= bytes_sent
+ 5; /* bigger pad, smaller smb hdr */
1856 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
& 0xFFFF);
1857 pSMB
->DataLengthHigh
= cpu_to_le16(bytes_sent
>> 16);
1858 inc_rfc1001_len(pSMB
, byte_count
);
1861 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1862 else { /* old style write has byte count 4 bytes earlier
1864 struct smb_com_writex_req
*pSMBW
=
1865 (struct smb_com_writex_req
*)pSMB
;
1866 pSMBW
->ByteCount
= cpu_to_le16(byte_count
);
1869 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1870 (struct smb_hdr
*) pSMBr
, &bytes_returned
, long_op
);
1871 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
1873 cifs_dbg(FYI
, "Send error in write = %d\n", rc
);
1875 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
1876 *nbytes
= (*nbytes
) << 16;
1877 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
1880 * Mask off high 16 bits when bytes written as returned by the
1881 * server is greater than bytes requested by the client. Some
1882 * OS/2 servers are known to set incorrect CountHigh values.
1884 if (*nbytes
> count
)
1888 cifs_buf_release(pSMB
);
1890 /* Note: On -EAGAIN error only caller can retry on handle based calls
1891 since file handle passed in no longer valid */
1897 cifs_writedata_release(struct kref
*refcount
)
1899 struct cifs_writedata
*wdata
= container_of(refcount
,
1900 struct cifs_writedata
, refcount
);
1903 cifsFileInfo_put(wdata
->cfile
);
1909 * Write failed with a retryable error. Resend the write request. It's also
1910 * possible that the page was redirtied so re-clean the page.
1913 cifs_writev_requeue(struct cifs_writedata
*wdata
)
1916 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
1917 struct TCP_Server_Info
*server
;
1918 unsigned int rest_len
;
1920 server
= tlink_tcon(wdata
->cfile
->tlink
)->ses
->server
;
1922 rest_len
= wdata
->bytes
;
1924 struct cifs_writedata
*wdata2
;
1925 unsigned int j
, nr_pages
, wsize
, tailsz
, cur_len
;
1927 wsize
= server
->ops
->wp_retry_size(inode
);
1928 if (wsize
< rest_len
) {
1929 nr_pages
= wsize
/ PAGE_CACHE_SIZE
;
1934 cur_len
= nr_pages
* PAGE_CACHE_SIZE
;
1935 tailsz
= PAGE_CACHE_SIZE
;
1937 nr_pages
= DIV_ROUND_UP(rest_len
, PAGE_CACHE_SIZE
);
1939 tailsz
= rest_len
- (nr_pages
- 1) * PAGE_CACHE_SIZE
;
1942 wdata2
= cifs_writedata_alloc(nr_pages
, cifs_writev_complete
);
1948 for (j
= 0; j
< nr_pages
; j
++) {
1949 wdata2
->pages
[j
] = wdata
->pages
[i
+ j
];
1950 lock_page(wdata2
->pages
[j
]);
1951 clear_page_dirty_for_io(wdata2
->pages
[j
]);
1954 wdata2
->sync_mode
= wdata
->sync_mode
;
1955 wdata2
->nr_pages
= nr_pages
;
1956 wdata2
->offset
= page_offset(wdata2
->pages
[0]);
1957 wdata2
->pagesz
= PAGE_CACHE_SIZE
;
1958 wdata2
->tailsz
= tailsz
;
1959 wdata2
->bytes
= cur_len
;
1961 wdata2
->cfile
= find_writable_file(CIFS_I(inode
), false);
1962 if (!wdata2
->cfile
) {
1963 cifs_dbg(VFS
, "No writable handles for inode\n");
1967 wdata2
->pid
= wdata2
->cfile
->pid
;
1968 rc
= server
->ops
->async_writev(wdata2
, cifs_writedata_release
);
1970 for (j
= 0; j
< nr_pages
; j
++) {
1971 unlock_page(wdata2
->pages
[j
]);
1972 if (rc
!= 0 && rc
!= -EAGAIN
) {
1973 SetPageError(wdata2
->pages
[j
]);
1974 end_page_writeback(wdata2
->pages
[j
]);
1975 page_cache_release(wdata2
->pages
[j
]);
1980 kref_put(&wdata2
->refcount
, cifs_writedata_release
);
1986 rest_len
-= cur_len
;
1988 } while (i
< wdata
->nr_pages
);
1990 mapping_set_error(inode
->i_mapping
, rc
);
1991 kref_put(&wdata
->refcount
, cifs_writedata_release
);
1995 cifs_writev_complete(struct work_struct
*work
)
1997 struct cifs_writedata
*wdata
= container_of(work
,
1998 struct cifs_writedata
, work
);
1999 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
2002 if (wdata
->result
== 0) {
2003 spin_lock(&inode
->i_lock
);
2004 cifs_update_eof(CIFS_I(inode
), wdata
->offset
, wdata
->bytes
);
2005 spin_unlock(&inode
->i_lock
);
2006 cifs_stats_bytes_written(tlink_tcon(wdata
->cfile
->tlink
),
2008 } else if (wdata
->sync_mode
== WB_SYNC_ALL
&& wdata
->result
== -EAGAIN
)
2009 return cifs_writev_requeue(wdata
);
2011 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
2012 struct page
*page
= wdata
->pages
[i
];
2013 if (wdata
->result
== -EAGAIN
)
2014 __set_page_dirty_nobuffers(page
);
2015 else if (wdata
->result
< 0)
2017 end_page_writeback(page
);
2018 page_cache_release(page
);
2020 if (wdata
->result
!= -EAGAIN
)
2021 mapping_set_error(inode
->i_mapping
, wdata
->result
);
2022 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2025 struct cifs_writedata
*
2026 cifs_writedata_alloc(unsigned int nr_pages
, work_func_t complete
)
2028 struct cifs_writedata
*wdata
;
2030 /* writedata + number of page pointers */
2031 wdata
= kzalloc(sizeof(*wdata
) +
2032 sizeof(struct page
*) * nr_pages
, GFP_NOFS
);
2033 if (wdata
!= NULL
) {
2034 kref_init(&wdata
->refcount
);
2035 INIT_LIST_HEAD(&wdata
->list
);
2036 init_completion(&wdata
->done
);
2037 INIT_WORK(&wdata
->work
, complete
);
2043 * Check the mid_state and signature on received buffer (if any), and queue the
2044 * workqueue completion task.
2047 cifs_writev_callback(struct mid_q_entry
*mid
)
2049 struct cifs_writedata
*wdata
= mid
->callback_data
;
2050 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2051 unsigned int written
;
2052 WRITE_RSP
*smb
= (WRITE_RSP
*)mid
->resp_buf
;
2054 switch (mid
->mid_state
) {
2055 case MID_RESPONSE_RECEIVED
:
2056 wdata
->result
= cifs_check_receive(mid
, tcon
->ses
->server
, 0);
2057 if (wdata
->result
!= 0)
2060 written
= le16_to_cpu(smb
->CountHigh
);
2062 written
+= le16_to_cpu(smb
->Count
);
2064 * Mask off high 16 bits when bytes written as returned
2065 * by the server is greater than bytes requested by the
2066 * client. OS/2 servers are known to set incorrect
2069 if (written
> wdata
->bytes
)
2072 if (written
< wdata
->bytes
)
2073 wdata
->result
= -ENOSPC
;
2075 wdata
->bytes
= written
;
2077 case MID_REQUEST_SUBMITTED
:
2078 case MID_RETRY_NEEDED
:
2079 wdata
->result
= -EAGAIN
;
2082 wdata
->result
= -EIO
;
2086 queue_work(cifsiod_wq
, &wdata
->work
);
2087 DeleteMidQEntry(mid
);
2088 add_credits(tcon
->ses
->server
, 1, 0);
2091 /* cifs_async_writev - send an async write, and set up mid to handle result */
2093 cifs_async_writev(struct cifs_writedata
*wdata
,
2094 void (*release
)(struct kref
*kref
))
2097 WRITE_REQ
*smb
= NULL
;
2099 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2101 struct smb_rqst rqst
= { };
2103 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2107 if (wdata
->offset
>> 32 > 0) {
2108 /* can not handle big offset for old srv */
2113 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **)&smb
);
2115 goto async_writev_out
;
2117 smb
->hdr
.Pid
= cpu_to_le16((__u16
)wdata
->pid
);
2118 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(wdata
->pid
>> 16));
2120 smb
->AndXCommand
= 0xFF; /* none */
2121 smb
->Fid
= wdata
->cfile
->fid
.netfid
;
2122 smb
->OffsetLow
= cpu_to_le32(wdata
->offset
& 0xFFFFFFFF);
2124 smb
->OffsetHigh
= cpu_to_le32(wdata
->offset
>> 32);
2125 smb
->Reserved
= 0xFFFFFFFF;
2130 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2132 /* 4 for RFC1001 length + 1 for BCC */
2133 iov
.iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4 + 1;
2138 rqst
.rq_pages
= wdata
->pages
;
2139 rqst
.rq_npages
= wdata
->nr_pages
;
2140 rqst
.rq_pagesz
= wdata
->pagesz
;
2141 rqst
.rq_tailsz
= wdata
->tailsz
;
2143 cifs_dbg(FYI
, "async write at %llu %u bytes\n",
2144 wdata
->offset
, wdata
->bytes
);
2146 smb
->DataLengthLow
= cpu_to_le16(wdata
->bytes
& 0xFFFF);
2147 smb
->DataLengthHigh
= cpu_to_le16(wdata
->bytes
>> 16);
2150 inc_rfc1001_len(&smb
->hdr
, wdata
->bytes
+ 1);
2151 put_bcc(wdata
->bytes
+ 1, &smb
->hdr
);
2154 struct smb_com_writex_req
*smbw
=
2155 (struct smb_com_writex_req
*)smb
;
2156 inc_rfc1001_len(&smbw
->hdr
, wdata
->bytes
+ 5);
2157 put_bcc(wdata
->bytes
+ 5, &smbw
->hdr
);
2158 iov
.iov_len
+= 4; /* pad bigger by four bytes */
2161 kref_get(&wdata
->refcount
);
2162 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, NULL
,
2163 cifs_writev_callback
, wdata
, 0);
2166 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2168 kref_put(&wdata
->refcount
, release
);
2171 cifs_small_buf_release(smb
);
2176 CIFSSMBWrite2(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
2177 unsigned int *nbytes
, struct kvec
*iov
, int n_vec
)
2180 WRITE_REQ
*pSMB
= NULL
;
2183 int resp_buf_type
= 0;
2184 __u32 pid
= io_parms
->pid
;
2185 __u16 netfid
= io_parms
->netfid
;
2186 __u64 offset
= io_parms
->offset
;
2187 struct cifs_tcon
*tcon
= io_parms
->tcon
;
2188 unsigned int count
= io_parms
->length
;
2192 cifs_dbg(FYI
, "write2 at %lld %d bytes\n", (long long)offset
, count
);
2194 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2198 if ((offset
>> 32) > 0) {
2199 /* can not handle big offset for old srv */
2203 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
);
2207 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
2208 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
2210 /* tcon and ses pointer are checked in smb_init */
2211 if (tcon
->ses
->server
== NULL
)
2212 return -ECONNABORTED
;
2214 pSMB
->AndXCommand
= 0xFF; /* none */
2216 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
2218 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
2219 pSMB
->Reserved
= 0xFFFFFFFF;
2220 pSMB
->WriteMode
= 0;
2221 pSMB
->Remaining
= 0;
2224 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2226 pSMB
->DataLengthLow
= cpu_to_le16(count
& 0xFFFF);
2227 pSMB
->DataLengthHigh
= cpu_to_le16(count
>> 16);
2228 /* header + 1 byte pad */
2229 smb_hdr_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 1;
2231 inc_rfc1001_len(pSMB
, count
+ 1);
2232 else /* wct == 12 */
2233 inc_rfc1001_len(pSMB
, count
+ 5); /* smb data starts later */
2235 pSMB
->ByteCount
= cpu_to_le16(count
+ 1);
2236 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2237 struct smb_com_writex_req
*pSMBW
=
2238 (struct smb_com_writex_req
*)pSMB
;
2239 pSMBW
->ByteCount
= cpu_to_le16(count
+ 5);
2241 iov
[0].iov_base
= pSMB
;
2243 iov
[0].iov_len
= smb_hdr_len
+ 4;
2244 else /* wct == 12 pad bigger by four bytes */
2245 iov
[0].iov_len
= smb_hdr_len
+ 8;
2248 rc
= SendReceive2(xid
, tcon
->ses
, iov
, n_vec
+ 1, &resp_buf_type
, 0);
2249 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2251 cifs_dbg(FYI
, "Send error Write2 = %d\n", rc
);
2252 } else if (resp_buf_type
== 0) {
2253 /* presumably this can not happen, but best to be safe */
2256 WRITE_RSP
*pSMBr
= (WRITE_RSP
*)iov
[0].iov_base
;
2257 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2258 *nbytes
= (*nbytes
) << 16;
2259 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2262 * Mask off high 16 bits when bytes written as returned by the
2263 * server is greater than bytes requested by the client. OS/2
2264 * servers are known to set incorrect CountHigh values.
2266 if (*nbytes
> count
)
2270 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2271 free_rsp_buf(resp_buf_type
, iov
[0].iov_base
);
2273 /* Note: On -EAGAIN error only caller can retry on handle based calls
2274 since file handle passed in no longer valid */
2279 int cifs_lockv(const unsigned int xid
, struct cifs_tcon
*tcon
,
2280 const __u16 netfid
, const __u8 lock_type
, const __u32 num_unlock
,
2281 const __u32 num_lock
, LOCKING_ANDX_RANGE
*buf
)
2284 LOCK_REQ
*pSMB
= NULL
;
2289 cifs_dbg(FYI
, "cifs_lockv num lock %d num unlock %d\n",
2290 num_lock
, num_unlock
);
2292 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2297 pSMB
->NumberOfLocks
= cpu_to_le16(num_lock
);
2298 pSMB
->NumberOfUnlocks
= cpu_to_le16(num_unlock
);
2299 pSMB
->LockType
= lock_type
;
2300 pSMB
->AndXCommand
= 0xFF; /* none */
2301 pSMB
->Fid
= netfid
; /* netfid stays le */
2303 count
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2304 inc_rfc1001_len(pSMB
, count
);
2305 pSMB
->ByteCount
= cpu_to_le16(count
);
2307 iov
[0].iov_base
= (char *)pSMB
;
2308 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4 -
2309 (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2310 iov
[1].iov_base
= (char *)buf
;
2311 iov
[1].iov_len
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2313 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2314 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 2, &resp_buf_type
, CIFS_NO_RESP
);
2316 cifs_dbg(FYI
, "Send error in cifs_lockv = %d\n", rc
);
2322 CIFSSMBLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2323 const __u16 smb_file_id
, const __u32 netpid
, const __u64 len
,
2324 const __u64 offset
, const __u32 numUnlock
,
2325 const __u32 numLock
, const __u8 lockType
,
2326 const bool waitFlag
, const __u8 oplock_level
)
2329 LOCK_REQ
*pSMB
= NULL
;
2330 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2335 cifs_dbg(FYI
, "CIFSSMBLock timeout %d numLock %d\n",
2336 (int)waitFlag
, numLock
);
2337 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2342 if (lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
2343 /* no response expected */
2344 flags
= CIFS_ASYNC_OP
| CIFS_OBREAK_OP
;
2346 } else if (waitFlag
) {
2347 flags
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2348 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
2353 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
2354 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
2355 pSMB
->LockType
= lockType
;
2356 pSMB
->OplockLevel
= oplock_level
;
2357 pSMB
->AndXCommand
= 0xFF; /* none */
2358 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
2360 if ((numLock
!= 0) || (numUnlock
!= 0)) {
2361 pSMB
->Locks
[0].Pid
= cpu_to_le16(netpid
);
2362 /* BB where to store pid high? */
2363 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
2364 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
2365 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
2366 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
2367 count
= sizeof(LOCKING_ANDX_RANGE
);
2372 inc_rfc1001_len(pSMB
, count
);
2373 pSMB
->ByteCount
= cpu_to_le16(count
);
2376 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2377 (struct smb_hdr
*) pSMB
, &bytes_returned
);
2378 cifs_small_buf_release(pSMB
);
2380 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)pSMB
, flags
);
2381 /* SMB buffer freed by function above */
2383 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2385 cifs_dbg(FYI
, "Send error in Lock = %d\n", rc
);
2387 /* Note: On -EAGAIN error only caller can retry on handle based calls
2388 since file handle passed in no longer valid */
2393 CIFSSMBPosixLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2394 const __u16 smb_file_id
, const __u32 netpid
,
2395 const loff_t start_offset
, const __u64 len
,
2396 struct file_lock
*pLockData
, const __u16 lock_type
,
2397 const bool waitFlag
)
2399 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2400 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2401 struct cifs_posix_lock
*parm_data
;
2404 int bytes_returned
= 0;
2405 int resp_buf_type
= 0;
2406 __u16 params
, param_offset
, offset
, byte_count
, count
;
2409 cifs_dbg(FYI
, "Posix Lock\n");
2411 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
2416 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)pSMB
;
2419 pSMB
->MaxSetupCount
= 0;
2422 pSMB
->Reserved2
= 0;
2423 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2424 offset
= param_offset
+ params
;
2426 count
= sizeof(struct cifs_posix_lock
);
2427 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2428 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2429 pSMB
->SetupCount
= 1;
2430 pSMB
->Reserved3
= 0;
2432 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
2434 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2435 byte_count
= 3 /* pad */ + params
+ count
;
2436 pSMB
->DataCount
= cpu_to_le16(count
);
2437 pSMB
->ParameterCount
= cpu_to_le16(params
);
2438 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2439 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2440 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2441 parm_data
= (struct cifs_posix_lock
*)
2442 (((char *) &pSMB
->hdr
.Protocol
) + offset
);
2444 parm_data
->lock_type
= cpu_to_le16(lock_type
);
2446 timeout
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2447 parm_data
->lock_flags
= cpu_to_le16(1);
2448 pSMB
->Timeout
= cpu_to_le32(-1);
2452 parm_data
->pid
= cpu_to_le32(netpid
);
2453 parm_data
->start
= cpu_to_le64(start_offset
);
2454 parm_data
->length
= cpu_to_le64(len
); /* normalize negative numbers */
2456 pSMB
->DataOffset
= cpu_to_le16(offset
);
2457 pSMB
->Fid
= smb_file_id
;
2458 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_LOCK
);
2459 pSMB
->Reserved4
= 0;
2460 inc_rfc1001_len(pSMB
, byte_count
);
2461 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2463 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2464 (struct smb_hdr
*) pSMBr
, &bytes_returned
);
2466 iov
[0].iov_base
= (char *)pSMB
;
2467 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
2468 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
2469 &resp_buf_type
, timeout
);
2470 pSMB
= NULL
; /* request buf already freed by SendReceive2. Do
2471 not try to free it twice below on exit */
2472 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)iov
[0].iov_base
;
2476 cifs_dbg(FYI
, "Send error in Posix Lock = %d\n", rc
);
2477 } else if (pLockData
) {
2478 /* lock structure can be returned on get */
2481 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2483 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(*parm_data
)) {
2484 rc
= -EIO
; /* bad smb */
2487 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
2488 data_count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2489 if (data_count
< sizeof(struct cifs_posix_lock
)) {
2493 parm_data
= (struct cifs_posix_lock
*)
2494 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2495 if (parm_data
->lock_type
== cpu_to_le16(CIFS_UNLCK
))
2496 pLockData
->fl_type
= F_UNLCK
;
2498 if (parm_data
->lock_type
==
2499 cpu_to_le16(CIFS_RDLCK
))
2500 pLockData
->fl_type
= F_RDLCK
;
2501 else if (parm_data
->lock_type
==
2502 cpu_to_le16(CIFS_WRLCK
))
2503 pLockData
->fl_type
= F_WRLCK
;
2505 pLockData
->fl_start
= le64_to_cpu(parm_data
->start
);
2506 pLockData
->fl_end
= pLockData
->fl_start
+
2507 le64_to_cpu(parm_data
->length
) - 1;
2508 pLockData
->fl_pid
= le32_to_cpu(parm_data
->pid
);
2514 cifs_small_buf_release(pSMB
);
2516 free_rsp_buf(resp_buf_type
, iov
[0].iov_base
);
2518 /* Note: On -EAGAIN error only caller can retry on handle based calls
2519 since file handle passed in no longer valid */
2526 CIFSSMBClose(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2529 CLOSE_REQ
*pSMB
= NULL
;
2530 cifs_dbg(FYI
, "In CIFSSMBClose\n");
2532 /* do not retry on dead session on close */
2533 rc
= small_smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
);
2539 pSMB
->FileID
= (__u16
) smb_file_id
;
2540 pSMB
->LastWriteTime
= 0xFFFFFFFF;
2541 pSMB
->ByteCount
= 0;
2542 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2543 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_closes
);
2546 /* EINTR is expected when user ctl-c to kill app */
2547 cifs_dbg(VFS
, "Send error in Close = %d\n", rc
);
2551 /* Since session is dead, file will be closed on server already */
2559 CIFSSMBFlush(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2562 FLUSH_REQ
*pSMB
= NULL
;
2563 cifs_dbg(FYI
, "In CIFSSMBFlush\n");
2565 rc
= small_smb_init(SMB_COM_FLUSH
, 1, tcon
, (void **) &pSMB
);
2569 pSMB
->FileID
= (__u16
) smb_file_id
;
2570 pSMB
->ByteCount
= 0;
2571 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2572 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_flushes
);
2574 cifs_dbg(VFS
, "Send error in Flush = %d\n", rc
);
2580 CIFSSMBRename(const unsigned int xid
, struct cifs_tcon
*tcon
,
2581 const char *from_name
, const char *to_name
,
2582 struct cifs_sb_info
*cifs_sb
)
2585 RENAME_REQ
*pSMB
= NULL
;
2586 RENAME_RSP
*pSMBr
= NULL
;
2588 int name_len
, name_len2
;
2590 int remap
= cifs_remap(cifs_sb
);
2592 cifs_dbg(FYI
, "In CIFSSMBRename\n");
2594 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
2599 pSMB
->BufferFormat
= 0x04;
2600 pSMB
->SearchAttributes
=
2601 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2604 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2605 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2606 from_name
, PATH_MAX
,
2607 cifs_sb
->local_nls
, remap
);
2608 name_len
++; /* trailing null */
2610 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2611 /* protocol requires ASCII signature byte on Unicode string */
2612 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2614 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2615 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2617 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2618 name_len2
*= 2; /* convert to bytes */
2619 } else { /* BB improve the check for buffer overruns BB */
2620 name_len
= strnlen(from_name
, PATH_MAX
);
2621 name_len
++; /* trailing null */
2622 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
2623 name_len2
= strnlen(to_name
, PATH_MAX
);
2624 name_len2
++; /* trailing null */
2625 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2626 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
2627 name_len2
++; /* trailing null */
2628 name_len2
++; /* signature byte */
2631 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2632 inc_rfc1001_len(pSMB
, count
);
2633 pSMB
->ByteCount
= cpu_to_le16(count
);
2635 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2636 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2637 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_renames
);
2639 cifs_dbg(FYI
, "Send error in rename = %d\n", rc
);
2641 cifs_buf_release(pSMB
);
2649 int CIFSSMBRenameOpenFile(const unsigned int xid
, struct cifs_tcon
*pTcon
,
2650 int netfid
, const char *target_name
,
2651 const struct nls_table
*nls_codepage
, int remap
)
2653 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2654 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2655 struct set_file_rename
*rename_info
;
2657 char dummy_string
[30];
2659 int bytes_returned
= 0;
2661 __u16 params
, param_offset
, offset
, count
, byte_count
;
2663 cifs_dbg(FYI
, "Rename to File by handle\n");
2664 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
2670 pSMB
->MaxSetupCount
= 0;
2674 pSMB
->Reserved2
= 0;
2675 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2676 offset
= param_offset
+ params
;
2678 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2679 rename_info
= (struct set_file_rename
*) data_offset
;
2680 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2681 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2682 pSMB
->SetupCount
= 1;
2683 pSMB
->Reserved3
= 0;
2684 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2685 byte_count
= 3 /* pad */ + params
;
2686 pSMB
->ParameterCount
= cpu_to_le16(params
);
2687 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2688 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2689 pSMB
->DataOffset
= cpu_to_le16(offset
);
2690 /* construct random name ".cifs_tmp<inodenum><mid>" */
2691 rename_info
->overwrite
= cpu_to_le32(1);
2692 rename_info
->root_fid
= 0;
2693 /* unicode only call */
2694 if (target_name
== NULL
) {
2695 sprintf(dummy_string
, "cifs%x", pSMB
->hdr
.Mid
);
2697 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2698 dummy_string
, 24, nls_codepage
, remap
);
2701 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2702 target_name
, PATH_MAX
, nls_codepage
,
2705 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
2706 count
= 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str
);
2707 byte_count
+= count
;
2708 pSMB
->DataCount
= cpu_to_le16(count
);
2709 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2711 pSMB
->InformationLevel
=
2712 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
2713 pSMB
->Reserved4
= 0;
2714 inc_rfc1001_len(pSMB
, byte_count
);
2715 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2716 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
2717 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2718 cifs_stats_inc(&pTcon
->stats
.cifs_stats
.num_t2renames
);
2720 cifs_dbg(FYI
, "Send error in Rename (by file handle) = %d\n",
2723 cifs_buf_release(pSMB
);
2725 /* Note: On -EAGAIN error only caller can retry on handle based calls
2726 since file handle passed in no longer valid */
2732 CIFSSMBCopy(const unsigned int xid
, struct cifs_tcon
*tcon
,
2733 const char *fromName
, const __u16 target_tid
, const char *toName
,
2734 const int flags
, const struct nls_table
*nls_codepage
, int remap
)
2737 COPY_REQ
*pSMB
= NULL
;
2738 COPY_RSP
*pSMBr
= NULL
;
2740 int name_len
, name_len2
;
2743 cifs_dbg(FYI
, "In CIFSSMBCopy\n");
2745 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
2750 pSMB
->BufferFormat
= 0x04;
2751 pSMB
->Tid2
= target_tid
;
2753 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
2755 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2756 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2757 fromName
, PATH_MAX
, nls_codepage
,
2759 name_len
++; /* trailing null */
2761 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2762 /* protocol requires ASCII signature byte on Unicode string */
2763 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2765 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2766 toName
, PATH_MAX
, nls_codepage
, remap
);
2767 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2768 name_len2
*= 2; /* convert to bytes */
2769 } else { /* BB improve the check for buffer overruns BB */
2770 name_len
= strnlen(fromName
, PATH_MAX
);
2771 name_len
++; /* trailing null */
2772 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
2773 name_len2
= strnlen(toName
, PATH_MAX
);
2774 name_len2
++; /* trailing null */
2775 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2776 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
2777 name_len2
++; /* trailing null */
2778 name_len2
++; /* signature byte */
2781 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2782 inc_rfc1001_len(pSMB
, count
);
2783 pSMB
->ByteCount
= cpu_to_le16(count
);
2785 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2786 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2788 cifs_dbg(FYI
, "Send error in copy = %d with %d files copied\n",
2789 rc
, le16_to_cpu(pSMBr
->CopyCount
));
2791 cifs_buf_release(pSMB
);
2800 CIFSUnixCreateSymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2801 const char *fromName
, const char *toName
,
2802 const struct nls_table
*nls_codepage
, int remap
)
2804 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2805 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2808 int name_len_target
;
2810 int bytes_returned
= 0;
2811 __u16 params
, param_offset
, offset
, byte_count
;
2813 cifs_dbg(FYI
, "In Symlink Unix style\n");
2815 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2820 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2822 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fromName
,
2823 /* find define for this maxpathcomponent */
2824 PATH_MAX
, nls_codepage
, remap
);
2825 name_len
++; /* trailing null */
2828 } else { /* BB improve the check for buffer overruns BB */
2829 name_len
= strnlen(fromName
, PATH_MAX
);
2830 name_len
++; /* trailing null */
2831 strncpy(pSMB
->FileName
, fromName
, name_len
);
2833 params
= 6 + name_len
;
2834 pSMB
->MaxSetupCount
= 0;
2838 pSMB
->Reserved2
= 0;
2839 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2840 InformationLevel
) - 4;
2841 offset
= param_offset
+ params
;
2843 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2844 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2846 cifsConvertToUTF16((__le16
*) data_offset
, toName
,
2847 /* find define for this maxpathcomponent */
2848 PATH_MAX
, nls_codepage
, remap
);
2849 name_len_target
++; /* trailing null */
2850 name_len_target
*= 2;
2851 } else { /* BB improve the check for buffer overruns BB */
2852 name_len_target
= strnlen(toName
, PATH_MAX
);
2853 name_len_target
++; /* trailing null */
2854 strncpy(data_offset
, toName
, name_len_target
);
2857 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2858 /* BB find exact max on data count below from sess */
2859 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2860 pSMB
->SetupCount
= 1;
2861 pSMB
->Reserved3
= 0;
2862 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2863 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2864 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2865 pSMB
->ParameterCount
= cpu_to_le16(params
);
2866 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2867 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2868 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2869 pSMB
->DataOffset
= cpu_to_le16(offset
);
2870 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
2871 pSMB
->Reserved4
= 0;
2872 inc_rfc1001_len(pSMB
, byte_count
);
2873 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2874 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2875 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2876 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_symlinks
);
2878 cifs_dbg(FYI
, "Send error in SetPathInfo create symlink = %d\n",
2881 cifs_buf_release(pSMB
);
2884 goto createSymLinkRetry
;
2890 CIFSUnixCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2891 const char *fromName
, const char *toName
,
2892 const struct nls_table
*nls_codepage
, int remap
)
2894 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2895 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2898 int name_len_target
;
2900 int bytes_returned
= 0;
2901 __u16 params
, param_offset
, offset
, byte_count
;
2903 cifs_dbg(FYI
, "In Create Hard link Unix style\n");
2904 createHardLinkRetry
:
2905 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2910 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2911 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->FileName
, toName
,
2912 PATH_MAX
, nls_codepage
, remap
);
2913 name_len
++; /* trailing null */
2916 } else { /* BB improve the check for buffer overruns BB */
2917 name_len
= strnlen(toName
, PATH_MAX
);
2918 name_len
++; /* trailing null */
2919 strncpy(pSMB
->FileName
, toName
, name_len
);
2921 params
= 6 + name_len
;
2922 pSMB
->MaxSetupCount
= 0;
2926 pSMB
->Reserved2
= 0;
2927 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2928 InformationLevel
) - 4;
2929 offset
= param_offset
+ params
;
2931 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2932 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2934 cifsConvertToUTF16((__le16
*) data_offset
, fromName
,
2935 PATH_MAX
, nls_codepage
, remap
);
2936 name_len_target
++; /* trailing null */
2937 name_len_target
*= 2;
2938 } else { /* BB improve the check for buffer overruns BB */
2939 name_len_target
= strnlen(fromName
, PATH_MAX
);
2940 name_len_target
++; /* trailing null */
2941 strncpy(data_offset
, fromName
, name_len_target
);
2944 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2945 /* BB find exact max on data count below from sess*/
2946 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2947 pSMB
->SetupCount
= 1;
2948 pSMB
->Reserved3
= 0;
2949 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2950 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2951 pSMB
->ParameterCount
= cpu_to_le16(params
);
2952 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2953 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2954 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2955 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2956 pSMB
->DataOffset
= cpu_to_le16(offset
);
2957 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
2958 pSMB
->Reserved4
= 0;
2959 inc_rfc1001_len(pSMB
, byte_count
);
2960 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2961 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2962 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2963 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
2965 cifs_dbg(FYI
, "Send error in SetPathInfo (hard link) = %d\n",
2968 cifs_buf_release(pSMB
);
2970 goto createHardLinkRetry
;
2976 CIFSCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2977 const char *from_name
, const char *to_name
,
2978 struct cifs_sb_info
*cifs_sb
)
2981 NT_RENAME_REQ
*pSMB
= NULL
;
2982 RENAME_RSP
*pSMBr
= NULL
;
2984 int name_len
, name_len2
;
2986 int remap
= cifs_remap(cifs_sb
);
2988 cifs_dbg(FYI
, "In CIFSCreateHardLink\n");
2989 winCreateHardLinkRetry
:
2991 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
2996 pSMB
->SearchAttributes
=
2997 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2999 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
3000 pSMB
->ClusterCount
= 0;
3002 pSMB
->BufferFormat
= 0x04;
3004 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3006 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, from_name
,
3007 PATH_MAX
, cifs_sb
->local_nls
, remap
);
3008 name_len
++; /* trailing null */
3011 /* protocol specifies ASCII buffer format (0x04) for unicode */
3012 pSMB
->OldFileName
[name_len
] = 0x04;
3013 pSMB
->OldFileName
[name_len
+ 1] = 0x00; /* pad */
3015 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
3016 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
3018 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
3019 name_len2
*= 2; /* convert to bytes */
3020 } else { /* BB improve the check for buffer overruns BB */
3021 name_len
= strnlen(from_name
, PATH_MAX
);
3022 name_len
++; /* trailing null */
3023 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
3024 name_len2
= strnlen(to_name
, PATH_MAX
);
3025 name_len2
++; /* trailing null */
3026 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
3027 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
3028 name_len2
++; /* trailing null */
3029 name_len2
++; /* signature byte */
3032 count
= 1 /* string type byte */ + name_len
+ name_len2
;
3033 inc_rfc1001_len(pSMB
, count
);
3034 pSMB
->ByteCount
= cpu_to_le16(count
);
3036 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3037 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3038 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3040 cifs_dbg(FYI
, "Send error in hard link (NT rename) = %d\n", rc
);
3042 cifs_buf_release(pSMB
);
3044 goto winCreateHardLinkRetry
;
3050 CIFSSMBUnixQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3051 const unsigned char *searchName
, char **symlinkinfo
,
3052 const struct nls_table
*nls_codepage
, int remap
)
3054 /* SMB_QUERY_FILE_UNIX_LINK */
3055 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3056 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3060 __u16 params
, byte_count
;
3063 cifs_dbg(FYI
, "In QPathSymLinkInfo (Unix) for path %s\n", searchName
);
3066 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3071 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3073 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3074 searchName
, PATH_MAX
, nls_codepage
,
3076 name_len
++; /* trailing null */
3078 } else { /* BB improve the check for buffer overruns BB */
3079 name_len
= strnlen(searchName
, PATH_MAX
);
3080 name_len
++; /* trailing null */
3081 strncpy(pSMB
->FileName
, searchName
, name_len
);
3084 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3085 pSMB
->TotalDataCount
= 0;
3086 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3087 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3088 pSMB
->MaxSetupCount
= 0;
3092 pSMB
->Reserved2
= 0;
3093 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3094 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3095 pSMB
->DataCount
= 0;
3096 pSMB
->DataOffset
= 0;
3097 pSMB
->SetupCount
= 1;
3098 pSMB
->Reserved3
= 0;
3099 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3100 byte_count
= params
+ 1 /* pad */ ;
3101 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3102 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3103 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
3104 pSMB
->Reserved4
= 0;
3105 inc_rfc1001_len(pSMB
, byte_count
);
3106 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3108 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3109 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3111 cifs_dbg(FYI
, "Send error in QuerySymLinkInfo = %d\n", rc
);
3113 /* decode response */
3115 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3116 /* BB also check enough total bytes returned */
3117 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3121 u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3123 data_start
= ((char *) &pSMBr
->hdr
.Protocol
) +
3124 le16_to_cpu(pSMBr
->t2
.DataOffset
);
3126 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3131 /* BB FIXME investigate remapping reserved chars here */
3132 *symlinkinfo
= cifs_strndup_from_utf16(data_start
,
3133 count
, is_unicode
, nls_codepage
);
3138 cifs_buf_release(pSMB
);
3140 goto querySymLinkRetry
;
3145 * Recent Windows versions now create symlinks more frequently
3146 * and they use the "reparse point" mechanism below. We can of course
3147 * do symlinks nicely to Samba and other servers which support the
3148 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3149 * "MF" symlinks optionally, but for recent Windows we really need to
3150 * reenable the code below and fix the cifs_symlink callers to handle this.
3151 * In the interim this code has been moved to its own config option so
3152 * it is not compiled in by default until callers fixed up and more tested.
3155 CIFSSMBQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3156 __u16 fid
, char **symlinkinfo
,
3157 const struct nls_table
*nls_codepage
)
3161 struct smb_com_transaction_ioctl_req
*pSMB
;
3162 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3164 unsigned int sub_len
;
3166 struct reparse_symlink_data
*reparse_buf
;
3167 struct reparse_posix_data
*posix_buf
;
3168 __u32 data_offset
, data_count
;
3171 cifs_dbg(FYI
, "In Windows reparse style QueryLink for fid %u\n", fid
);
3172 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3177 pSMB
->TotalParameterCount
= 0 ;
3178 pSMB
->TotalDataCount
= 0;
3179 pSMB
->MaxParameterCount
= cpu_to_le32(2);
3180 /* BB find exact data count max from sess structure BB */
3181 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3182 pSMB
->MaxSetupCount
= 4;
3184 pSMB
->ParameterOffset
= 0;
3185 pSMB
->DataCount
= 0;
3186 pSMB
->DataOffset
= 0;
3187 pSMB
->SetupCount
= 4;
3188 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3189 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3190 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
3191 pSMB
->IsFsctl
= 1; /* FSCTL */
3192 pSMB
->IsRootFlag
= 0;
3193 pSMB
->Fid
= fid
; /* file handle always le */
3194 pSMB
->ByteCount
= 0;
3196 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3197 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3199 cifs_dbg(FYI
, "Send error in QueryReparseLinkInfo = %d\n", rc
);
3203 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3204 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3205 if (get_bcc(&pSMBr
->hdr
) < 2 || data_offset
> 512) {
3206 /* BB also check enough total bytes returned */
3207 rc
= -EIO
; /* bad smb */
3210 if (!data_count
|| (data_count
> 2048)) {
3212 cifs_dbg(FYI
, "Invalid return data count on get reparse info ioctl\n");
3215 end_of_smb
= 2 + get_bcc(&pSMBr
->hdr
) + (char *)&pSMBr
->ByteCount
;
3216 reparse_buf
= (struct reparse_symlink_data
*)
3217 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
3218 if ((char *)reparse_buf
>= end_of_smb
) {
3222 if (reparse_buf
->ReparseTag
== cpu_to_le32(IO_REPARSE_TAG_NFS
)) {
3223 cifs_dbg(FYI
, "NFS style reparse tag\n");
3224 posix_buf
= (struct reparse_posix_data
*)reparse_buf
;
3226 if (posix_buf
->InodeType
!= cpu_to_le64(NFS_SPECFILE_LNK
)) {
3227 cifs_dbg(FYI
, "unsupported file type 0x%llx\n",
3228 le64_to_cpu(posix_buf
->InodeType
));
3233 sub_len
= le16_to_cpu(reparse_buf
->ReparseDataLength
);
3234 if (posix_buf
->PathBuffer
+ sub_len
> end_of_smb
) {
3235 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3239 *symlinkinfo
= cifs_strndup_from_utf16(posix_buf
->PathBuffer
,
3240 sub_len
, is_unicode
, nls_codepage
);
3242 } else if (reparse_buf
->ReparseTag
!=
3243 cpu_to_le32(IO_REPARSE_TAG_SYMLINK
)) {
3248 /* Reparse tag is NTFS symlink */
3249 sub_start
= le16_to_cpu(reparse_buf
->SubstituteNameOffset
) +
3250 reparse_buf
->PathBuffer
;
3251 sub_len
= le16_to_cpu(reparse_buf
->SubstituteNameLength
);
3252 if (sub_start
+ sub_len
> end_of_smb
) {
3253 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3257 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3262 /* BB FIXME investigate remapping reserved chars here */
3263 *symlinkinfo
= cifs_strndup_from_utf16(sub_start
, sub_len
, is_unicode
,
3268 cifs_buf_release(pSMB
);
3271 * Note: On -EAGAIN error only caller can retry on handle based calls
3272 * since file handle passed in no longer valid.
3278 CIFSSMB_set_compression(const unsigned int xid
, struct cifs_tcon
*tcon
,
3283 struct smb_com_transaction_compr_ioctl_req
*pSMB
;
3284 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3286 cifs_dbg(FYI
, "Set compression for %u\n", fid
);
3287 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3292 pSMB
->compression_state
= cpu_to_le16(COMPRESSION_FORMAT_DEFAULT
);
3294 pSMB
->TotalParameterCount
= 0;
3295 pSMB
->TotalDataCount
= cpu_to_le32(2);
3296 pSMB
->MaxParameterCount
= 0;
3297 pSMB
->MaxDataCount
= 0;
3298 pSMB
->MaxSetupCount
= 4;
3300 pSMB
->ParameterOffset
= 0;
3301 pSMB
->DataCount
= cpu_to_le32(2);
3303 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req
,
3304 compression_state
) - 4); /* 84 */
3305 pSMB
->SetupCount
= 4;
3306 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3307 pSMB
->ParameterCount
= 0;
3308 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_SET_COMPRESSION
);
3309 pSMB
->IsFsctl
= 1; /* FSCTL */
3310 pSMB
->IsRootFlag
= 0;
3311 pSMB
->Fid
= fid
; /* file handle always le */
3312 /* 3 byte pad, followed by 2 byte compress state */
3313 pSMB
->ByteCount
= cpu_to_le16(5);
3314 inc_rfc1001_len(pSMB
, 5);
3316 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3317 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3319 cifs_dbg(FYI
, "Send error in SetCompression = %d\n", rc
);
3321 cifs_buf_release(pSMB
);
3324 * Note: On -EAGAIN error only caller can retry on handle based calls
3325 * since file handle passed in no longer valid.
3331 #ifdef CONFIG_CIFS_POSIX
3333 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3334 static void cifs_convert_ace(posix_acl_xattr_entry
*ace
,
3335 struct cifs_posix_ace
*cifs_ace
)
3337 /* u8 cifs fields do not need le conversion */
3338 ace
->e_perm
= cpu_to_le16(cifs_ace
->cifs_e_perm
);
3339 ace
->e_tag
= cpu_to_le16(cifs_ace
->cifs_e_tag
);
3340 ace
->e_id
= cpu_to_le32(le64_to_cpu(cifs_ace
->cifs_uid
));
3342 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3343 ace->e_perm, ace->e_tag, ace->e_id);
3349 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3350 static int cifs_copy_posix_acl(char *trgt
, char *src
, const int buflen
,
3351 const int acl_type
, const int size_of_data_area
)
3356 struct cifs_posix_ace
*pACE
;
3357 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)src
;
3358 posix_acl_xattr_header
*local_acl
= (posix_acl_xattr_header
*)trgt
;
3360 if (le16_to_cpu(cifs_acl
->version
) != CIFS_ACL_VERSION
)
3363 if (acl_type
& ACL_TYPE_ACCESS
) {
3364 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3365 pACE
= &cifs_acl
->ace_array
[0];
3366 size
= sizeof(struct cifs_posix_acl
);
3367 size
+= sizeof(struct cifs_posix_ace
) * count
;
3368 /* check if we would go beyond end of SMB */
3369 if (size_of_data_area
< size
) {
3370 cifs_dbg(FYI
, "bad CIFS POSIX ACL size %d vs. %d\n",
3371 size_of_data_area
, size
);
3374 } else if (acl_type
& ACL_TYPE_DEFAULT
) {
3375 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3376 size
= sizeof(struct cifs_posix_acl
);
3377 size
+= sizeof(struct cifs_posix_ace
) * count
;
3378 /* skip past access ACEs to get to default ACEs */
3379 pACE
= &cifs_acl
->ace_array
[count
];
3380 count
= le16_to_cpu(cifs_acl
->default_entry_count
);
3381 size
+= sizeof(struct cifs_posix_ace
) * count
;
3382 /* check if we would go beyond end of SMB */
3383 if (size_of_data_area
< size
)
3390 size
= posix_acl_xattr_size(count
);
3391 if ((buflen
== 0) || (local_acl
== NULL
)) {
3392 /* used to query ACL EA size */
3393 } else if (size
> buflen
) {
3395 } else /* buffer big enough */ {
3396 local_acl
->a_version
= cpu_to_le32(POSIX_ACL_XATTR_VERSION
);
3397 for (i
= 0; i
< count
; i
++) {
3398 cifs_convert_ace(&local_acl
->a_entries
[i
], pACE
);
3405 static __u16
convert_ace_to_cifs_ace(struct cifs_posix_ace
*cifs_ace
,
3406 const posix_acl_xattr_entry
*local_ace
)
3408 __u16 rc
= 0; /* 0 = ACL converted ok */
3410 cifs_ace
->cifs_e_perm
= le16_to_cpu(local_ace
->e_perm
);
3411 cifs_ace
->cifs_e_tag
= le16_to_cpu(local_ace
->e_tag
);
3412 /* BB is there a better way to handle the large uid? */
3413 if (local_ace
->e_id
== cpu_to_le32(-1)) {
3414 /* Probably no need to le convert -1 on any arch but can not hurt */
3415 cifs_ace
->cifs_uid
= cpu_to_le64(-1);
3417 cifs_ace
->cifs_uid
= cpu_to_le64(le32_to_cpu(local_ace
->e_id
));
3419 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3420 ace->e_perm, ace->e_tag, ace->e_id);
3425 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3426 static __u16
ACL_to_cifs_posix(char *parm_data
, const char *pACL
,
3427 const int buflen
, const int acl_type
)
3430 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)parm_data
;
3431 posix_acl_xattr_header
*local_acl
= (posix_acl_xattr_header
*)pACL
;
3435 if ((buflen
== 0) || (pACL
== NULL
) || (cifs_acl
== NULL
))
3438 count
= posix_acl_xattr_count((size_t)buflen
);
3439 cifs_dbg(FYI
, "setting acl with %d entries from buf of length %d and version of %d\n",
3440 count
, buflen
, le32_to_cpu(local_acl
->a_version
));
3441 if (le32_to_cpu(local_acl
->a_version
) != 2) {
3442 cifs_dbg(FYI
, "unknown POSIX ACL version %d\n",
3443 le32_to_cpu(local_acl
->a_version
));
3446 cifs_acl
->version
= cpu_to_le16(1);
3447 if (acl_type
== ACL_TYPE_ACCESS
) {
3448 cifs_acl
->access_entry_count
= cpu_to_le16(count
);
3449 cifs_acl
->default_entry_count
= cpu_to_le16(0xFFFF);
3450 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3451 cifs_acl
->default_entry_count
= cpu_to_le16(count
);
3452 cifs_acl
->access_entry_count
= cpu_to_le16(0xFFFF);
3454 cifs_dbg(FYI
, "unknown ACL type %d\n", acl_type
);
3457 for (i
= 0; i
< count
; i
++) {
3458 rc
= convert_ace_to_cifs_ace(&cifs_acl
->ace_array
[i
],
3459 &local_acl
->a_entries
[i
]);
3461 /* ACE not converted */
3466 rc
= (__u16
)(count
* sizeof(struct cifs_posix_ace
));
3467 rc
+= sizeof(struct cifs_posix_acl
);
3468 /* BB add check to make sure ACL does not overflow SMB */
3474 CIFSSMBGetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3475 const unsigned char *searchName
,
3476 char *acl_inf
, const int buflen
, const int acl_type
,
3477 const struct nls_table
*nls_codepage
, int remap
)
3479 /* SMB_QUERY_POSIX_ACL */
3480 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3481 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3485 __u16 params
, byte_count
;
3487 cifs_dbg(FYI
, "In GetPosixACL (Unix) for path %s\n", searchName
);
3490 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3495 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3497 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3498 searchName
, PATH_MAX
, nls_codepage
,
3500 name_len
++; /* trailing null */
3502 pSMB
->FileName
[name_len
] = 0;
3503 pSMB
->FileName
[name_len
+1] = 0;
3504 } else { /* BB improve the check for buffer overruns BB */
3505 name_len
= strnlen(searchName
, PATH_MAX
);
3506 name_len
++; /* trailing null */
3507 strncpy(pSMB
->FileName
, searchName
, name_len
);
3510 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3511 pSMB
->TotalDataCount
= 0;
3512 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3513 /* BB find exact max data count below from sess structure BB */
3514 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3515 pSMB
->MaxSetupCount
= 0;
3519 pSMB
->Reserved2
= 0;
3520 pSMB
->ParameterOffset
= cpu_to_le16(
3521 offsetof(struct smb_com_transaction2_qpi_req
,
3522 InformationLevel
) - 4);
3523 pSMB
->DataCount
= 0;
3524 pSMB
->DataOffset
= 0;
3525 pSMB
->SetupCount
= 1;
3526 pSMB
->Reserved3
= 0;
3527 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3528 byte_count
= params
+ 1 /* pad */ ;
3529 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3530 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3531 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_ACL
);
3532 pSMB
->Reserved4
= 0;
3533 inc_rfc1001_len(pSMB
, byte_count
);
3534 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3536 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3537 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3538 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3540 cifs_dbg(FYI
, "Send error in Query POSIX ACL = %d\n", rc
);
3542 /* decode response */
3544 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3545 /* BB also check enough total bytes returned */
3546 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3547 rc
= -EIO
; /* bad smb */
3549 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3550 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3551 rc
= cifs_copy_posix_acl(acl_inf
,
3552 (char *)&pSMBr
->hdr
.Protocol
+data_offset
,
3553 buflen
, acl_type
, count
);
3556 cifs_buf_release(pSMB
);
3563 CIFSSMBSetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3564 const unsigned char *fileName
,
3565 const char *local_acl
, const int buflen
,
3567 const struct nls_table
*nls_codepage
, int remap
)
3569 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3570 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3574 int bytes_returned
= 0;
3575 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
3577 cifs_dbg(FYI
, "In SetPosixACL (Unix) for path %s\n", fileName
);
3579 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3583 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3585 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
3586 PATH_MAX
, nls_codepage
, remap
);
3587 name_len
++; /* trailing null */
3589 } else { /* BB improve the check for buffer overruns BB */
3590 name_len
= strnlen(fileName
, PATH_MAX
);
3591 name_len
++; /* trailing null */
3592 strncpy(pSMB
->FileName
, fileName
, name_len
);
3594 params
= 6 + name_len
;
3595 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3596 /* BB find max SMB size from sess */
3597 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3598 pSMB
->MaxSetupCount
= 0;
3602 pSMB
->Reserved2
= 0;
3603 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3604 InformationLevel
) - 4;
3605 offset
= param_offset
+ params
;
3606 parm_data
= ((char *) &pSMB
->hdr
.Protocol
) + offset
;
3607 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3609 /* convert to on the wire format for POSIX ACL */
3610 data_count
= ACL_to_cifs_posix(parm_data
, local_acl
, buflen
, acl_type
);
3612 if (data_count
== 0) {
3614 goto setACLerrorExit
;
3616 pSMB
->DataOffset
= cpu_to_le16(offset
);
3617 pSMB
->SetupCount
= 1;
3618 pSMB
->Reserved3
= 0;
3619 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3620 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_ACL
);
3621 byte_count
= 3 /* pad */ + params
+ data_count
;
3622 pSMB
->DataCount
= cpu_to_le16(data_count
);
3623 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3624 pSMB
->ParameterCount
= cpu_to_le16(params
);
3625 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3626 pSMB
->Reserved4
= 0;
3627 inc_rfc1001_len(pSMB
, byte_count
);
3628 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3629 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3630 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3632 cifs_dbg(FYI
, "Set POSIX ACL returned %d\n", rc
);
3635 cifs_buf_release(pSMB
);
3641 /* BB fix tabs in this function FIXME BB */
3643 CIFSGetExtAttr(const unsigned int xid
, struct cifs_tcon
*tcon
,
3644 const int netfid
, __u64
*pExtAttrBits
, __u64
*pMask
)
3647 struct smb_t2_qfi_req
*pSMB
= NULL
;
3648 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3650 __u16 params
, byte_count
;
3652 cifs_dbg(FYI
, "In GetExtAttr\n");
3657 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3662 params
= 2 /* level */ + 2 /* fid */;
3663 pSMB
->t2
.TotalDataCount
= 0;
3664 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3665 /* BB find exact max data count below from sess structure BB */
3666 pSMB
->t2
.MaxDataCount
= cpu_to_le16(4000);
3667 pSMB
->t2
.MaxSetupCount
= 0;
3668 pSMB
->t2
.Reserved
= 0;
3670 pSMB
->t2
.Timeout
= 0;
3671 pSMB
->t2
.Reserved2
= 0;
3672 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3674 pSMB
->t2
.DataCount
= 0;
3675 pSMB
->t2
.DataOffset
= 0;
3676 pSMB
->t2
.SetupCount
= 1;
3677 pSMB
->t2
.Reserved3
= 0;
3678 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3679 byte_count
= params
+ 1 /* pad */ ;
3680 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3681 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3682 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_ATTR_FLAGS
);
3685 inc_rfc1001_len(pSMB
, byte_count
);
3686 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3688 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3689 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3691 cifs_dbg(FYI
, "error %d in GetExtAttr\n", rc
);
3693 /* decode response */
3694 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3695 /* BB also check enough total bytes returned */
3696 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3697 /* If rc should we check for EOPNOSUPP and
3698 disable the srvino flag? or in caller? */
3699 rc
= -EIO
; /* bad smb */
3701 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3702 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3703 struct file_chattr_info
*pfinfo
;
3704 /* BB Do we need a cast or hash here ? */
3706 cifs_dbg(FYI
, "Illegal size ret in GetExtAttr\n");
3710 pfinfo
= (struct file_chattr_info
*)
3711 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
3712 *pExtAttrBits
= le64_to_cpu(pfinfo
->mode
);
3713 *pMask
= le64_to_cpu(pfinfo
->mask
);
3717 cifs_buf_release(pSMB
);
3719 goto GetExtAttrRetry
;
3723 #endif /* CONFIG_POSIX */
3725 #ifdef CONFIG_CIFS_ACL
3727 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3728 * all NT TRANSACTS that we init here have total parm and data under about 400
3729 * bytes (to fit in small cifs buffer size), which is the case so far, it
3730 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3731 * returned setup area) and MaxParameterCount (returned parms size) must be set
3735 smb_init_nttransact(const __u16 sub_command
, const int setup_count
,
3736 const int parm_len
, struct cifs_tcon
*tcon
,
3741 struct smb_com_ntransact_req
*pSMB
;
3743 rc
= small_smb_init(SMB_COM_NT_TRANSACT
, 19 + setup_count
, tcon
,
3747 *ret_buf
= (void *)pSMB
;
3749 pSMB
->TotalParameterCount
= cpu_to_le32(parm_len
);
3750 pSMB
->TotalDataCount
= 0;
3751 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3752 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3753 pSMB
->DataCount
= pSMB
->TotalDataCount
;
3754 temp_offset
= offsetof(struct smb_com_ntransact_req
, Parms
) +
3755 (setup_count
* 2) - 4 /* for rfc1001 length itself */;
3756 pSMB
->ParameterOffset
= cpu_to_le32(temp_offset
);
3757 pSMB
->DataOffset
= cpu_to_le32(temp_offset
+ parm_len
);
3758 pSMB
->SetupCount
= setup_count
; /* no need to le convert byte fields */
3759 pSMB
->SubCommand
= cpu_to_le16(sub_command
);
3764 validate_ntransact(char *buf
, char **ppparm
, char **ppdata
,
3765 __u32
*pparmlen
, __u32
*pdatalen
)
3768 __u32 data_count
, data_offset
, parm_count
, parm_offset
;
3769 struct smb_com_ntransact_rsp
*pSMBr
;
3778 pSMBr
= (struct smb_com_ntransact_rsp
*)buf
;
3780 bcc
= get_bcc(&pSMBr
->hdr
);
3781 end_of_smb
= 2 /* sizeof byte count */ + bcc
+
3782 (char *)&pSMBr
->ByteCount
;
3784 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3785 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3786 parm_offset
= le32_to_cpu(pSMBr
->ParameterOffset
);
3787 parm_count
= le32_to_cpu(pSMBr
->ParameterCount
);
3789 *ppparm
= (char *)&pSMBr
->hdr
.Protocol
+ parm_offset
;
3790 *ppdata
= (char *)&pSMBr
->hdr
.Protocol
+ data_offset
;
3792 /* should we also check that parm and data areas do not overlap? */
3793 if (*ppparm
> end_of_smb
) {
3794 cifs_dbg(FYI
, "parms start after end of smb\n");
3796 } else if (parm_count
+ *ppparm
> end_of_smb
) {
3797 cifs_dbg(FYI
, "parm end after end of smb\n");
3799 } else if (*ppdata
> end_of_smb
) {
3800 cifs_dbg(FYI
, "data starts after end of smb\n");
3802 } else if (data_count
+ *ppdata
> end_of_smb
) {
3803 cifs_dbg(FYI
, "data %p + count %d (%p) past smb end %p start %p\n",
3804 *ppdata
, data_count
, (data_count
+ *ppdata
),
3807 } else if (parm_count
+ data_count
> bcc
) {
3808 cifs_dbg(FYI
, "parm count and data count larger than SMB\n");
3811 *pdatalen
= data_count
;
3812 *pparmlen
= parm_count
;
3816 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3818 CIFSSMBGetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3819 struct cifs_ntsd
**acl_inf
, __u32
*pbuflen
)
3823 QUERY_SEC_DESC_REQ
*pSMB
;
3826 cifs_dbg(FYI
, "GetCifsACL\n");
3831 rc
= smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC
, 0,
3832 8 /* parm len */, tcon
, (void **) &pSMB
);
3836 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3837 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3838 pSMB
->MaxSetupCount
= 0;
3839 pSMB
->Fid
= fid
; /* file handle always le */
3840 pSMB
->AclFlags
= cpu_to_le32(CIFS_ACL_OWNER
| CIFS_ACL_GROUP
|
3842 pSMB
->ByteCount
= cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3843 inc_rfc1001_len(pSMB
, 11);
3844 iov
[0].iov_base
= (char *)pSMB
;
3845 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
3847 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovec */, &buf_type
,
3849 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3851 cifs_dbg(FYI
, "Send error in QuerySecDesc = %d\n", rc
);
3852 } else { /* decode response */
3856 struct smb_com_ntransact_rsp
*pSMBr
;
3859 /* validate_nttransact */
3860 rc
= validate_ntransact(iov
[0].iov_base
, (char **)&parm
,
3861 &pdata
, &parm_len
, pbuflen
);
3864 pSMBr
= (struct smb_com_ntransact_rsp
*)iov
[0].iov_base
;
3866 cifs_dbg(FYI
, "smb %p parm %p data %p\n",
3867 pSMBr
, parm
, *acl_inf
);
3869 if (le32_to_cpu(pSMBr
->ParameterCount
) != 4) {
3870 rc
= -EIO
; /* bad smb */
3875 /* BB check that data area is minimum length and as big as acl_len */
3877 acl_len
= le32_to_cpu(*parm
);
3878 if (acl_len
!= *pbuflen
) {
3879 cifs_dbg(VFS
, "acl length %d does not match %d\n",
3881 if (*pbuflen
> acl_len
)
3885 /* check if buffer is big enough for the acl
3886 header followed by the smallest SID */
3887 if ((*pbuflen
< sizeof(struct cifs_ntsd
) + 8) ||
3888 (*pbuflen
>= 64 * 1024)) {
3889 cifs_dbg(VFS
, "bad acl length %d\n", *pbuflen
);
3893 *acl_inf
= kmemdup(pdata
, *pbuflen
, GFP_KERNEL
);
3894 if (*acl_inf
== NULL
) {
3901 free_rsp_buf(buf_type
, iov
[0].iov_base
);
3902 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3907 CIFSSMBSetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3908 struct cifs_ntsd
*pntsd
, __u32 acllen
, int aclflag
)
3910 __u16 byte_count
, param_count
, data_count
, param_offset
, data_offset
;
3912 int bytes_returned
= 0;
3913 SET_SEC_DESC_REQ
*pSMB
= NULL
;
3917 rc
= smb_init(SMB_COM_NT_TRANSACT
, 19, tcon
, (void **) &pSMB
, &pSMBr
);
3921 pSMB
->MaxSetupCount
= 0;
3925 param_offset
= offsetof(struct smb_com_transaction_ssec_req
, Fid
) - 4;
3926 data_count
= acllen
;
3927 data_offset
= param_offset
+ param_count
;
3928 byte_count
= 3 /* pad */ + param_count
;
3930 pSMB
->DataCount
= cpu_to_le32(data_count
);
3931 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3932 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3933 pSMB
->MaxDataCount
= cpu_to_le32(16384);
3934 pSMB
->ParameterCount
= cpu_to_le32(param_count
);
3935 pSMB
->ParameterOffset
= cpu_to_le32(param_offset
);
3936 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3937 pSMB
->DataOffset
= cpu_to_le32(data_offset
);
3938 pSMB
->SetupCount
= 0;
3939 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC
);
3940 pSMB
->ByteCount
= cpu_to_le16(byte_count
+data_count
);
3942 pSMB
->Fid
= fid
; /* file handle always le */
3943 pSMB
->Reserved2
= 0;
3944 pSMB
->AclFlags
= cpu_to_le32(aclflag
);
3946 if (pntsd
&& acllen
) {
3947 memcpy((char *)pSMBr
+ offsetof(struct smb_hdr
, Protocol
) +
3948 data_offset
, pntsd
, acllen
);
3949 inc_rfc1001_len(pSMB
, byte_count
+ data_count
);
3951 inc_rfc1001_len(pSMB
, byte_count
);
3953 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3954 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3956 cifs_dbg(FYI
, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3957 bytes_returned
, rc
);
3959 cifs_dbg(FYI
, "Set CIFS ACL returned %d\n", rc
);
3960 cifs_buf_release(pSMB
);
3963 goto setCifsAclRetry
;
3968 #endif /* CONFIG_CIFS_ACL */
3970 /* Legacy Query Path Information call for lookup to old servers such
3973 SMBQueryInformation(const unsigned int xid
, struct cifs_tcon
*tcon
,
3974 const char *search_name
, FILE_ALL_INFO
*data
,
3975 const struct nls_table
*nls_codepage
, int remap
)
3977 QUERY_INFORMATION_REQ
*pSMB
;
3978 QUERY_INFORMATION_RSP
*pSMBr
;
3983 cifs_dbg(FYI
, "In SMBQPath path %s\n", search_name
);
3985 rc
= smb_init(SMB_COM_QUERY_INFORMATION
, 0, tcon
, (void **) &pSMB
,
3990 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3992 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3993 search_name
, PATH_MAX
, nls_codepage
,
3995 name_len
++; /* trailing null */
3998 name_len
= strnlen(search_name
, PATH_MAX
);
3999 name_len
++; /* trailing null */
4000 strncpy(pSMB
->FileName
, search_name
, name_len
);
4002 pSMB
->BufferFormat
= 0x04;
4003 name_len
++; /* account for buffer type byte */
4004 inc_rfc1001_len(pSMB
, (__u16
)name_len
);
4005 pSMB
->ByteCount
= cpu_to_le16(name_len
);
4007 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4008 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4010 cifs_dbg(FYI
, "Send error in QueryInfo = %d\n", rc
);
4013 __u32 time
= le32_to_cpu(pSMBr
->last_write_time
);
4015 /* decode response */
4016 /* BB FIXME - add time zone adjustment BB */
4017 memset(data
, 0, sizeof(FILE_ALL_INFO
));
4020 /* decode time fields */
4021 data
->ChangeTime
= cpu_to_le64(cifs_UnixTimeToNT(ts
));
4022 data
->LastWriteTime
= data
->ChangeTime
;
4023 data
->LastAccessTime
= 0;
4024 data
->AllocationSize
=
4025 cpu_to_le64(le32_to_cpu(pSMBr
->size
));
4026 data
->EndOfFile
= data
->AllocationSize
;
4028 cpu_to_le32(le16_to_cpu(pSMBr
->attr
));
4030 rc
= -EIO
; /* bad buffer passed in */
4032 cifs_buf_release(pSMB
);
4041 CIFSSMBQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4042 u16 netfid
, FILE_ALL_INFO
*pFindData
)
4044 struct smb_t2_qfi_req
*pSMB
= NULL
;
4045 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4048 __u16 params
, byte_count
;
4051 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4056 params
= 2 /* level */ + 2 /* fid */;
4057 pSMB
->t2
.TotalDataCount
= 0;
4058 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4059 /* BB find exact max data count below from sess structure BB */
4060 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4061 pSMB
->t2
.MaxSetupCount
= 0;
4062 pSMB
->t2
.Reserved
= 0;
4064 pSMB
->t2
.Timeout
= 0;
4065 pSMB
->t2
.Reserved2
= 0;
4066 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4068 pSMB
->t2
.DataCount
= 0;
4069 pSMB
->t2
.DataOffset
= 0;
4070 pSMB
->t2
.SetupCount
= 1;
4071 pSMB
->t2
.Reserved3
= 0;
4072 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4073 byte_count
= params
+ 1 /* pad */ ;
4074 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4075 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4076 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4079 inc_rfc1001_len(pSMB
, byte_count
);
4080 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4082 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4083 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4085 cifs_dbg(FYI
, "Send error in QFileInfo = %d", rc
);
4086 } else { /* decode response */
4087 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4089 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4091 else if (get_bcc(&pSMBr
->hdr
) < 40)
4092 rc
= -EIO
; /* bad smb */
4093 else if (pFindData
) {
4094 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4095 memcpy((char *) pFindData
,
4096 (char *) &pSMBr
->hdr
.Protocol
+
4097 data_offset
, sizeof(FILE_ALL_INFO
));
4101 cifs_buf_release(pSMB
);
4103 goto QFileInfoRetry
;
4109 CIFSSMBQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4110 const char *search_name
, FILE_ALL_INFO
*data
,
4111 int legacy
/* old style infolevel */,
4112 const struct nls_table
*nls_codepage
, int remap
)
4114 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4115 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4116 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4120 __u16 params
, byte_count
;
4122 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4124 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4129 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4131 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, search_name
,
4132 PATH_MAX
, nls_codepage
, remap
);
4133 name_len
++; /* trailing null */
4135 } else { /* BB improve the check for buffer overruns BB */
4136 name_len
= strnlen(search_name
, PATH_MAX
);
4137 name_len
++; /* trailing null */
4138 strncpy(pSMB
->FileName
, search_name
, name_len
);
4141 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4142 pSMB
->TotalDataCount
= 0;
4143 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4144 /* BB find exact max SMB PDU from sess structure BB */
4145 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4146 pSMB
->MaxSetupCount
= 0;
4150 pSMB
->Reserved2
= 0;
4151 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4152 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4153 pSMB
->DataCount
= 0;
4154 pSMB
->DataOffset
= 0;
4155 pSMB
->SetupCount
= 1;
4156 pSMB
->Reserved3
= 0;
4157 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4158 byte_count
= params
+ 1 /* pad */ ;
4159 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4160 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4162 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
4164 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4165 pSMB
->Reserved4
= 0;
4166 inc_rfc1001_len(pSMB
, byte_count
);
4167 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4169 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4170 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4172 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4173 } else { /* decode response */
4174 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4176 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4178 else if (!legacy
&& get_bcc(&pSMBr
->hdr
) < 40)
4179 rc
= -EIO
; /* bad smb */
4180 else if (legacy
&& get_bcc(&pSMBr
->hdr
) < 24)
4181 rc
= -EIO
; /* 24 or 26 expected but we do not read
4185 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4188 * On legacy responses we do not read the last field,
4189 * EAsize, fortunately since it varies by subdialect and
4190 * also note it differs on Set vs Get, ie two bytes or 4
4191 * bytes depending but we don't care here.
4194 size
= sizeof(FILE_INFO_STANDARD
);
4196 size
= sizeof(FILE_ALL_INFO
);
4197 memcpy((char *) data
, (char *) &pSMBr
->hdr
.Protocol
+
4202 cifs_buf_release(pSMB
);
4204 goto QPathInfoRetry
;
4210 CIFSSMBUnixQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4211 u16 netfid
, FILE_UNIX_BASIC_INFO
*pFindData
)
4213 struct smb_t2_qfi_req
*pSMB
= NULL
;
4214 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4217 __u16 params
, byte_count
;
4220 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4225 params
= 2 /* level */ + 2 /* fid */;
4226 pSMB
->t2
.TotalDataCount
= 0;
4227 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4228 /* BB find exact max data count below from sess structure BB */
4229 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4230 pSMB
->t2
.MaxSetupCount
= 0;
4231 pSMB
->t2
.Reserved
= 0;
4233 pSMB
->t2
.Timeout
= 0;
4234 pSMB
->t2
.Reserved2
= 0;
4235 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4237 pSMB
->t2
.DataCount
= 0;
4238 pSMB
->t2
.DataOffset
= 0;
4239 pSMB
->t2
.SetupCount
= 1;
4240 pSMB
->t2
.Reserved3
= 0;
4241 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4242 byte_count
= params
+ 1 /* pad */ ;
4243 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4244 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4245 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4248 inc_rfc1001_len(pSMB
, byte_count
);
4249 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4251 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4252 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4254 cifs_dbg(FYI
, "Send error in UnixQFileInfo = %d", rc
);
4255 } else { /* decode response */
4256 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4258 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4259 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4260 rc
= -EIO
; /* bad smb */
4262 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4263 memcpy((char *) pFindData
,
4264 (char *) &pSMBr
->hdr
.Protocol
+
4266 sizeof(FILE_UNIX_BASIC_INFO
));
4270 cifs_buf_release(pSMB
);
4272 goto UnixQFileInfoRetry
;
4278 CIFSSMBUnixQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4279 const unsigned char *searchName
,
4280 FILE_UNIX_BASIC_INFO
*pFindData
,
4281 const struct nls_table
*nls_codepage
, int remap
)
4283 /* SMB_QUERY_FILE_UNIX_BASIC */
4284 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4285 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4287 int bytes_returned
= 0;
4289 __u16 params
, byte_count
;
4291 cifs_dbg(FYI
, "In QPathInfo (Unix) the path %s\n", searchName
);
4293 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4298 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4300 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4301 PATH_MAX
, nls_codepage
, remap
);
4302 name_len
++; /* trailing null */
4304 } else { /* BB improve the check for buffer overruns BB */
4305 name_len
= strnlen(searchName
, PATH_MAX
);
4306 name_len
++; /* trailing null */
4307 strncpy(pSMB
->FileName
, searchName
, name_len
);
4310 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4311 pSMB
->TotalDataCount
= 0;
4312 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4313 /* BB find exact max SMB PDU from sess structure BB */
4314 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4315 pSMB
->MaxSetupCount
= 0;
4319 pSMB
->Reserved2
= 0;
4320 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4321 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4322 pSMB
->DataCount
= 0;
4323 pSMB
->DataOffset
= 0;
4324 pSMB
->SetupCount
= 1;
4325 pSMB
->Reserved3
= 0;
4326 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4327 byte_count
= params
+ 1 /* pad */ ;
4328 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4329 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4330 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4331 pSMB
->Reserved4
= 0;
4332 inc_rfc1001_len(pSMB
, byte_count
);
4333 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4335 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4336 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4338 cifs_dbg(FYI
, "Send error in UnixQPathInfo = %d", rc
);
4339 } else { /* decode response */
4340 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4342 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4343 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4344 rc
= -EIO
; /* bad smb */
4346 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4347 memcpy((char *) pFindData
,
4348 (char *) &pSMBr
->hdr
.Protocol
+
4350 sizeof(FILE_UNIX_BASIC_INFO
));
4353 cifs_buf_release(pSMB
);
4355 goto UnixQPathInfoRetry
;
4360 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4362 CIFSFindFirst(const unsigned int xid
, struct cifs_tcon
*tcon
,
4363 const char *searchName
, struct cifs_sb_info
*cifs_sb
,
4364 __u16
*pnetfid
, __u16 search_flags
,
4365 struct cifs_search_info
*psrch_inf
, bool msearch
)
4367 /* level 257 SMB_ */
4368 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
4369 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
4370 T2_FFIRST_RSP_PARMS
*parms
;
4372 int bytes_returned
= 0;
4373 int name_len
, remap
;
4374 __u16 params
, byte_count
;
4375 struct nls_table
*nls_codepage
;
4377 cifs_dbg(FYI
, "In FindFirst for %s\n", searchName
);
4380 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4385 nls_codepage
= cifs_sb
->local_nls
;
4386 remap
= cifs_remap(cifs_sb
);
4388 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4390 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4391 PATH_MAX
, nls_codepage
, remap
);
4392 /* We can not add the asterik earlier in case
4393 it got remapped to 0xF03A as if it were part of the
4394 directory name instead of a wildcard */
4397 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4398 pSMB
->FileName
[name_len
+1] = 0;
4399 pSMB
->FileName
[name_len
+2] = '*';
4400 pSMB
->FileName
[name_len
+3] = 0;
4401 name_len
+= 4; /* now the trailing null */
4402 /* null terminate just in case */
4403 pSMB
->FileName
[name_len
] = 0;
4404 pSMB
->FileName
[name_len
+1] = 0;
4407 } else { /* BB add check for overrun of SMB buf BB */
4408 name_len
= strnlen(searchName
, PATH_MAX
);
4409 /* BB fix here and in unicode clause above ie
4410 if (name_len > buffersize-header)
4411 free buffer exit; BB */
4412 strncpy(pSMB
->FileName
, searchName
, name_len
);
4414 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4415 pSMB
->FileName
[name_len
+1] = '*';
4416 pSMB
->FileName
[name_len
+2] = 0;
4421 params
= 12 + name_len
/* includes null */ ;
4422 pSMB
->TotalDataCount
= 0; /* no EAs */
4423 pSMB
->MaxParameterCount
= cpu_to_le16(10);
4424 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4425 pSMB
->MaxSetupCount
= 0;
4429 pSMB
->Reserved2
= 0;
4430 byte_count
= params
+ 1 /* pad */ ;
4431 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4432 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4433 pSMB
->ParameterOffset
= cpu_to_le16(
4434 offsetof(struct smb_com_transaction2_ffirst_req
, SearchAttributes
)
4436 pSMB
->DataCount
= 0;
4437 pSMB
->DataOffset
= 0;
4438 pSMB
->SetupCount
= 1; /* one byte, no need to make endian neutral */
4439 pSMB
->Reserved3
= 0;
4440 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
4441 pSMB
->SearchAttributes
=
4442 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
4444 pSMB
->SearchCount
= cpu_to_le16(CIFSMaxBufSize
/sizeof(FILE_UNIX_INFO
));
4445 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4446 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4448 /* BB what should we set StorageType to? Does it matter? BB */
4449 pSMB
->SearchStorageType
= 0;
4450 inc_rfc1001_len(pSMB
, byte_count
);
4451 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4453 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4454 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4455 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_ffirst
);
4457 if (rc
) {/* BB add logic to retry regular search if Unix search
4458 rejected unexpectedly by server */
4459 /* BB Add code to handle unsupported level rc */
4460 cifs_dbg(FYI
, "Error in FindFirst = %d\n", rc
);
4462 cifs_buf_release(pSMB
);
4464 /* BB eventually could optimize out free and realloc of buf */
4467 goto findFirstRetry
;
4468 } else { /* decode response */
4469 /* BB remember to free buffer if error BB */
4470 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4474 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4475 psrch_inf
->unicode
= true;
4477 psrch_inf
->unicode
= false;
4479 psrch_inf
->ntwrk_buf_start
= (char *)pSMBr
;
4480 psrch_inf
->smallBuf
= 0;
4481 psrch_inf
->srch_entries_start
=
4482 (char *) &pSMBr
->hdr
.Protocol
+
4483 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4484 parms
= (T2_FFIRST_RSP_PARMS
*)((char *) &pSMBr
->hdr
.Protocol
+
4485 le16_to_cpu(pSMBr
->t2
.ParameterOffset
));
4487 if (parms
->EndofSearch
)
4488 psrch_inf
->endOfSearch
= true;
4490 psrch_inf
->endOfSearch
= false;
4492 psrch_inf
->entries_in_buffer
=
4493 le16_to_cpu(parms
->SearchCount
);
4494 psrch_inf
->index_of_last_entry
= 2 /* skip . and .. */ +
4495 psrch_inf
->entries_in_buffer
;
4496 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4497 if (CIFSMaxBufSize
< lnoff
) {
4498 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4499 psrch_inf
->last_entry
= NULL
;
4503 psrch_inf
->last_entry
= psrch_inf
->srch_entries_start
+
4507 *pnetfid
= parms
->SearchHandle
;
4509 cifs_buf_release(pSMB
);
4516 int CIFSFindNext(const unsigned int xid
, struct cifs_tcon
*tcon
,
4517 __u16 searchHandle
, __u16 search_flags
,
4518 struct cifs_search_info
*psrch_inf
)
4520 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
4521 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
4522 T2_FNEXT_RSP_PARMS
*parms
;
4523 char *response_data
;
4526 unsigned int name_len
;
4527 __u16 params
, byte_count
;
4529 cifs_dbg(FYI
, "In FindNext\n");
4531 if (psrch_inf
->endOfSearch
)
4534 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4539 params
= 14; /* includes 2 bytes of null string, converted to LE below*/
4541 pSMB
->TotalDataCount
= 0; /* no EAs */
4542 pSMB
->MaxParameterCount
= cpu_to_le16(8);
4543 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4544 pSMB
->MaxSetupCount
= 0;
4548 pSMB
->Reserved2
= 0;
4549 pSMB
->ParameterOffset
= cpu_to_le16(
4550 offsetof(struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
4551 pSMB
->DataCount
= 0;
4552 pSMB
->DataOffset
= 0;
4553 pSMB
->SetupCount
= 1;
4554 pSMB
->Reserved3
= 0;
4555 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
4556 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
4558 cpu_to_le16(CIFSMaxBufSize
/ sizeof(FILE_UNIX_INFO
));
4559 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4560 pSMB
->ResumeKey
= psrch_inf
->resume_key
;
4561 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4563 name_len
= psrch_inf
->resume_name_len
;
4565 if (name_len
< PATH_MAX
) {
4566 memcpy(pSMB
->ResumeFileName
, psrch_inf
->presume_name
, name_len
);
4567 byte_count
+= name_len
;
4568 /* 14 byte parm len above enough for 2 byte null terminator */
4569 pSMB
->ResumeFileName
[name_len
] = 0;
4570 pSMB
->ResumeFileName
[name_len
+1] = 0;
4573 goto FNext2_err_exit
;
4575 byte_count
= params
+ 1 /* pad */ ;
4576 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4577 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4578 inc_rfc1001_len(pSMB
, byte_count
);
4579 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4581 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4582 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4583 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fnext
);
4586 psrch_inf
->endOfSearch
= true;
4587 cifs_buf_release(pSMB
);
4588 rc
= 0; /* search probably was closed at end of search*/
4590 cifs_dbg(FYI
, "FindNext returned = %d\n", rc
);
4591 } else { /* decode response */
4592 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4597 /* BB fixme add lock for file (srch_info) struct here */
4598 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4599 psrch_inf
->unicode
= true;
4601 psrch_inf
->unicode
= false;
4602 response_data
= (char *) &pSMBr
->hdr
.Protocol
+
4603 le16_to_cpu(pSMBr
->t2
.ParameterOffset
);
4604 parms
= (T2_FNEXT_RSP_PARMS
*)response_data
;
4605 response_data
= (char *)&pSMBr
->hdr
.Protocol
+
4606 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4607 if (psrch_inf
->smallBuf
)
4608 cifs_small_buf_release(
4609 psrch_inf
->ntwrk_buf_start
);
4611 cifs_buf_release(psrch_inf
->ntwrk_buf_start
);
4612 psrch_inf
->srch_entries_start
= response_data
;
4613 psrch_inf
->ntwrk_buf_start
= (char *)pSMB
;
4614 psrch_inf
->smallBuf
= 0;
4615 if (parms
->EndofSearch
)
4616 psrch_inf
->endOfSearch
= true;
4618 psrch_inf
->endOfSearch
= false;
4619 psrch_inf
->entries_in_buffer
=
4620 le16_to_cpu(parms
->SearchCount
);
4621 psrch_inf
->index_of_last_entry
+=
4622 psrch_inf
->entries_in_buffer
;
4623 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4624 if (CIFSMaxBufSize
< lnoff
) {
4625 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4626 psrch_inf
->last_entry
= NULL
;
4629 psrch_inf
->last_entry
=
4630 psrch_inf
->srch_entries_start
+ lnoff
;
4632 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4633 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4635 /* BB fixme add unlock here */
4640 /* BB On error, should we leave previous search buf (and count and
4641 last entry fields) intact or free the previous one? */
4643 /* Note: On -EAGAIN error only caller can retry on handle based calls
4644 since file handle passed in no longer valid */
4647 cifs_buf_release(pSMB
);
4652 CIFSFindClose(const unsigned int xid
, struct cifs_tcon
*tcon
,
4653 const __u16 searchHandle
)
4656 FINDCLOSE_REQ
*pSMB
= NULL
;
4658 cifs_dbg(FYI
, "In CIFSSMBFindClose\n");
4659 rc
= small_smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **)&pSMB
);
4661 /* no sense returning error if session restarted
4662 as file handle has been closed */
4668 pSMB
->FileID
= searchHandle
;
4669 pSMB
->ByteCount
= 0;
4670 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
4672 cifs_dbg(VFS
, "Send error in FindClose = %d\n", rc
);
4674 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fclose
);
4676 /* Since session is dead, search handle closed on server already */
4684 CIFSGetSrvInodeNumber(const unsigned int xid
, struct cifs_tcon
*tcon
,
4685 const char *search_name
, __u64
*inode_number
,
4686 const struct nls_table
*nls_codepage
, int remap
)
4689 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4690 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4691 int name_len
, bytes_returned
;
4692 __u16 params
, byte_count
;
4694 cifs_dbg(FYI
, "In GetSrvInodeNum for %s\n", search_name
);
4698 GetInodeNumberRetry
:
4699 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4704 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4706 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4707 search_name
, PATH_MAX
, nls_codepage
,
4709 name_len
++; /* trailing null */
4711 } else { /* BB improve the check for buffer overruns BB */
4712 name_len
= strnlen(search_name
, PATH_MAX
);
4713 name_len
++; /* trailing null */
4714 strncpy(pSMB
->FileName
, search_name
, name_len
);
4717 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
4718 pSMB
->TotalDataCount
= 0;
4719 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4720 /* BB find exact max data count below from sess structure BB */
4721 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4722 pSMB
->MaxSetupCount
= 0;
4726 pSMB
->Reserved2
= 0;
4727 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4728 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4729 pSMB
->DataCount
= 0;
4730 pSMB
->DataOffset
= 0;
4731 pSMB
->SetupCount
= 1;
4732 pSMB
->Reserved3
= 0;
4733 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4734 byte_count
= params
+ 1 /* pad */ ;
4735 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4736 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4737 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO
);
4738 pSMB
->Reserved4
= 0;
4739 inc_rfc1001_len(pSMB
, byte_count
);
4740 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4742 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4743 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4745 cifs_dbg(FYI
, "error %d in QueryInternalInfo\n", rc
);
4747 /* decode response */
4748 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4749 /* BB also check enough total bytes returned */
4750 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
4751 /* If rc should we check for EOPNOSUPP and
4752 disable the srvino flag? or in caller? */
4753 rc
= -EIO
; /* bad smb */
4755 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4756 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
4757 struct file_internal_info
*pfinfo
;
4758 /* BB Do we need a cast or hash here ? */
4760 cifs_dbg(FYI
, "Illegal size ret in QryIntrnlInf\n");
4762 goto GetInodeNumOut
;
4764 pfinfo
= (struct file_internal_info
*)
4765 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
4766 *inode_number
= le64_to_cpu(pfinfo
->UniqueId
);
4770 cifs_buf_release(pSMB
);
4772 goto GetInodeNumberRetry
;
4776 /* parses DFS refferal V3 structure
4777 * caller is responsible for freeing target_nodes
4780 * on failure - errno
4783 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
,
4784 unsigned int *num_of_nodes
,
4785 struct dfs_info3_param
**target_nodes
,
4786 const struct nls_table
*nls_codepage
, int remap
,
4787 const char *searchName
)
4792 struct dfs_referral_level_3
*ref
;
4794 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4798 *num_of_nodes
= le16_to_cpu(pSMBr
->NumberOfReferrals
);
4800 if (*num_of_nodes
< 1) {
4801 cifs_dbg(VFS
, "num_referrals: must be at least > 0, but we get num_referrals = %d\n",
4804 goto parse_DFS_referrals_exit
;
4807 ref
= (struct dfs_referral_level_3
*) &(pSMBr
->referrals
);
4808 if (ref
->VersionNumber
!= cpu_to_le16(3)) {
4809 cifs_dbg(VFS
, "Referrals of V%d version are not supported, should be V3\n",
4810 le16_to_cpu(ref
->VersionNumber
));
4812 goto parse_DFS_referrals_exit
;
4815 /* get the upper boundary of the resp buffer */
4816 data_end
= (char *)(&(pSMBr
->PathConsumed
)) +
4817 le16_to_cpu(pSMBr
->t2
.DataCount
);
4819 cifs_dbg(FYI
, "num_referrals: %d dfs flags: 0x%x ...\n",
4820 *num_of_nodes
, le32_to_cpu(pSMBr
->DFSFlags
));
4822 *target_nodes
= kcalloc(*num_of_nodes
, sizeof(struct dfs_info3_param
),
4824 if (*target_nodes
== NULL
) {
4826 goto parse_DFS_referrals_exit
;
4829 /* collect necessary data from referrals */
4830 for (i
= 0; i
< *num_of_nodes
; i
++) {
4833 struct dfs_info3_param
*node
= (*target_nodes
)+i
;
4835 node
->flags
= le32_to_cpu(pSMBr
->DFSFlags
);
4837 __le16
*tmp
= kmalloc(strlen(searchName
)*2 + 2,
4841 goto parse_DFS_referrals_exit
;
4843 cifsConvertToUTF16((__le16
*) tmp
, searchName
,
4844 PATH_MAX
, nls_codepage
, remap
);
4845 node
->path_consumed
= cifs_utf16_bytes(tmp
,
4846 le16_to_cpu(pSMBr
->PathConsumed
),
4850 node
->path_consumed
= le16_to_cpu(pSMBr
->PathConsumed
);
4852 node
->server_type
= le16_to_cpu(ref
->ServerType
);
4853 node
->ref_flag
= le16_to_cpu(ref
->ReferralEntryFlags
);
4856 temp
= (char *)ref
+ le16_to_cpu(ref
->DfsPathOffset
);
4857 max_len
= data_end
- temp
;
4858 node
->path_name
= cifs_strndup_from_utf16(temp
, max_len
,
4859 is_unicode
, nls_codepage
);
4860 if (!node
->path_name
) {
4862 goto parse_DFS_referrals_exit
;
4865 /* copy link target UNC */
4866 temp
= (char *)ref
+ le16_to_cpu(ref
->NetworkAddressOffset
);
4867 max_len
= data_end
- temp
;
4868 node
->node_name
= cifs_strndup_from_utf16(temp
, max_len
,
4869 is_unicode
, nls_codepage
);
4870 if (!node
->node_name
) {
4872 goto parse_DFS_referrals_exit
;
4878 parse_DFS_referrals_exit
:
4880 free_dfs_info_array(*target_nodes
, *num_of_nodes
);
4881 *target_nodes
= NULL
;
4888 CIFSGetDFSRefer(const unsigned int xid
, struct cifs_ses
*ses
,
4889 const char *search_name
, struct dfs_info3_param
**target_nodes
,
4890 unsigned int *num_of_nodes
,
4891 const struct nls_table
*nls_codepage
, int remap
)
4893 /* TRANS2_GET_DFS_REFERRAL */
4894 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
4895 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
4899 __u16 params
, byte_count
;
4901 *target_nodes
= NULL
;
4903 cifs_dbg(FYI
, "In GetDFSRefer the path %s\n", search_name
);
4907 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, NULL
, (void **) &pSMB
,
4912 /* server pointer checked in called function,
4913 but should never be null here anyway */
4914 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
4915 pSMB
->hdr
.Tid
= ses
->ipc_tid
;
4916 pSMB
->hdr
.Uid
= ses
->Suid
;
4917 if (ses
->capabilities
& CAP_STATUS32
)
4918 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
4919 if (ses
->capabilities
& CAP_DFS
)
4920 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
4922 if (ses
->capabilities
& CAP_UNICODE
) {
4923 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
4925 cifsConvertToUTF16((__le16
*) pSMB
->RequestFileName
,
4926 search_name
, PATH_MAX
, nls_codepage
,
4928 name_len
++; /* trailing null */
4930 } else { /* BB improve the check for buffer overruns BB */
4931 name_len
= strnlen(search_name
, PATH_MAX
);
4932 name_len
++; /* trailing null */
4933 strncpy(pSMB
->RequestFileName
, search_name
, name_len
);
4936 if (ses
->server
->sign
)
4937 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
4939 pSMB
->hdr
.Uid
= ses
->Suid
;
4941 params
= 2 /* level */ + name_len
/*includes null */ ;
4942 pSMB
->TotalDataCount
= 0;
4943 pSMB
->DataCount
= 0;
4944 pSMB
->DataOffset
= 0;
4945 pSMB
->MaxParameterCount
= 0;
4946 /* BB find exact max SMB PDU from sess structure BB */
4947 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4948 pSMB
->MaxSetupCount
= 0;
4952 pSMB
->Reserved2
= 0;
4953 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4954 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
4955 pSMB
->SetupCount
= 1;
4956 pSMB
->Reserved3
= 0;
4957 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
4958 byte_count
= params
+ 3 /* pad */ ;
4959 pSMB
->ParameterCount
= cpu_to_le16(params
);
4960 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4961 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
4962 inc_rfc1001_len(pSMB
, byte_count
);
4963 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4965 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
4966 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4968 cifs_dbg(FYI
, "Send error in GetDFSRefer = %d\n", rc
);
4971 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4973 /* BB Also check if enough total bytes returned? */
4974 if (rc
|| get_bcc(&pSMBr
->hdr
) < 17) {
4975 rc
= -EIO
; /* bad smb */
4979 cifs_dbg(FYI
, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4980 get_bcc(&pSMBr
->hdr
), le16_to_cpu(pSMBr
->t2
.DataOffset
));
4982 /* parse returned result into more usable form */
4983 rc
= parse_DFS_referrals(pSMBr
, num_of_nodes
,
4984 target_nodes
, nls_codepage
, remap
,
4988 cifs_buf_release(pSMB
);
4996 /* Query File System Info such as free space to old servers such as Win 9x */
4998 SMBOldQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4999 struct kstatfs
*FSData
)
5001 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
5002 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5003 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5004 FILE_SYSTEM_ALLOC_INFO
*response_data
;
5006 int bytes_returned
= 0;
5007 __u16 params
, byte_count
;
5009 cifs_dbg(FYI
, "OldQFSInfo\n");
5011 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5016 params
= 2; /* level */
5017 pSMB
->TotalDataCount
= 0;
5018 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5019 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5020 pSMB
->MaxSetupCount
= 0;
5024 pSMB
->Reserved2
= 0;
5025 byte_count
= params
+ 1 /* pad */ ;
5026 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5027 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5028 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5029 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5030 pSMB
->DataCount
= 0;
5031 pSMB
->DataOffset
= 0;
5032 pSMB
->SetupCount
= 1;
5033 pSMB
->Reserved3
= 0;
5034 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5035 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_ALLOCATION
);
5036 inc_rfc1001_len(pSMB
, byte_count
);
5037 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5039 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5040 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5042 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5043 } else { /* decode response */
5044 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5046 if (rc
|| get_bcc(&pSMBr
->hdr
) < 18)
5047 rc
= -EIO
; /* bad smb */
5049 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5050 cifs_dbg(FYI
, "qfsinf resp BCC: %d Offset %d\n",
5051 get_bcc(&pSMBr
->hdr
), data_offset
);
5053 response_data
= (FILE_SYSTEM_ALLOC_INFO
*)
5054 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
5056 le16_to_cpu(response_data
->BytesPerSector
) *
5057 le32_to_cpu(response_data
->
5058 SectorsPerAllocationUnit
);
5060 le32_to_cpu(response_data
->TotalAllocationUnits
);
5061 FSData
->f_bfree
= FSData
->f_bavail
=
5062 le32_to_cpu(response_data
->FreeAllocationUnits
);
5063 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5064 (unsigned long long)FSData
->f_blocks
,
5065 (unsigned long long)FSData
->f_bfree
,
5069 cifs_buf_release(pSMB
);
5072 goto oldQFSInfoRetry
;
5078 CIFSSMBQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5079 struct kstatfs
*FSData
)
5081 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5082 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5083 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5084 FILE_SYSTEM_INFO
*response_data
;
5086 int bytes_returned
= 0;
5087 __u16 params
, byte_count
;
5089 cifs_dbg(FYI
, "In QFSInfo\n");
5091 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5096 params
= 2; /* level */
5097 pSMB
->TotalDataCount
= 0;
5098 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5099 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5100 pSMB
->MaxSetupCount
= 0;
5104 pSMB
->Reserved2
= 0;
5105 byte_count
= params
+ 1 /* pad */ ;
5106 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5107 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5108 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5109 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5110 pSMB
->DataCount
= 0;
5111 pSMB
->DataOffset
= 0;
5112 pSMB
->SetupCount
= 1;
5113 pSMB
->Reserved3
= 0;
5114 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5115 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
5116 inc_rfc1001_len(pSMB
, byte_count
);
5117 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5119 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5120 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5122 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5123 } else { /* decode response */
5124 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5126 if (rc
|| get_bcc(&pSMBr
->hdr
) < 24)
5127 rc
= -EIO
; /* bad smb */
5129 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5133 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5136 le32_to_cpu(response_data
->BytesPerSector
) *
5137 le32_to_cpu(response_data
->
5138 SectorsPerAllocationUnit
);
5140 le64_to_cpu(response_data
->TotalAllocationUnits
);
5141 FSData
->f_bfree
= FSData
->f_bavail
=
5142 le64_to_cpu(response_data
->FreeAllocationUnits
);
5143 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5144 (unsigned long long)FSData
->f_blocks
,
5145 (unsigned long long)FSData
->f_bfree
,
5149 cifs_buf_release(pSMB
);
5158 CIFSSMBQFSAttributeInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5160 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5161 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5162 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5163 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
5165 int bytes_returned
= 0;
5166 __u16 params
, byte_count
;
5168 cifs_dbg(FYI
, "In QFSAttributeInfo\n");
5170 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5175 params
= 2; /* level */
5176 pSMB
->TotalDataCount
= 0;
5177 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5178 /* BB find exact max SMB PDU from sess structure BB */
5179 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5180 pSMB
->MaxSetupCount
= 0;
5184 pSMB
->Reserved2
= 0;
5185 byte_count
= params
+ 1 /* pad */ ;
5186 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5187 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5188 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5189 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5190 pSMB
->DataCount
= 0;
5191 pSMB
->DataOffset
= 0;
5192 pSMB
->SetupCount
= 1;
5193 pSMB
->Reserved3
= 0;
5194 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5195 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
5196 inc_rfc1001_len(pSMB
, byte_count
);
5197 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5199 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5200 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5202 cifs_dbg(VFS
, "Send error in QFSAttributeInfo = %d\n", rc
);
5203 } else { /* decode response */
5204 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5206 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5207 /* BB also check if enough bytes returned */
5208 rc
= -EIO
; /* bad smb */
5210 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5212 (FILE_SYSTEM_ATTRIBUTE_INFO
5213 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5215 memcpy(&tcon
->fsAttrInfo
, response_data
,
5216 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO
));
5219 cifs_buf_release(pSMB
);
5222 goto QFSAttributeRetry
;
5228 CIFSSMBQFSDeviceInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5230 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5231 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5232 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5233 FILE_SYSTEM_DEVICE_INFO
*response_data
;
5235 int bytes_returned
= 0;
5236 __u16 params
, byte_count
;
5238 cifs_dbg(FYI
, "In QFSDeviceInfo\n");
5240 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5245 params
= 2; /* level */
5246 pSMB
->TotalDataCount
= 0;
5247 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5248 /* BB find exact max SMB PDU from sess structure BB */
5249 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5250 pSMB
->MaxSetupCount
= 0;
5254 pSMB
->Reserved2
= 0;
5255 byte_count
= params
+ 1 /* pad */ ;
5256 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5257 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5258 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5259 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5261 pSMB
->DataCount
= 0;
5262 pSMB
->DataOffset
= 0;
5263 pSMB
->SetupCount
= 1;
5264 pSMB
->Reserved3
= 0;
5265 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5266 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
5267 inc_rfc1001_len(pSMB
, byte_count
);
5268 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5270 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5271 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5273 cifs_dbg(FYI
, "Send error in QFSDeviceInfo = %d\n", rc
);
5274 } else { /* decode response */
5275 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5277 if (rc
|| get_bcc(&pSMBr
->hdr
) <
5278 sizeof(FILE_SYSTEM_DEVICE_INFO
))
5279 rc
= -EIO
; /* bad smb */
5281 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5283 (FILE_SYSTEM_DEVICE_INFO
*)
5284 (((char *) &pSMBr
->hdr
.Protocol
) +
5286 memcpy(&tcon
->fsDevInfo
, response_data
,
5287 sizeof(FILE_SYSTEM_DEVICE_INFO
));
5290 cifs_buf_release(pSMB
);
5293 goto QFSDeviceRetry
;
5299 CIFSSMBQFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5301 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5302 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5303 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5304 FILE_SYSTEM_UNIX_INFO
*response_data
;
5306 int bytes_returned
= 0;
5307 __u16 params
, byte_count
;
5309 cifs_dbg(FYI
, "In QFSUnixInfo\n");
5311 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5312 (void **) &pSMB
, (void **) &pSMBr
);
5316 params
= 2; /* level */
5317 pSMB
->TotalDataCount
= 0;
5318 pSMB
->DataCount
= 0;
5319 pSMB
->DataOffset
= 0;
5320 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5321 /* BB find exact max SMB PDU from sess structure BB */
5322 pSMB
->MaxDataCount
= cpu_to_le16(100);
5323 pSMB
->MaxSetupCount
= 0;
5327 pSMB
->Reserved2
= 0;
5328 byte_count
= params
+ 1 /* pad */ ;
5329 pSMB
->ParameterCount
= cpu_to_le16(params
);
5330 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5331 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5332 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5333 pSMB
->SetupCount
= 1;
5334 pSMB
->Reserved3
= 0;
5335 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5336 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
5337 inc_rfc1001_len(pSMB
, byte_count
);
5338 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5340 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5341 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5343 cifs_dbg(VFS
, "Send error in QFSUnixInfo = %d\n", rc
);
5344 } else { /* decode response */
5345 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5347 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5348 rc
= -EIO
; /* bad smb */
5350 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5352 (FILE_SYSTEM_UNIX_INFO
5353 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5355 memcpy(&tcon
->fsUnixInfo
, response_data
,
5356 sizeof(FILE_SYSTEM_UNIX_INFO
));
5359 cifs_buf_release(pSMB
);
5369 CIFSSMBSetFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
, __u64 cap
)
5371 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5372 TRANSACTION2_SETFSI_REQ
*pSMB
= NULL
;
5373 TRANSACTION2_SETFSI_RSP
*pSMBr
= NULL
;
5375 int bytes_returned
= 0;
5376 __u16 params
, param_offset
, offset
, byte_count
;
5378 cifs_dbg(FYI
, "In SETFSUnixInfo\n");
5380 /* BB switch to small buf init to save memory */
5381 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5382 (void **) &pSMB
, (void **) &pSMBr
);
5386 params
= 4; /* 2 bytes zero followed by info level. */
5387 pSMB
->MaxSetupCount
= 0;
5391 pSMB
->Reserved2
= 0;
5392 param_offset
= offsetof(struct smb_com_transaction2_setfsi_req
, FileNum
)
5394 offset
= param_offset
+ params
;
5396 pSMB
->MaxParameterCount
= cpu_to_le16(4);
5397 /* BB find exact max SMB PDU from sess structure BB */
5398 pSMB
->MaxDataCount
= cpu_to_le16(100);
5399 pSMB
->SetupCount
= 1;
5400 pSMB
->Reserved3
= 0;
5401 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FS_INFORMATION
);
5402 byte_count
= 1 /* pad */ + params
+ 12;
5404 pSMB
->DataCount
= cpu_to_le16(12);
5405 pSMB
->ParameterCount
= cpu_to_le16(params
);
5406 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5407 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5408 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5409 pSMB
->DataOffset
= cpu_to_le16(offset
);
5413 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_CIFS_UNIX_INFO
);
5416 pSMB
->ClientUnixMajor
= cpu_to_le16(CIFS_UNIX_MAJOR_VERSION
);
5417 pSMB
->ClientUnixMinor
= cpu_to_le16(CIFS_UNIX_MINOR_VERSION
);
5418 pSMB
->ClientUnixCap
= cpu_to_le64(cap
);
5420 inc_rfc1001_len(pSMB
, byte_count
);
5421 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5423 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5424 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5426 cifs_dbg(VFS
, "Send error in SETFSUnixInfo = %d\n", rc
);
5427 } else { /* decode response */
5428 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5430 rc
= -EIO
; /* bad smb */
5432 cifs_buf_release(pSMB
);
5435 goto SETFSUnixRetry
;
5443 CIFSSMBQFSPosixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5444 struct kstatfs
*FSData
)
5446 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5447 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5448 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5449 FILE_SYSTEM_POSIX_INFO
*response_data
;
5451 int bytes_returned
= 0;
5452 __u16 params
, byte_count
;
5454 cifs_dbg(FYI
, "In QFSPosixInfo\n");
5456 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5461 params
= 2; /* level */
5462 pSMB
->TotalDataCount
= 0;
5463 pSMB
->DataCount
= 0;
5464 pSMB
->DataOffset
= 0;
5465 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5466 /* BB find exact max SMB PDU from sess structure BB */
5467 pSMB
->MaxDataCount
= cpu_to_le16(100);
5468 pSMB
->MaxSetupCount
= 0;
5472 pSMB
->Reserved2
= 0;
5473 byte_count
= params
+ 1 /* pad */ ;
5474 pSMB
->ParameterCount
= cpu_to_le16(params
);
5475 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5476 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5477 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5478 pSMB
->SetupCount
= 1;
5479 pSMB
->Reserved3
= 0;
5480 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5481 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_FS_INFO
);
5482 inc_rfc1001_len(pSMB
, byte_count
);
5483 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5485 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5486 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5488 cifs_dbg(FYI
, "Send error in QFSUnixInfo = %d\n", rc
);
5489 } else { /* decode response */
5490 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5492 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5493 rc
= -EIO
; /* bad smb */
5495 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5497 (FILE_SYSTEM_POSIX_INFO
5498 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5501 le32_to_cpu(response_data
->BlockSize
);
5503 le64_to_cpu(response_data
->TotalBlocks
);
5505 le64_to_cpu(response_data
->BlocksAvail
);
5506 if (response_data
->UserBlocksAvail
== cpu_to_le64(-1)) {
5507 FSData
->f_bavail
= FSData
->f_bfree
;
5510 le64_to_cpu(response_data
->UserBlocksAvail
);
5512 if (response_data
->TotalFileNodes
!= cpu_to_le64(-1))
5514 le64_to_cpu(response_data
->TotalFileNodes
);
5515 if (response_data
->FreeFileNodes
!= cpu_to_le64(-1))
5517 le64_to_cpu(response_data
->FreeFileNodes
);
5520 cifs_buf_release(pSMB
);
5530 * We can not use write of zero bytes trick to set file size due to need for
5531 * large file support. Also note that this SetPathInfo is preferred to
5532 * SetFileInfo based method in next routine which is only needed to work around
5533 * a sharing violation bugin Samba which this routine can run into.
5536 CIFSSMBSetEOF(const unsigned int xid
, struct cifs_tcon
*tcon
,
5537 const char *file_name
, __u64 size
, struct cifs_sb_info
*cifs_sb
,
5538 bool set_allocation
)
5540 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5541 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5542 struct file_end_of_file_info
*parm_data
;
5545 int bytes_returned
= 0;
5546 int remap
= cifs_remap(cifs_sb
);
5548 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
5550 cifs_dbg(FYI
, "In SetEOF\n");
5552 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5557 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5559 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5560 PATH_MAX
, cifs_sb
->local_nls
, remap
);
5561 name_len
++; /* trailing null */
5563 } else { /* BB improve the check for buffer overruns BB */
5564 name_len
= strnlen(file_name
, PATH_MAX
);
5565 name_len
++; /* trailing null */
5566 strncpy(pSMB
->FileName
, file_name
, name_len
);
5568 params
= 6 + name_len
;
5569 data_count
= sizeof(struct file_end_of_file_info
);
5570 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5571 pSMB
->MaxDataCount
= cpu_to_le16(4100);
5572 pSMB
->MaxSetupCount
= 0;
5576 pSMB
->Reserved2
= 0;
5577 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5578 InformationLevel
) - 4;
5579 offset
= param_offset
+ params
;
5580 if (set_allocation
) {
5581 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5582 pSMB
->InformationLevel
=
5583 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5585 pSMB
->InformationLevel
=
5586 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5587 } else /* Set File Size */ {
5588 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5589 pSMB
->InformationLevel
=
5590 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5592 pSMB
->InformationLevel
=
5593 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5597 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
5599 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5600 pSMB
->DataOffset
= cpu_to_le16(offset
);
5601 pSMB
->SetupCount
= 1;
5602 pSMB
->Reserved3
= 0;
5603 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5604 byte_count
= 3 /* pad */ + params
+ data_count
;
5605 pSMB
->DataCount
= cpu_to_le16(data_count
);
5606 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5607 pSMB
->ParameterCount
= cpu_to_le16(params
);
5608 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5609 pSMB
->Reserved4
= 0;
5610 inc_rfc1001_len(pSMB
, byte_count
);
5611 parm_data
->FileSize
= cpu_to_le64(size
);
5612 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5613 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5614 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5616 cifs_dbg(FYI
, "SetPathInfo (file size) returned %d\n", rc
);
5618 cifs_buf_release(pSMB
);
5627 CIFSSMBSetFileSize(const unsigned int xid
, struct cifs_tcon
*tcon
,
5628 struct cifsFileInfo
*cfile
, __u64 size
, bool set_allocation
)
5630 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5631 struct file_end_of_file_info
*parm_data
;
5633 __u16 params
, param_offset
, offset
, byte_count
, count
;
5635 cifs_dbg(FYI
, "SetFileSize (via SetFileInfo) %lld\n",
5637 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5642 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)cfile
->pid
);
5643 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(cfile
->pid
>> 16));
5646 pSMB
->MaxSetupCount
= 0;
5650 pSMB
->Reserved2
= 0;
5651 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5652 offset
= param_offset
+ params
;
5654 count
= sizeof(struct file_end_of_file_info
);
5655 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5656 /* BB find exact max SMB PDU from sess structure BB */
5657 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5658 pSMB
->SetupCount
= 1;
5659 pSMB
->Reserved3
= 0;
5660 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5661 byte_count
= 3 /* pad */ + params
+ count
;
5662 pSMB
->DataCount
= cpu_to_le16(count
);
5663 pSMB
->ParameterCount
= cpu_to_le16(params
);
5664 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5665 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5666 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5668 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
)
5670 pSMB
->DataOffset
= cpu_to_le16(offset
);
5671 parm_data
->FileSize
= cpu_to_le64(size
);
5672 pSMB
->Fid
= cfile
->fid
.netfid
;
5673 if (set_allocation
) {
5674 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5675 pSMB
->InformationLevel
=
5676 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5678 pSMB
->InformationLevel
=
5679 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5680 } else /* Set File Size */ {
5681 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5682 pSMB
->InformationLevel
=
5683 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5685 pSMB
->InformationLevel
=
5686 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5688 pSMB
->Reserved4
= 0;
5689 inc_rfc1001_len(pSMB
, byte_count
);
5690 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5691 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5693 cifs_dbg(FYI
, "Send error in SetFileInfo (SetFileSize) = %d\n",
5697 /* Note: On -EAGAIN error only caller can retry on handle based calls
5698 since file handle passed in no longer valid */
5703 /* Some legacy servers such as NT4 require that the file times be set on
5704 an open handle, rather than by pathname - this is awkward due to
5705 potential access conflicts on the open, but it is unavoidable for these
5706 old servers since the only other choice is to go from 100 nanosecond DCE
5707 time and resort to the original setpathinfo level which takes the ancient
5708 DOS time format with 2 second granularity */
5710 CIFSSMBSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5711 const FILE_BASIC_INFO
*data
, __u16 fid
, __u32 pid_of_opener
)
5713 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5716 __u16 params
, param_offset
, offset
, byte_count
, count
;
5718 cifs_dbg(FYI
, "Set Times (via SetFileInfo)\n");
5719 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5724 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5725 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5728 pSMB
->MaxSetupCount
= 0;
5732 pSMB
->Reserved2
= 0;
5733 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5734 offset
= param_offset
+ params
;
5736 data_offset
= (char *)pSMB
+
5737 offsetof(struct smb_hdr
, Protocol
) + offset
;
5739 count
= sizeof(FILE_BASIC_INFO
);
5740 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5741 /* BB find max SMB PDU from sess */
5742 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5743 pSMB
->SetupCount
= 1;
5744 pSMB
->Reserved3
= 0;
5745 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5746 byte_count
= 3 /* pad */ + params
+ count
;
5747 pSMB
->DataCount
= cpu_to_le16(count
);
5748 pSMB
->ParameterCount
= cpu_to_le16(params
);
5749 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5750 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5751 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5752 pSMB
->DataOffset
= cpu_to_le16(offset
);
5754 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5755 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5757 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5758 pSMB
->Reserved4
= 0;
5759 inc_rfc1001_len(pSMB
, byte_count
);
5760 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5761 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5762 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5764 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5767 /* Note: On -EAGAIN error only caller can retry on handle based calls
5768 since file handle passed in no longer valid */
5774 CIFSSMBSetFileDisposition(const unsigned int xid
, struct cifs_tcon
*tcon
,
5775 bool delete_file
, __u16 fid
, __u32 pid_of_opener
)
5777 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5780 __u16 params
, param_offset
, offset
, byte_count
, count
;
5782 cifs_dbg(FYI
, "Set File Disposition (via SetFileInfo)\n");
5783 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5788 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5789 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5792 pSMB
->MaxSetupCount
= 0;
5796 pSMB
->Reserved2
= 0;
5797 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5798 offset
= param_offset
+ params
;
5800 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5803 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5804 /* BB find max SMB PDU from sess */
5805 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5806 pSMB
->SetupCount
= 1;
5807 pSMB
->Reserved3
= 0;
5808 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5809 byte_count
= 3 /* pad */ + params
+ count
;
5810 pSMB
->DataCount
= cpu_to_le16(count
);
5811 pSMB
->ParameterCount
= cpu_to_le16(params
);
5812 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5813 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5814 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5815 pSMB
->DataOffset
= cpu_to_le16(offset
);
5817 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO
);
5818 pSMB
->Reserved4
= 0;
5819 inc_rfc1001_len(pSMB
, byte_count
);
5820 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5821 *data_offset
= delete_file
? 1 : 0;
5822 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5824 cifs_dbg(FYI
, "Send error in SetFileDisposition = %d\n", rc
);
5830 CIFSSMBSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5831 const char *fileName
, const FILE_BASIC_INFO
*data
,
5832 const struct nls_table
*nls_codepage
, int remap
)
5834 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5835 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5838 int bytes_returned
= 0;
5840 __u16 params
, param_offset
, offset
, byte_count
, count
;
5842 cifs_dbg(FYI
, "In SetTimes\n");
5845 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5850 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5852 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5853 PATH_MAX
, nls_codepage
, remap
);
5854 name_len
++; /* trailing null */
5856 } else { /* BB improve the check for buffer overruns BB */
5857 name_len
= strnlen(fileName
, PATH_MAX
);
5858 name_len
++; /* trailing null */
5859 strncpy(pSMB
->FileName
, fileName
, name_len
);
5862 params
= 6 + name_len
;
5863 count
= sizeof(FILE_BASIC_INFO
);
5864 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5865 /* BB find max SMB PDU from sess structure BB */
5866 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5867 pSMB
->MaxSetupCount
= 0;
5871 pSMB
->Reserved2
= 0;
5872 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5873 InformationLevel
) - 4;
5874 offset
= param_offset
+ params
;
5875 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5876 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5877 pSMB
->DataOffset
= cpu_to_le16(offset
);
5878 pSMB
->SetupCount
= 1;
5879 pSMB
->Reserved3
= 0;
5880 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5881 byte_count
= 3 /* pad */ + params
+ count
;
5883 pSMB
->DataCount
= cpu_to_le16(count
);
5884 pSMB
->ParameterCount
= cpu_to_le16(params
);
5885 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5886 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5887 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5888 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5890 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5891 pSMB
->Reserved4
= 0;
5892 inc_rfc1001_len(pSMB
, byte_count
);
5893 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5894 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5895 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5896 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5898 cifs_dbg(FYI
, "SetPathInfo (times) returned %d\n", rc
);
5900 cifs_buf_release(pSMB
);
5908 /* Can not be used to set time stamps yet (due to old DOS time format) */
5909 /* Can be used to set attributes */
5910 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5911 handling it anyway and NT4 was what we thought it would be needed for
5912 Do not delete it until we prove whether needed for Win9x though */
5914 CIFSSMBSetAttrLegacy(unsigned int xid
, struct cifs_tcon
*tcon
, char *fileName
,
5915 __u16 dos_attrs
, const struct nls_table
*nls_codepage
)
5917 SETATTR_REQ
*pSMB
= NULL
;
5918 SETATTR_RSP
*pSMBr
= NULL
;
5923 cifs_dbg(FYI
, "In SetAttrLegacy\n");
5926 rc
= smb_init(SMB_COM_SETATTR
, 8, tcon
, (void **) &pSMB
,
5931 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5933 ConvertToUTF16((__le16
*) pSMB
->fileName
, fileName
,
5934 PATH_MAX
, nls_codepage
);
5935 name_len
++; /* trailing null */
5937 } else { /* BB improve the check for buffer overruns BB */
5938 name_len
= strnlen(fileName
, PATH_MAX
);
5939 name_len
++; /* trailing null */
5940 strncpy(pSMB
->fileName
, fileName
, name_len
);
5942 pSMB
->attr
= cpu_to_le16(dos_attrs
);
5943 pSMB
->BufferFormat
= 0x04;
5944 inc_rfc1001_len(pSMB
, name_len
+ 1);
5945 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
5946 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5947 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5949 cifs_dbg(FYI
, "Error in LegacySetAttr = %d\n", rc
);
5951 cifs_buf_release(pSMB
);
5954 goto SetAttrLgcyRetry
;
5958 #endif /* temporarily unneeded SetAttr legacy function */
5961 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO
*data_offset
,
5962 const struct cifs_unix_set_info_args
*args
)
5964 u64 uid
= NO_CHANGE_64
, gid
= NO_CHANGE_64
;
5965 u64 mode
= args
->mode
;
5967 if (uid_valid(args
->uid
))
5968 uid
= from_kuid(&init_user_ns
, args
->uid
);
5969 if (gid_valid(args
->gid
))
5970 gid
= from_kgid(&init_user_ns
, args
->gid
);
5973 * Samba server ignores set of file size to zero due to bugs in some
5974 * older clients, but we should be precise - we use SetFileSize to
5975 * set file size and do not want to truncate file size to zero
5976 * accidentally as happened on one Samba server beta by putting
5977 * zero instead of -1 here
5979 data_offset
->EndOfFile
= cpu_to_le64(NO_CHANGE_64
);
5980 data_offset
->NumOfBytes
= cpu_to_le64(NO_CHANGE_64
);
5981 data_offset
->LastStatusChange
= cpu_to_le64(args
->ctime
);
5982 data_offset
->LastAccessTime
= cpu_to_le64(args
->atime
);
5983 data_offset
->LastModificationTime
= cpu_to_le64(args
->mtime
);
5984 data_offset
->Uid
= cpu_to_le64(uid
);
5985 data_offset
->Gid
= cpu_to_le64(gid
);
5986 /* better to leave device as zero when it is */
5987 data_offset
->DevMajor
= cpu_to_le64(MAJOR(args
->device
));
5988 data_offset
->DevMinor
= cpu_to_le64(MINOR(args
->device
));
5989 data_offset
->Permissions
= cpu_to_le64(mode
);
5992 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
5993 else if (S_ISDIR(mode
))
5994 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
5995 else if (S_ISLNK(mode
))
5996 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
5997 else if (S_ISCHR(mode
))
5998 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
5999 else if (S_ISBLK(mode
))
6000 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
6001 else if (S_ISFIFO(mode
))
6002 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
6003 else if (S_ISSOCK(mode
))
6004 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
6008 CIFSSMBUnixSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6009 const struct cifs_unix_set_info_args
*args
,
6010 u16 fid
, u32 pid_of_opener
)
6012 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
6015 u16 params
, param_offset
, offset
, byte_count
, count
;
6017 cifs_dbg(FYI
, "Set Unix Info (via SetFileInfo)\n");
6018 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
6023 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
6024 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
6027 pSMB
->MaxSetupCount
= 0;
6031 pSMB
->Reserved2
= 0;
6032 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
6033 offset
= param_offset
+ params
;
6035 data_offset
= (char *)pSMB
+
6036 offsetof(struct smb_hdr
, Protocol
) + offset
;
6038 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6040 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6041 /* BB find max SMB PDU from sess */
6042 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6043 pSMB
->SetupCount
= 1;
6044 pSMB
->Reserved3
= 0;
6045 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
6046 byte_count
= 3 /* pad */ + params
+ count
;
6047 pSMB
->DataCount
= cpu_to_le16(count
);
6048 pSMB
->ParameterCount
= cpu_to_le16(params
);
6049 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6050 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6051 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6052 pSMB
->DataOffset
= cpu_to_le16(offset
);
6054 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6055 pSMB
->Reserved4
= 0;
6056 inc_rfc1001_len(pSMB
, byte_count
);
6057 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6059 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO
*)data_offset
, args
);
6061 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
6063 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
6066 /* Note: On -EAGAIN error only caller can retry on handle based calls
6067 since file handle passed in no longer valid */
6073 CIFSSMBUnixSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6074 const char *file_name
,
6075 const struct cifs_unix_set_info_args
*args
,
6076 const struct nls_table
*nls_codepage
, int remap
)
6078 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
6079 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
6082 int bytes_returned
= 0;
6083 FILE_UNIX_BASIC_INFO
*data_offset
;
6084 __u16 params
, param_offset
, offset
, count
, byte_count
;
6086 cifs_dbg(FYI
, "In SetUID/GID/Mode\n");
6088 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6093 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6095 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
6096 PATH_MAX
, nls_codepage
, remap
);
6097 name_len
++; /* trailing null */
6099 } else { /* BB improve the check for buffer overruns BB */
6100 name_len
= strnlen(file_name
, PATH_MAX
);
6101 name_len
++; /* trailing null */
6102 strncpy(pSMB
->FileName
, file_name
, name_len
);
6105 params
= 6 + name_len
;
6106 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6107 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6108 /* BB find max SMB PDU from sess structure BB */
6109 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6110 pSMB
->MaxSetupCount
= 0;
6114 pSMB
->Reserved2
= 0;
6115 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6116 InformationLevel
) - 4;
6117 offset
= param_offset
+ params
;
6119 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
6121 memset(data_offset
, 0, count
);
6122 pSMB
->DataOffset
= cpu_to_le16(offset
);
6123 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6124 pSMB
->SetupCount
= 1;
6125 pSMB
->Reserved3
= 0;
6126 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6127 byte_count
= 3 /* pad */ + params
+ count
;
6128 pSMB
->ParameterCount
= cpu_to_le16(params
);
6129 pSMB
->DataCount
= cpu_to_le16(count
);
6130 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6131 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6132 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6133 pSMB
->Reserved4
= 0;
6134 inc_rfc1001_len(pSMB
, byte_count
);
6136 cifs_fill_unix_set_info(data_offset
, args
);
6138 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6139 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6140 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6142 cifs_dbg(FYI
, "SetPathInfo (perms) returned %d\n", rc
);
6144 cifs_buf_release(pSMB
);
6150 #ifdef CONFIG_CIFS_XATTR
6152 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6153 * function used by listxattr and getxattr type calls. When ea_name is set,
6154 * it looks for that attribute name and stuffs that value into the EAData
6155 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6156 * buffer. In both cases, the return value is either the length of the
6157 * resulting data or a negative error code. If EAData is a NULL pointer then
6158 * the data isn't copied to it, but the length is returned.
6161 CIFSSMBQAllEAs(const unsigned int xid
, struct cifs_tcon
*tcon
,
6162 const unsigned char *searchName
, const unsigned char *ea_name
,
6163 char *EAData
, size_t buf_size
,
6164 const struct nls_table
*nls_codepage
, int remap
)
6166 /* BB assumes one setup word */
6167 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
6168 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
6172 struct fealist
*ea_response_data
;
6173 struct fea
*temp_fea
;
6176 __u16 params
, byte_count
, data_offset
;
6177 unsigned int ea_name_len
= ea_name
? strlen(ea_name
) : 0;
6179 cifs_dbg(FYI
, "In Query All EAs path %s\n", searchName
);
6181 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6186 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6188 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
6189 PATH_MAX
, nls_codepage
, remap
);
6190 list_len
++; /* trailing null */
6192 } else { /* BB improve the check for buffer overruns BB */
6193 list_len
= strnlen(searchName
, PATH_MAX
);
6194 list_len
++; /* trailing null */
6195 strncpy(pSMB
->FileName
, searchName
, list_len
);
6198 params
= 2 /* level */ + 4 /* reserved */ + list_len
/* includes NUL */;
6199 pSMB
->TotalDataCount
= 0;
6200 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6201 /* BB find exact max SMB PDU from sess structure BB */
6202 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
6203 pSMB
->MaxSetupCount
= 0;
6207 pSMB
->Reserved2
= 0;
6208 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
6209 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
6210 pSMB
->DataCount
= 0;
6211 pSMB
->DataOffset
= 0;
6212 pSMB
->SetupCount
= 1;
6213 pSMB
->Reserved3
= 0;
6214 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
6215 byte_count
= params
+ 1 /* pad */ ;
6216 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
6217 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6218 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
6219 pSMB
->Reserved4
= 0;
6220 inc_rfc1001_len(pSMB
, byte_count
);
6221 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6223 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6224 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6226 cifs_dbg(FYI
, "Send error in QueryAllEAs = %d\n", rc
);
6231 /* BB also check enough total bytes returned */
6232 /* BB we need to improve the validity checking
6233 of these trans2 responses */
6235 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
6236 if (rc
|| get_bcc(&pSMBr
->hdr
) < 4) {
6237 rc
= -EIO
; /* bad smb */
6241 /* check that length of list is not more than bcc */
6242 /* check that each entry does not go beyond length
6244 /* check that each element of each entry does not
6245 go beyond end of list */
6246 /* validate_trans2_offsets() */
6247 /* BB check if start of smb + data_offset > &bcc+ bcc */
6249 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
6250 ea_response_data
= (struct fealist
*)
6251 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
6253 list_len
= le32_to_cpu(ea_response_data
->list_len
);
6254 cifs_dbg(FYI
, "ea length %d\n", list_len
);
6255 if (list_len
<= 8) {
6256 cifs_dbg(FYI
, "empty EA list returned from server\n");
6257 /* didn't find the named attribute */
6263 /* make sure list_len doesn't go past end of SMB */
6264 end_of_smb
= (char *)pByteArea(&pSMBr
->hdr
) + get_bcc(&pSMBr
->hdr
);
6265 if ((char *)ea_response_data
+ list_len
> end_of_smb
) {
6266 cifs_dbg(FYI
, "EA list appears to go beyond SMB\n");
6271 /* account for ea list len */
6273 temp_fea
= ea_response_data
->list
;
6274 temp_ptr
= (char *)temp_fea
;
6275 while (list_len
> 0) {
6276 unsigned int name_len
;
6281 /* make sure we can read name_len and value_len */
6283 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6288 name_len
= temp_fea
->name_len
;
6289 value_len
= le16_to_cpu(temp_fea
->value_len
);
6290 list_len
-= name_len
+ 1 + value_len
;
6292 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6298 if (ea_name_len
== name_len
&&
6299 memcmp(ea_name
, temp_ptr
, name_len
) == 0) {
6300 temp_ptr
+= name_len
+ 1;
6304 if ((size_t)value_len
> buf_size
) {
6308 memcpy(EAData
, temp_ptr
, value_len
);
6312 /* account for prefix user. and trailing null */
6313 rc
+= (5 + 1 + name_len
);
6314 if (rc
< (int) buf_size
) {
6315 memcpy(EAData
, "user.", 5);
6317 memcpy(EAData
, temp_ptr
, name_len
);
6319 /* null terminate name */
6322 } else if (buf_size
== 0) {
6323 /* skip copy - calc size only */
6325 /* stop before overrun buffer */
6330 temp_ptr
+= name_len
+ 1 + value_len
;
6331 temp_fea
= (struct fea
*)temp_ptr
;
6334 /* didn't find the named attribute */
6339 cifs_buf_release(pSMB
);
6347 CIFSSMBSetEA(const unsigned int xid
, struct cifs_tcon
*tcon
,
6348 const char *fileName
, const char *ea_name
, const void *ea_value
,
6349 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
,
6352 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
6353 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
6354 struct fealist
*parm_data
;
6357 int bytes_returned
= 0;
6358 __u16 params
, param_offset
, byte_count
, offset
, count
;
6360 cifs_dbg(FYI
, "In SetEA\n");
6362 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6367 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6369 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
6370 PATH_MAX
, nls_codepage
, remap
);
6371 name_len
++; /* trailing null */
6373 } else { /* BB improve the check for buffer overruns BB */
6374 name_len
= strnlen(fileName
, PATH_MAX
);
6375 name_len
++; /* trailing null */
6376 strncpy(pSMB
->FileName
, fileName
, name_len
);
6379 params
= 6 + name_len
;
6381 /* done calculating parms using name_len of file name,
6382 now use name_len to calculate length of ea name
6383 we are going to create in the inode xattrs */
6384 if (ea_name
== NULL
)
6387 name_len
= strnlen(ea_name
, 255);
6389 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
;
6390 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6391 /* BB find max SMB PDU from sess */
6392 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6393 pSMB
->MaxSetupCount
= 0;
6397 pSMB
->Reserved2
= 0;
6398 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6399 InformationLevel
) - 4;
6400 offset
= param_offset
+ params
;
6401 pSMB
->InformationLevel
=
6402 cpu_to_le16(SMB_SET_FILE_EA
);
6405 (struct fealist
*) (((char *) &pSMB
->hdr
.Protocol
) +
6407 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6408 pSMB
->DataOffset
= cpu_to_le16(offset
);
6409 pSMB
->SetupCount
= 1;
6410 pSMB
->Reserved3
= 0;
6411 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6412 byte_count
= 3 /* pad */ + params
+ count
;
6413 pSMB
->DataCount
= cpu_to_le16(count
);
6414 parm_data
->list_len
= cpu_to_le32(count
);
6415 parm_data
->list
[0].EA_flags
= 0;
6416 /* we checked above that name len is less than 255 */
6417 parm_data
->list
[0].name_len
= (__u8
)name_len
;
6418 /* EA names are always ASCII */
6420 strncpy(parm_data
->list
[0].name
, ea_name
, name_len
);
6421 parm_data
->list
[0].name
[name_len
] = 0;
6422 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
6423 /* caller ensures that ea_value_len is less than 64K but
6424 we need to ensure that it fits within the smb */
6426 /*BB add length check to see if it would fit in
6427 negotiated SMB buffer size BB */
6428 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6430 memcpy(parm_data
->list
[0].name
+name_len
+1,
6431 ea_value
, ea_value_len
);
6433 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6434 pSMB
->ParameterCount
= cpu_to_le16(params
);
6435 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6436 pSMB
->Reserved4
= 0;
6437 inc_rfc1001_len(pSMB
, byte_count
);
6438 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6439 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6440 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6442 cifs_dbg(FYI
, "SetPathInfo (EA) returned %d\n", rc
);
6444 cifs_buf_release(pSMB
);
6453 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6455 * Years ago the kernel added a "dnotify" function for Samba server,
6456 * to allow network clients (such as Windows) to display updated
6457 * lists of files in directory listings automatically when
6458 * files are added by one user when another user has the
6459 * same directory open on their desktop. The Linux cifs kernel
6460 * client hooked into the kernel side of this interface for
6461 * the same reason, but ironically when the VFS moved from
6462 * "dnotify" to "inotify" it became harder to plug in Linux
6463 * network file system clients (the most obvious use case
6464 * for notify interfaces is when multiple users can update
6465 * the contents of the same directory - exactly what network
6466 * file systems can do) although the server (Samba) could
6467 * still use it. For the short term we leave the worker
6468 * function ifdeffed out (below) until inotify is fixed
6469 * in the VFS to make it easier to plug in network file
6470 * system clients. If inotify turns out to be permanently
6471 * incompatible for network fs clients, we could instead simply
6472 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6474 int CIFSSMBNotify(const unsigned int xid
, struct cifs_tcon
*tcon
,
6475 const int notify_subdirs
, const __u16 netfid
,
6476 __u32 filter
, struct file
*pfile
, int multishot
,
6477 const struct nls_table
*nls_codepage
)
6480 struct smb_com_transaction_change_notify_req
*pSMB
= NULL
;
6481 struct smb_com_ntransaction_change_notify_rsp
*pSMBr
= NULL
;
6482 struct dir_notify_req
*dnotify_req
;
6485 cifs_dbg(FYI
, "In CIFSSMBNotify for file handle %d\n", (int)netfid
);
6486 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
6491 pSMB
->TotalParameterCount
= 0 ;
6492 pSMB
->TotalDataCount
= 0;
6493 pSMB
->MaxParameterCount
= cpu_to_le32(2);
6494 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
6495 pSMB
->MaxSetupCount
= 4;
6497 pSMB
->ParameterOffset
= 0;
6498 pSMB
->DataCount
= 0;
6499 pSMB
->DataOffset
= 0;
6500 pSMB
->SetupCount
= 4; /* single byte does not need le conversion */
6501 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE
);
6502 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6504 pSMB
->WatchTree
= 1; /* one byte - no le conversion needed */
6505 pSMB
->Reserved2
= 0;
6506 pSMB
->CompletionFilter
= cpu_to_le32(filter
);
6507 pSMB
->Fid
= netfid
; /* file handle always le */
6508 pSMB
->ByteCount
= 0;
6510 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6511 (struct smb_hdr
*)pSMBr
, &bytes_returned
,
6514 cifs_dbg(FYI
, "Error in Notify = %d\n", rc
);
6516 /* Add file to outstanding requests */
6517 /* BB change to kmem cache alloc */
6518 dnotify_req
= kmalloc(
6519 sizeof(struct dir_notify_req
),
6522 dnotify_req
->Pid
= pSMB
->hdr
.Pid
;
6523 dnotify_req
->PidHigh
= pSMB
->hdr
.PidHigh
;
6524 dnotify_req
->Mid
= pSMB
->hdr
.Mid
;
6525 dnotify_req
->Tid
= pSMB
->hdr
.Tid
;
6526 dnotify_req
->Uid
= pSMB
->hdr
.Uid
;
6527 dnotify_req
->netfid
= netfid
;
6528 dnotify_req
->pfile
= pfile
;
6529 dnotify_req
->filter
= filter
;
6530 dnotify_req
->multishot
= multishot
;
6531 spin_lock(&GlobalMid_Lock
);
6532 list_add_tail(&dnotify_req
->lhead
,
6533 &GlobalDnotifyReqList
);
6534 spin_unlock(&GlobalMid_Lock
);
6538 cifs_buf_release(pSMB
);
6541 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */