4 * Copyright (C) International Business Machines Corp., 2002,2010
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Contains the routines for constructing the SMB PDUs themselves
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
25 /* These are mostly routines that operate on a pathname, or on a tree id */
26 /* (mounted volume), but there are eight handle based routines which must be */
27 /* treated slightly differently for reconnection purposes since we never */
28 /* want to reuse a stale file handle and only the caller knows the file info */
31 #include <linux/kernel.h>
32 #include <linux/vfs.h>
33 #include <linux/slab.h>
34 #include <linux/posix_acl_xattr.h>
35 #include <linux/pagemap.h>
36 #include <linux/swap.h>
37 #include <linux/task_io_accounting_ops.h>
38 #include <asm/uaccess.h>
42 #include "cifsproto.h"
43 #include "cifs_unicode.h"
44 #include "cifs_debug.h"
47 #ifdef CONFIG_CIFS_POSIX
52 #ifdef CONFIG_CIFS_WEAK_PW_HASH
53 {LANMAN_PROT
, "\2LM1.2X002"},
54 {LANMAN2_PROT
, "\2LANMAN2.1"},
55 #endif /* weak password hashing for legacy clients */
56 {CIFS_PROT
, "\2NT LM 0.12"},
57 {POSIX_PROT
, "\2POSIX 2"},
65 #ifdef CONFIG_CIFS_WEAK_PW_HASH
66 {LANMAN_PROT
, "\2LM1.2X002"},
67 {LANMAN2_PROT
, "\2LANMAN2.1"},
68 #endif /* weak password hashing for legacy clients */
69 {CIFS_PROT
, "\2NT LM 0.12"},
74 /* define the number of elements in the cifs dialect array */
75 #ifdef CONFIG_CIFS_POSIX
76 #ifdef CONFIG_CIFS_WEAK_PW_HASH
77 #define CIFS_NUM_PROT 4
79 #define CIFS_NUM_PROT 2
80 #endif /* CIFS_WEAK_PW_HASH */
82 #ifdef CONFIG_CIFS_WEAK_PW_HASH
83 #define CIFS_NUM_PROT 3
85 #define CIFS_NUM_PROT 1
86 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
87 #endif /* CIFS_POSIX */
90 * Mark as invalid, all open files on tree connections since they
91 * were closed when session to server was lost.
94 cifs_mark_open_files_invalid(struct cifs_tcon
*tcon
)
96 struct cifsFileInfo
*open_file
= NULL
;
97 struct list_head
*tmp
;
98 struct list_head
*tmp1
;
100 /* list all files open on tree connection and mark them invalid */
101 spin_lock(&tcon
->open_file_lock
);
102 list_for_each_safe(tmp
, tmp1
, &tcon
->openFileList
) {
103 open_file
= list_entry(tmp
, struct cifsFileInfo
, tlist
);
104 open_file
->invalidHandle
= true;
105 open_file
->oplock_break_cancelled
= true;
107 spin_unlock(&tcon
->open_file_lock
);
109 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
114 /* reconnect the socket, tcon, and smb session if needed */
116 cifs_reconnect_tcon(struct cifs_tcon
*tcon
, int smb_command
)
119 struct cifs_ses
*ses
;
120 struct TCP_Server_Info
*server
;
121 struct nls_table
*nls_codepage
;
124 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
125 * tcp and smb session status done differently for those three - in the
132 server
= ses
->server
;
135 * only tree disconnect, open, and write, (and ulogoff which does not
136 * have tcon) are allowed as we start force umount
138 if (tcon
->tidStatus
== CifsExiting
) {
139 if (smb_command
!= SMB_COM_WRITE_ANDX
&&
140 smb_command
!= SMB_COM_OPEN_ANDX
&&
141 smb_command
!= SMB_COM_TREE_DISCONNECT
) {
142 cifs_dbg(FYI
, "can not send cmd %d while umounting\n",
149 * Give demultiplex thread up to 10 seconds to reconnect, should be
150 * greater than cifs socket timeout which is 7 seconds
152 while (server
->tcpStatus
== CifsNeedReconnect
) {
153 rc
= wait_event_interruptible_timeout(server
->response_q
,
154 (server
->tcpStatus
!= CifsNeedReconnect
),
157 cifs_dbg(FYI
, "%s: aborting reconnect due to a received"
158 " signal by the process\n", __func__
);
162 /* are we still trying to reconnect? */
163 if (server
->tcpStatus
!= CifsNeedReconnect
)
167 * on "soft" mounts we wait once. Hard mounts keep
168 * retrying until process is killed or server comes
172 cifs_dbg(FYI
, "gave up waiting on reconnect in smb_init\n");
177 if (!ses
->need_reconnect
&& !tcon
->need_reconnect
)
180 nls_codepage
= load_nls_default();
183 * need to prevent multiple threads trying to simultaneously
184 * reconnect the same SMB session
186 mutex_lock(&ses
->session_mutex
);
189 * Recheck after acquire mutex. If another thread is negotiating
190 * and the server never sends an answer the socket will be closed
191 * and tcpStatus set to reconnect.
193 if (server
->tcpStatus
== CifsNeedReconnect
) {
195 mutex_unlock(&ses
->session_mutex
);
199 rc
= cifs_negotiate_protocol(0, ses
);
200 if (rc
== 0 && ses
->need_reconnect
)
201 rc
= cifs_setup_session(0, ses
, nls_codepage
);
203 /* do we need to reconnect tcon? */
204 if (rc
|| !tcon
->need_reconnect
) {
205 mutex_unlock(&ses
->session_mutex
);
209 cifs_mark_open_files_invalid(tcon
);
210 rc
= CIFSTCon(0, ses
, tcon
->treeName
, tcon
, nls_codepage
);
211 mutex_unlock(&ses
->session_mutex
);
212 cifs_dbg(FYI
, "reconnect tcon rc = %d\n", rc
);
217 atomic_inc(&tconInfoReconnectCount
);
219 /* tell server Unix caps we support */
220 if (ses
->capabilities
& CAP_UNIX
)
221 reset_cifs_unix_caps(0, tcon
, NULL
, NULL
);
224 * Removed call to reopen open files here. It is safer (and faster) to
225 * reopen files one at a time as needed in read and write.
227 * FIXME: what about file locks? don't we need to reclaim them ASAP?
232 * Check if handle based operation so we know whether we can continue
233 * or not without returning to caller to reset file handle
235 switch (smb_command
) {
236 case SMB_COM_READ_ANDX
:
237 case SMB_COM_WRITE_ANDX
:
239 case SMB_COM_FIND_CLOSE2
:
240 case SMB_COM_LOCKING_ANDX
:
244 unload_nls(nls_codepage
);
248 /* Allocate and return pointer to an SMB request buffer, and set basic
249 SMB information in the SMB header. If the return code is zero, this
250 function must have filled in request_buf pointer */
252 small_smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
257 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
261 *request_buf
= cifs_small_buf_get();
262 if (*request_buf
== NULL
) {
263 /* BB should we add a retry in here if not a writepage? */
267 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
,
271 cifs_stats_inc(&tcon
->num_smbs_sent
);
277 small_smb_init_no_tc(const int smb_command
, const int wct
,
278 struct cifs_ses
*ses
, void **request_buf
)
281 struct smb_hdr
*buffer
;
283 rc
= small_smb_init(smb_command
, wct
, NULL
, request_buf
);
287 buffer
= (struct smb_hdr
*)*request_buf
;
288 buffer
->Mid
= get_next_mid(ses
->server
);
289 if (ses
->capabilities
& CAP_UNICODE
)
290 buffer
->Flags2
|= SMBFLG2_UNICODE
;
291 if (ses
->capabilities
& CAP_STATUS32
)
292 buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
294 /* uid, tid can stay at zero as set in header assemble */
296 /* BB add support for turning on the signing when
297 this function is used after 1st of session setup requests */
302 /* If the return code is zero, this function must fill in request_buf pointer */
304 __smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
305 void **request_buf
, void **response_buf
)
307 *request_buf
= cifs_buf_get();
308 if (*request_buf
== NULL
) {
309 /* BB should we add a retry in here if not a writepage? */
312 /* Although the original thought was we needed the response buf for */
313 /* potential retries of smb operations it turns out we can determine */
314 /* from the mid flags when the request buffer can be resent without */
315 /* having to use a second distinct buffer for the response */
317 *response_buf
= *request_buf
;
319 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
, tcon
,
323 cifs_stats_inc(&tcon
->num_smbs_sent
);
328 /* If the return code is zero, this function must fill in request_buf pointer */
330 smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
331 void **request_buf
, void **response_buf
)
335 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
339 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
343 smb_init_no_reconnect(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
344 void **request_buf
, void **response_buf
)
346 if (tcon
->ses
->need_reconnect
|| tcon
->need_reconnect
)
349 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
352 static int validate_t2(struct smb_t2_rsp
*pSMB
)
354 unsigned int total_size
;
356 /* check for plausible wct */
357 if (pSMB
->hdr
.WordCount
< 10)
360 /* check for parm and data offset going beyond end of smb */
361 if (get_unaligned_le16(&pSMB
->t2_rsp
.ParameterOffset
) > 1024 ||
362 get_unaligned_le16(&pSMB
->t2_rsp
.DataOffset
) > 1024)
365 total_size
= get_unaligned_le16(&pSMB
->t2_rsp
.ParameterCount
);
366 if (total_size
>= 512)
369 /* check that bcc is at least as big as parms + data, and that it is
370 * less than negotiated smb buffer
372 total_size
+= get_unaligned_le16(&pSMB
->t2_rsp
.DataCount
);
373 if (total_size
> get_bcc(&pSMB
->hdr
) ||
374 total_size
>= CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
)
379 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB
,
380 sizeof(struct smb_t2_rsp
) + 16);
385 decode_ext_sec_blob(struct cifs_ses
*ses
, NEGOTIATE_RSP
*pSMBr
)
389 char *guid
= pSMBr
->u
.extended_response
.GUID
;
390 struct TCP_Server_Info
*server
= ses
->server
;
392 count
= get_bcc(&pSMBr
->hdr
);
393 if (count
< SMB1_CLIENT_GUID_SIZE
)
396 spin_lock(&cifs_tcp_ses_lock
);
397 if (server
->srv_count
> 1) {
398 spin_unlock(&cifs_tcp_ses_lock
);
399 if (memcmp(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
) != 0) {
400 cifs_dbg(FYI
, "server UID changed\n");
401 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
404 spin_unlock(&cifs_tcp_ses_lock
);
405 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
408 if (count
== SMB1_CLIENT_GUID_SIZE
) {
409 server
->sec_ntlmssp
= true;
411 count
-= SMB1_CLIENT_GUID_SIZE
;
412 rc
= decode_negTokenInit(
413 pSMBr
->u
.extended_response
.SecurityBlob
, count
, server
);
422 cifs_enable_signing(struct TCP_Server_Info
*server
, bool mnt_sign_required
)
424 bool srv_sign_required
= server
->sec_mode
& server
->vals
->signing_required
;
425 bool srv_sign_enabled
= server
->sec_mode
& server
->vals
->signing_enabled
;
426 bool mnt_sign_enabled
= global_secflags
& CIFSSEC_MAY_SIGN
;
429 * Is signing required by mnt options? If not then check
430 * global_secflags to see if it is there.
432 if (!mnt_sign_required
)
433 mnt_sign_required
= ((global_secflags
& CIFSSEC_MUST_SIGN
) ==
437 * If signing is required then it's automatically enabled too,
438 * otherwise, check to see if the secflags allow it.
440 mnt_sign_enabled
= mnt_sign_required
? mnt_sign_required
:
441 (global_secflags
& CIFSSEC_MAY_SIGN
);
443 /* If server requires signing, does client allow it? */
444 if (srv_sign_required
) {
445 if (!mnt_sign_enabled
) {
446 cifs_dbg(VFS
, "Server requires signing, but it's disabled in SecurityFlags!");
452 /* If client requires signing, does server allow it? */
453 if (mnt_sign_required
) {
454 if (!srv_sign_enabled
) {
455 cifs_dbg(VFS
, "Server does not support signing!");
464 #ifdef CONFIG_CIFS_WEAK_PW_HASH
466 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
469 struct lanman_neg_rsp
*rsp
= (struct lanman_neg_rsp
*)pSMBr
;
471 if (server
->dialect
!= LANMAN_PROT
&& server
->dialect
!= LANMAN2_PROT
)
474 server
->sec_mode
= le16_to_cpu(rsp
->SecurityMode
);
475 server
->maxReq
= min_t(unsigned int,
476 le16_to_cpu(rsp
->MaxMpxCount
),
478 set_credits(server
, server
->maxReq
);
479 server
->maxBuf
= le16_to_cpu(rsp
->MaxBufSize
);
480 /* even though we do not use raw we might as well set this
481 accurately, in case we ever find a need for it */
482 if ((le16_to_cpu(rsp
->RawMode
) & RAW_ENABLE
) == RAW_ENABLE
) {
483 server
->max_rw
= 0xFF00;
484 server
->capabilities
= CAP_MPX_MODE
| CAP_RAW_MODE
;
486 server
->max_rw
= 0;/* do not need to use raw anyway */
487 server
->capabilities
= CAP_MPX_MODE
;
489 tmp
= (__s16
)le16_to_cpu(rsp
->ServerTimeZone
);
491 /* OS/2 often does not set timezone therefore
492 * we must use server time to calc time zone.
493 * Could deviate slightly from the right zone.
494 * Smallest defined timezone difference is 15 minutes
495 * (i.e. Nepal). Rounding up/down is done to match
498 int val
, seconds
, remain
, result
;
499 struct timespec ts
, utc
;
501 ts
= cnvrtDosUnixTm(rsp
->SrvTime
.Date
,
502 rsp
->SrvTime
.Time
, 0);
503 cifs_dbg(FYI
, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
504 (int)ts
.tv_sec
, (int)utc
.tv_sec
,
505 (int)(utc
.tv_sec
- ts
.tv_sec
));
506 val
= (int)(utc
.tv_sec
- ts
.tv_sec
);
508 result
= (seconds
/ MIN_TZ_ADJ
) * MIN_TZ_ADJ
;
509 remain
= seconds
% MIN_TZ_ADJ
;
510 if (remain
>= (MIN_TZ_ADJ
/ 2))
511 result
+= MIN_TZ_ADJ
;
514 server
->timeAdj
= result
;
516 server
->timeAdj
= (int)tmp
;
517 server
->timeAdj
*= 60; /* also in seconds */
519 cifs_dbg(FYI
, "server->timeAdj: %d seconds\n", server
->timeAdj
);
522 /* BB get server time for time conversions and add
523 code to use it and timezone since this is not UTC */
525 if (rsp
->EncryptionKeyLength
==
526 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE
)) {
527 memcpy(server
->cryptkey
, rsp
->EncryptionKey
,
528 CIFS_CRYPTO_KEY_SIZE
);
529 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
530 return -EIO
; /* need cryptkey unless plain text */
533 cifs_dbg(FYI
, "LANMAN negotiated\n");
538 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
540 cifs_dbg(VFS
, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
546 should_set_ext_sec_flag(enum securityEnum sectype
)
553 if (global_secflags
&
554 (CIFSSEC_MAY_KRB5
| CIFSSEC_MAY_NTLMSSP
))
563 CIFSSMBNegotiate(const unsigned int xid
, struct cifs_ses
*ses
)
566 NEGOTIATE_RSP
*pSMBr
;
570 struct TCP_Server_Info
*server
= ses
->server
;
574 WARN(1, "%s: server is NULL!\n", __func__
);
578 rc
= smb_init(SMB_COM_NEGOTIATE
, 0, NULL
/* no tcon yet */ ,
579 (void **) &pSMB
, (void **) &pSMBr
);
583 pSMB
->hdr
.Mid
= get_next_mid(server
);
584 pSMB
->hdr
.Flags2
|= (SMBFLG2_UNICODE
| SMBFLG2_ERR_STATUS
);
586 if (should_set_ext_sec_flag(ses
->sectype
)) {
587 cifs_dbg(FYI
, "Requesting extended security.");
588 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
593 * We know that all the name entries in the protocols array
594 * are short (< 16 bytes anyway) and are NUL terminated.
596 for (i
= 0; i
< CIFS_NUM_PROT
; i
++) {
597 size_t len
= strlen(protocols
[i
].name
) + 1;
599 memcpy(pSMB
->DialectsArray
+count
, protocols
[i
].name
, len
);
602 inc_rfc1001_len(pSMB
, count
);
603 pSMB
->ByteCount
= cpu_to_le16(count
);
605 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
606 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
610 server
->dialect
= le16_to_cpu(pSMBr
->DialectIndex
);
611 cifs_dbg(FYI
, "Dialect: %d\n", server
->dialect
);
612 /* Check wct = 1 error case */
613 if ((pSMBr
->hdr
.WordCount
< 13) || (server
->dialect
== BAD_PROT
)) {
614 /* core returns wct = 1, but we do not ask for core - otherwise
615 small wct just comes when dialect index is -1 indicating we
616 could not negotiate a common dialect */
619 } else if (pSMBr
->hdr
.WordCount
== 13) {
620 server
->negflavor
= CIFS_NEGFLAVOR_LANMAN
;
621 rc
= decode_lanman_negprot_rsp(server
, pSMBr
);
623 } else if (pSMBr
->hdr
.WordCount
!= 17) {
628 /* else wct == 17, NTLM or better */
630 server
->sec_mode
= pSMBr
->SecurityMode
;
631 if ((server
->sec_mode
& SECMODE_USER
) == 0)
632 cifs_dbg(FYI
, "share mode security\n");
634 /* one byte, so no need to convert this or EncryptionKeyLen from
636 server
->maxReq
= min_t(unsigned int, le16_to_cpu(pSMBr
->MaxMpxCount
),
638 set_credits(server
, server
->maxReq
);
639 /* probably no need to store and check maxvcs */
640 server
->maxBuf
= le32_to_cpu(pSMBr
->MaxBufferSize
);
641 server
->max_rw
= le32_to_cpu(pSMBr
->MaxRawSize
);
642 cifs_dbg(NOISY
, "Max buf = %d\n", ses
->server
->maxBuf
);
643 server
->capabilities
= le32_to_cpu(pSMBr
->Capabilities
);
644 server
->timeAdj
= (int)(__s16
)le16_to_cpu(pSMBr
->ServerTimeZone
);
645 server
->timeAdj
*= 60;
647 if (pSMBr
->EncryptionKeyLength
== CIFS_CRYPTO_KEY_SIZE
) {
648 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
649 memcpy(ses
->server
->cryptkey
, pSMBr
->u
.EncryptionKey
,
650 CIFS_CRYPTO_KEY_SIZE
);
651 } else if (pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
||
652 server
->capabilities
& CAP_EXTENDED_SECURITY
) {
653 server
->negflavor
= CIFS_NEGFLAVOR_EXTENDED
;
654 rc
= decode_ext_sec_blob(ses
, pSMBr
);
655 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
656 rc
= -EIO
; /* no crypt key only if plain text pwd */
658 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
659 server
->capabilities
&= ~CAP_EXTENDED_SECURITY
;
664 rc
= cifs_enable_signing(server
, ses
->sign
);
666 cifs_buf_release(pSMB
);
668 cifs_dbg(FYI
, "negprot rc %d\n", rc
);
673 CIFSSMBTDis(const unsigned int xid
, struct cifs_tcon
*tcon
)
675 struct smb_hdr
*smb_buffer
;
678 cifs_dbg(FYI
, "In tree disconnect\n");
680 /* BB: do we need to check this? These should never be NULL. */
681 if ((tcon
->ses
== NULL
) || (tcon
->ses
->server
== NULL
))
685 * No need to return error on this operation if tid invalidated and
686 * closed on server already e.g. due to tcp session crashing. Also,
687 * the tcon is no longer on the list, so no need to take lock before
690 if ((tcon
->need_reconnect
) || (tcon
->ses
->need_reconnect
))
693 rc
= small_smb_init(SMB_COM_TREE_DISCONNECT
, 0, tcon
,
694 (void **)&smb_buffer
);
698 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)smb_buffer
, 0);
700 cifs_dbg(FYI
, "Tree disconnect failed %d\n", rc
);
702 /* No need to return error on this operation if tid invalidated and
703 closed on server already e.g. due to tcp session crashing */
711 * This is a no-op for now. We're not really interested in the reply, but
712 * rather in the fact that the server sent one and that server->lstrp
715 * FIXME: maybe we should consider checking that the reply matches request?
718 cifs_echo_callback(struct mid_q_entry
*mid
)
720 struct TCP_Server_Info
*server
= mid
->callback_data
;
722 mutex_lock(&server
->srv_mutex
);
723 DeleteMidQEntry(mid
);
724 mutex_unlock(&server
->srv_mutex
);
725 add_credits(server
, 1, CIFS_ECHO_OP
);
729 CIFSSMBEcho(struct TCP_Server_Info
*server
)
734 struct smb_rqst rqst
= { .rq_iov
= &iov
,
737 cifs_dbg(FYI
, "In echo request\n");
739 rc
= small_smb_init(SMB_COM_ECHO
, 0, NULL
, (void **)&smb
);
743 if (server
->capabilities
& CAP_UNICODE
)
744 smb
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
746 /* set up echo request */
747 smb
->hdr
.Tid
= 0xffff;
748 smb
->hdr
.WordCount
= 1;
749 put_unaligned_le16(1, &smb
->EchoCount
);
750 put_bcc(1, &smb
->hdr
);
752 inc_rfc1001_len(smb
, 3);
754 iov
.iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4;
756 rc
= cifs_call_async(server
, &rqst
, NULL
, cifs_echo_callback
,
757 server
, CIFS_ASYNC_OP
| CIFS_ECHO_OP
);
759 cifs_dbg(FYI
, "Echo request failed: %d\n", rc
);
761 cifs_small_buf_release(smb
);
767 CIFSSMBLogoff(const unsigned int xid
, struct cifs_ses
*ses
)
769 LOGOFF_ANDX_REQ
*pSMB
;
772 cifs_dbg(FYI
, "In SMBLogoff for session disconnect\n");
775 * BB: do we need to check validity of ses and server? They should
776 * always be valid since we have an active reference. If not, that
777 * should probably be a BUG()
779 if (!ses
|| !ses
->server
)
782 mutex_lock(&ses
->session_mutex
);
783 if (ses
->need_reconnect
)
784 goto session_already_dead
; /* no need to send SMBlogoff if uid
785 already closed due to reconnect */
786 rc
= small_smb_init(SMB_COM_LOGOFF_ANDX
, 2, NULL
, (void **)&pSMB
);
788 mutex_unlock(&ses
->session_mutex
);
792 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
794 if (ses
->server
->sign
)
795 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
797 pSMB
->hdr
.Uid
= ses
->Suid
;
799 pSMB
->AndXCommand
= 0xFF;
800 rc
= SendReceiveNoRsp(xid
, ses
, (char *) pSMB
, 0);
801 session_already_dead
:
802 mutex_unlock(&ses
->session_mutex
);
804 /* if session dead then we do not need to do ulogoff,
805 since server closed smb session, no sense reporting
813 CIFSPOSIXDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
,
814 const char *fileName
, __u16 type
,
815 const struct nls_table
*nls_codepage
, int remap
)
817 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
818 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
819 struct unlink_psx_rq
*pRqD
;
822 int bytes_returned
= 0;
823 __u16 params
, param_offset
, offset
, byte_count
;
825 cifs_dbg(FYI
, "In POSIX delete\n");
827 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
832 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
834 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
835 PATH_MAX
, nls_codepage
, remap
);
836 name_len
++; /* trailing null */
838 } else { /* BB add path length overrun check */
839 name_len
= strnlen(fileName
, PATH_MAX
);
840 name_len
++; /* trailing null */
841 strncpy(pSMB
->FileName
, fileName
, name_len
);
844 params
= 6 + name_len
;
845 pSMB
->MaxParameterCount
= cpu_to_le16(2);
846 pSMB
->MaxDataCount
= 0; /* BB double check this with jra */
847 pSMB
->MaxSetupCount
= 0;
852 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
853 InformationLevel
) - 4;
854 offset
= param_offset
+ params
;
856 /* Setup pointer to Request Data (inode type) */
857 pRqD
= (struct unlink_psx_rq
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
858 pRqD
->type
= cpu_to_le16(type
);
859 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
860 pSMB
->DataOffset
= cpu_to_le16(offset
);
861 pSMB
->SetupCount
= 1;
863 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
864 byte_count
= 3 /* pad */ + params
+ sizeof(struct unlink_psx_rq
);
866 pSMB
->DataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
867 pSMB
->TotalDataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
868 pSMB
->ParameterCount
= cpu_to_le16(params
);
869 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
870 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_UNLINK
);
872 inc_rfc1001_len(pSMB
, byte_count
);
873 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
874 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
875 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
877 cifs_dbg(FYI
, "Posix delete returned %d\n", rc
);
878 cifs_buf_release(pSMB
);
880 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
889 CIFSSMBDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
890 struct cifs_sb_info
*cifs_sb
)
892 DELETE_FILE_REQ
*pSMB
= NULL
;
893 DELETE_FILE_RSP
*pSMBr
= NULL
;
897 int remap
= cifs_remap(cifs_sb
);
900 rc
= smb_init(SMB_COM_DELETE
, 1, tcon
, (void **) &pSMB
,
905 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
906 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->fileName
, name
,
907 PATH_MAX
, cifs_sb
->local_nls
,
909 name_len
++; /* trailing null */
911 } else { /* BB improve check for buffer overruns BB */
912 name_len
= strnlen(name
, PATH_MAX
);
913 name_len
++; /* trailing null */
914 strncpy(pSMB
->fileName
, name
, name_len
);
916 pSMB
->SearchAttributes
=
917 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
);
918 pSMB
->BufferFormat
= 0x04;
919 inc_rfc1001_len(pSMB
, name_len
+ 1);
920 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
921 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
922 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
923 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
925 cifs_dbg(FYI
, "Error in RMFile = %d\n", rc
);
927 cifs_buf_release(pSMB
);
935 CIFSSMBRmDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
936 struct cifs_sb_info
*cifs_sb
)
938 DELETE_DIRECTORY_REQ
*pSMB
= NULL
;
939 DELETE_DIRECTORY_RSP
*pSMBr
= NULL
;
943 int remap
= cifs_remap(cifs_sb
);
945 cifs_dbg(FYI
, "In CIFSSMBRmDir\n");
947 rc
= smb_init(SMB_COM_DELETE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
952 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
953 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
954 PATH_MAX
, cifs_sb
->local_nls
,
956 name_len
++; /* trailing null */
958 } else { /* BB improve check for buffer overruns BB */
959 name_len
= strnlen(name
, PATH_MAX
);
960 name_len
++; /* trailing null */
961 strncpy(pSMB
->DirName
, name
, name_len
);
964 pSMB
->BufferFormat
= 0x04;
965 inc_rfc1001_len(pSMB
, name_len
+ 1);
966 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
967 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
968 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
969 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_rmdirs
);
971 cifs_dbg(FYI
, "Error in RMDir = %d\n", rc
);
973 cifs_buf_release(pSMB
);
980 CIFSSMBMkDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
981 struct cifs_sb_info
*cifs_sb
)
984 CREATE_DIRECTORY_REQ
*pSMB
= NULL
;
985 CREATE_DIRECTORY_RSP
*pSMBr
= NULL
;
988 int remap
= cifs_remap(cifs_sb
);
990 cifs_dbg(FYI
, "In CIFSSMBMkDir\n");
992 rc
= smb_init(SMB_COM_CREATE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
997 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
998 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
999 PATH_MAX
, cifs_sb
->local_nls
,
1001 name_len
++; /* trailing null */
1003 } else { /* BB improve check for buffer overruns BB */
1004 name_len
= strnlen(name
, PATH_MAX
);
1005 name_len
++; /* trailing null */
1006 strncpy(pSMB
->DirName
, name
, name_len
);
1009 pSMB
->BufferFormat
= 0x04;
1010 inc_rfc1001_len(pSMB
, name_len
+ 1);
1011 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1012 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1013 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1014 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_mkdirs
);
1016 cifs_dbg(FYI
, "Error in Mkdir = %d\n", rc
);
1018 cifs_buf_release(pSMB
);
1025 CIFSPOSIXCreate(const unsigned int xid
, struct cifs_tcon
*tcon
,
1026 __u32 posix_flags
, __u64 mode
, __u16
*netfid
,
1027 FILE_UNIX_BASIC_INFO
*pRetData
, __u32
*pOplock
,
1028 const char *name
, const struct nls_table
*nls_codepage
,
1031 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
1032 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
1035 int bytes_returned
= 0;
1036 __u16 params
, param_offset
, offset
, byte_count
, count
;
1037 OPEN_PSX_REQ
*pdata
;
1038 OPEN_PSX_RSP
*psx_rsp
;
1040 cifs_dbg(FYI
, "In POSIX Create\n");
1042 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1047 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1049 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, name
,
1050 PATH_MAX
, nls_codepage
, remap
);
1051 name_len
++; /* trailing null */
1053 } else { /* BB improve the check for buffer overruns BB */
1054 name_len
= strnlen(name
, PATH_MAX
);
1055 name_len
++; /* trailing null */
1056 strncpy(pSMB
->FileName
, name
, name_len
);
1059 params
= 6 + name_len
;
1060 count
= sizeof(OPEN_PSX_REQ
);
1061 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1062 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* large enough */
1063 pSMB
->MaxSetupCount
= 0;
1067 pSMB
->Reserved2
= 0;
1068 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
1069 InformationLevel
) - 4;
1070 offset
= param_offset
+ params
;
1071 pdata
= (OPEN_PSX_REQ
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
1072 pdata
->Level
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
1073 pdata
->Permissions
= cpu_to_le64(mode
);
1074 pdata
->PosixOpenFlags
= cpu_to_le32(posix_flags
);
1075 pdata
->OpenFlags
= cpu_to_le32(*pOplock
);
1076 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
1077 pSMB
->DataOffset
= cpu_to_le16(offset
);
1078 pSMB
->SetupCount
= 1;
1079 pSMB
->Reserved3
= 0;
1080 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
1081 byte_count
= 3 /* pad */ + params
+ count
;
1083 pSMB
->DataCount
= cpu_to_le16(count
);
1084 pSMB
->ParameterCount
= cpu_to_le16(params
);
1085 pSMB
->TotalDataCount
= pSMB
->DataCount
;
1086 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1087 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_OPEN
);
1088 pSMB
->Reserved4
= 0;
1089 inc_rfc1001_len(pSMB
, byte_count
);
1090 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1091 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1092 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1094 cifs_dbg(FYI
, "Posix create returned %d\n", rc
);
1095 goto psx_create_err
;
1098 cifs_dbg(FYI
, "copying inode info\n");
1099 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
1101 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)) {
1102 rc
= -EIO
; /* bad smb */
1103 goto psx_create_err
;
1106 /* copy return information to pRetData */
1107 psx_rsp
= (OPEN_PSX_RSP
*)((char *) &pSMBr
->hdr
.Protocol
1108 + le16_to_cpu(pSMBr
->t2
.DataOffset
));
1110 *pOplock
= le16_to_cpu(psx_rsp
->OplockFlags
);
1112 *netfid
= psx_rsp
->Fid
; /* cifs fid stays in le */
1113 /* Let caller know file was created so we can set the mode. */
1114 /* Do we care about the CreateAction in any other cases? */
1115 if (cpu_to_le32(FILE_CREATE
) == psx_rsp
->CreateAction
)
1116 *pOplock
|= CIFS_CREATE_ACTION
;
1117 /* check to make sure response data is there */
1118 if (psx_rsp
->ReturnedLevel
!= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
)) {
1119 pRetData
->Type
= cpu_to_le32(-1); /* unknown */
1120 cifs_dbg(NOISY
, "unknown type\n");
1122 if (get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)
1123 + sizeof(FILE_UNIX_BASIC_INFO
)) {
1124 cifs_dbg(VFS
, "Open response data too small\n");
1125 pRetData
->Type
= cpu_to_le32(-1);
1126 goto psx_create_err
;
1128 memcpy((char *) pRetData
,
1129 (char *)psx_rsp
+ sizeof(OPEN_PSX_RSP
),
1130 sizeof(FILE_UNIX_BASIC_INFO
));
1134 cifs_buf_release(pSMB
);
1136 if (posix_flags
& SMB_O_DIRECTORY
)
1137 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixmkdirs
);
1139 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixopens
);
1147 static __u16
convert_disposition(int disposition
)
1151 switch (disposition
) {
1152 case FILE_SUPERSEDE
:
1153 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1156 ofun
= SMBOPEN_OAPPEND
;
1159 ofun
= SMBOPEN_OCREATE
;
1162 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OAPPEND
;
1164 case FILE_OVERWRITE
:
1165 ofun
= SMBOPEN_OTRUNC
;
1167 case FILE_OVERWRITE_IF
:
1168 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1171 cifs_dbg(FYI
, "unknown disposition %d\n", disposition
);
1172 ofun
= SMBOPEN_OAPPEND
; /* regular open */
1178 access_flags_to_smbopen_mode(const int access_flags
)
1180 int masked_flags
= access_flags
& (GENERIC_READ
| GENERIC_WRITE
);
1182 if (masked_flags
== GENERIC_READ
)
1183 return SMBOPEN_READ
;
1184 else if (masked_flags
== GENERIC_WRITE
)
1185 return SMBOPEN_WRITE
;
1187 /* just go for read/write */
1188 return SMBOPEN_READWRITE
;
1192 SMBLegacyOpen(const unsigned int xid
, struct cifs_tcon
*tcon
,
1193 const char *fileName
, const int openDisposition
,
1194 const int access_flags
, const int create_options
, __u16
*netfid
,
1195 int *pOplock
, FILE_ALL_INFO
*pfile_info
,
1196 const struct nls_table
*nls_codepage
, int remap
)
1199 OPENX_REQ
*pSMB
= NULL
;
1200 OPENX_RSP
*pSMBr
= NULL
;
1206 rc
= smb_init(SMB_COM_OPEN_ANDX
, 15, tcon
, (void **) &pSMB
,
1211 pSMB
->AndXCommand
= 0xFF; /* none */
1213 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1214 count
= 1; /* account for one byte pad to word boundary */
1216 cifsConvertToUTF16((__le16
*) (pSMB
->fileName
+ 1),
1217 fileName
, PATH_MAX
, nls_codepage
, remap
);
1218 name_len
++; /* trailing null */
1220 } else { /* BB improve check for buffer overruns BB */
1221 count
= 0; /* no pad */
1222 name_len
= strnlen(fileName
, PATH_MAX
);
1223 name_len
++; /* trailing null */
1224 strncpy(pSMB
->fileName
, fileName
, name_len
);
1226 if (*pOplock
& REQ_OPLOCK
)
1227 pSMB
->OpenFlags
= cpu_to_le16(REQ_OPLOCK
);
1228 else if (*pOplock
& REQ_BATCHOPLOCK
)
1229 pSMB
->OpenFlags
= cpu_to_le16(REQ_BATCHOPLOCK
);
1231 pSMB
->OpenFlags
|= cpu_to_le16(REQ_MORE_INFO
);
1232 pSMB
->Mode
= cpu_to_le16(access_flags_to_smbopen_mode(access_flags
));
1233 pSMB
->Mode
|= cpu_to_le16(0x40); /* deny none */
1234 /* set file as system file if special file such
1235 as fifo and server expecting SFU style and
1236 no Unix extensions */
1238 if (create_options
& CREATE_OPTION_SPECIAL
)
1239 pSMB
->FileAttributes
= cpu_to_le16(ATTR_SYSTEM
);
1240 else /* BB FIXME BB */
1241 pSMB
->FileAttributes
= cpu_to_le16(0/*ATTR_NORMAL*/);
1243 if (create_options
& CREATE_OPTION_READONLY
)
1244 pSMB
->FileAttributes
|= cpu_to_le16(ATTR_READONLY
);
1247 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1248 CREATE_OPTIONS_MASK); */
1249 /* BB FIXME END BB */
1251 pSMB
->Sattr
= cpu_to_le16(ATTR_HIDDEN
| ATTR_SYSTEM
| ATTR_DIRECTORY
);
1252 pSMB
->OpenFunction
= cpu_to_le16(convert_disposition(openDisposition
));
1254 inc_rfc1001_len(pSMB
, count
);
1256 pSMB
->ByteCount
= cpu_to_le16(count
);
1257 /* long_op set to 1 to allow for oplock break timeouts */
1258 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1259 (struct smb_hdr
*)pSMBr
, &bytes_returned
, 0);
1260 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1262 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1264 /* BB verify if wct == 15 */
1266 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1268 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
1269 /* Let caller know file was created so we can set the mode. */
1270 /* Do we care about the CreateAction in any other cases? */
1272 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1273 *pOplock |= CIFS_CREATE_ACTION; */
1277 pfile_info
->CreationTime
= 0; /* BB convert CreateTime*/
1278 pfile_info
->LastAccessTime
= 0; /* BB fixme */
1279 pfile_info
->LastWriteTime
= 0; /* BB fixme */
1280 pfile_info
->ChangeTime
= 0; /* BB fixme */
1281 pfile_info
->Attributes
=
1282 cpu_to_le32(le16_to_cpu(pSMBr
->FileAttributes
));
1283 /* the file_info buf is endian converted by caller */
1284 pfile_info
->AllocationSize
=
1285 cpu_to_le64(le32_to_cpu(pSMBr
->EndOfFile
));
1286 pfile_info
->EndOfFile
= pfile_info
->AllocationSize
;
1287 pfile_info
->NumberOfLinks
= cpu_to_le32(1);
1288 pfile_info
->DeletePending
= 0;
1292 cifs_buf_release(pSMB
);
1299 CIFS_open(const unsigned int xid
, struct cifs_open_parms
*oparms
, int *oplock
,
1303 OPEN_REQ
*req
= NULL
;
1304 OPEN_RSP
*rsp
= NULL
;
1308 struct cifs_sb_info
*cifs_sb
= oparms
->cifs_sb
;
1309 struct cifs_tcon
*tcon
= oparms
->tcon
;
1310 int remap
= cifs_remap(cifs_sb
);
1311 const struct nls_table
*nls
= cifs_sb
->local_nls
;
1312 int create_options
= oparms
->create_options
;
1313 int desired_access
= oparms
->desired_access
;
1314 int disposition
= oparms
->disposition
;
1315 const char *path
= oparms
->path
;
1318 rc
= smb_init(SMB_COM_NT_CREATE_ANDX
, 24, tcon
, (void **)&req
,
1323 /* no commands go after this */
1324 req
->AndXCommand
= 0xFF;
1326 if (req
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1327 /* account for one byte pad to word boundary */
1329 name_len
= cifsConvertToUTF16((__le16
*)(req
->fileName
+ 1),
1330 path
, PATH_MAX
, nls
, remap
);
1334 req
->NameLength
= cpu_to_le16(name_len
);
1336 /* BB improve check for buffer overruns BB */
1339 name_len
= strnlen(path
, PATH_MAX
);
1342 req
->NameLength
= cpu_to_le16(name_len
);
1343 strncpy(req
->fileName
, path
, name_len
);
1346 if (*oplock
& REQ_OPLOCK
)
1347 req
->OpenFlags
= cpu_to_le32(REQ_OPLOCK
);
1348 else if (*oplock
& REQ_BATCHOPLOCK
)
1349 req
->OpenFlags
= cpu_to_le32(REQ_BATCHOPLOCK
);
1351 req
->DesiredAccess
= cpu_to_le32(desired_access
);
1352 req
->AllocationSize
= 0;
1355 * Set file as system file if special file such as fifo and server
1356 * expecting SFU style and no Unix extensions.
1358 if (create_options
& CREATE_OPTION_SPECIAL
)
1359 req
->FileAttributes
= cpu_to_le32(ATTR_SYSTEM
);
1361 req
->FileAttributes
= cpu_to_le32(ATTR_NORMAL
);
1364 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1365 * sensitive checks for other servers such as Samba.
1367 if (tcon
->ses
->capabilities
& CAP_UNIX
)
1368 req
->FileAttributes
|= cpu_to_le32(ATTR_POSIX_SEMANTICS
);
1370 if (create_options
& CREATE_OPTION_READONLY
)
1371 req
->FileAttributes
|= cpu_to_le32(ATTR_READONLY
);
1373 req
->ShareAccess
= cpu_to_le32(FILE_SHARE_ALL
);
1374 req
->CreateDisposition
= cpu_to_le32(disposition
);
1375 req
->CreateOptions
= cpu_to_le32(create_options
& CREATE_OPTIONS_MASK
);
1377 /* BB Expirement with various impersonation levels and verify */
1378 req
->ImpersonationLevel
= cpu_to_le32(SECURITY_IMPERSONATION
);
1379 req
->SecurityFlags
= SECURITY_CONTEXT_TRACKING
|SECURITY_EFFECTIVE_ONLY
;
1382 inc_rfc1001_len(req
, count
);
1384 req
->ByteCount
= cpu_to_le16(count
);
1385 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*)req
,
1386 (struct smb_hdr
*)rsp
, &bytes_returned
, 0);
1387 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1389 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1390 cifs_buf_release(req
);
1396 /* 1 byte no need to le_to_cpu */
1397 *oplock
= rsp
->OplockLevel
;
1398 /* cifs fid stays in le */
1399 oparms
->fid
->netfid
= rsp
->Fid
;
1401 /* Let caller know file was created so we can set the mode. */
1402 /* Do we care about the CreateAction in any other cases? */
1403 if (cpu_to_le32(FILE_CREATE
) == rsp
->CreateAction
)
1404 *oplock
|= CIFS_CREATE_ACTION
;
1407 /* copy from CreationTime to Attributes */
1408 memcpy((char *)buf
, (char *)&rsp
->CreationTime
, 36);
1409 /* the file_info buf is endian converted by caller */
1410 buf
->AllocationSize
= rsp
->AllocationSize
;
1411 buf
->EndOfFile
= rsp
->EndOfFile
;
1412 buf
->NumberOfLinks
= cpu_to_le32(1);
1413 buf
->DeletePending
= 0;
1416 cifs_buf_release(req
);
1421 * Discard any remaining data in the current SMB. To do this, we borrow the
1425 discard_remaining_data(struct TCP_Server_Info
*server
)
1427 unsigned int rfclen
= get_rfc1002_length(server
->smallbuf
);
1428 int remaining
= rfclen
+ 4 - server
->total_read
;
1430 while (remaining
> 0) {
1433 length
= cifs_read_from_socket(server
, server
->bigbuf
,
1434 min_t(unsigned int, remaining
,
1435 CIFSMaxBufSize
+ MAX_HEADER_SIZE(server
)));
1438 server
->total_read
+= length
;
1439 remaining
-= length
;
1446 cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1449 struct cifs_readdata
*rdata
= mid
->callback_data
;
1451 length
= discard_remaining_data(server
);
1452 dequeue_mid(mid
, rdata
->result
);
1453 mid
->resp_buf
= server
->smallbuf
;
1454 server
->smallbuf
= NULL
;
1459 cifs_readv_receive(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1462 unsigned int data_offset
, data_len
;
1463 struct cifs_readdata
*rdata
= mid
->callback_data
;
1464 char *buf
= server
->smallbuf
;
1465 unsigned int buflen
= get_rfc1002_length(buf
) + 4;
1467 cifs_dbg(FYI
, "%s: mid=%llu offset=%llu bytes=%u\n",
1468 __func__
, mid
->mid
, rdata
->offset
, rdata
->bytes
);
1471 * read the rest of READ_RSP header (sans Data array), or whatever we
1472 * can if there's not enough data. At this point, we've read down to
1475 len
= min_t(unsigned int, buflen
, server
->vals
->read_rsp_size
) -
1476 HEADER_SIZE(server
) + 1;
1478 rdata
->iov
.iov_base
= buf
+ HEADER_SIZE(server
) - 1;
1479 rdata
->iov
.iov_len
= len
;
1481 length
= cifs_readv_from_socket(server
, &rdata
->iov
, 1, len
);
1484 server
->total_read
+= length
;
1486 if (server
->ops
->is_session_expired
&&
1487 server
->ops
->is_session_expired(buf
)) {
1488 cifs_reconnect(server
);
1489 wake_up(&server
->response_q
);
1493 if (server
->ops
->is_status_pending
&&
1494 server
->ops
->is_status_pending(buf
, server
, 0)) {
1495 discard_remaining_data(server
);
1499 /* Was the SMB read successful? */
1500 rdata
->result
= server
->ops
->map_error(buf
, false);
1501 if (rdata
->result
!= 0) {
1502 cifs_dbg(FYI
, "%s: server returned error %d\n",
1503 __func__
, rdata
->result
);
1504 return cifs_readv_discard(server
, mid
);
1507 /* Is there enough to get to the rest of the READ_RSP header? */
1508 if (server
->total_read
< server
->vals
->read_rsp_size
) {
1509 cifs_dbg(FYI
, "%s: server returned short header. got=%u expected=%zu\n",
1510 __func__
, server
->total_read
,
1511 server
->vals
->read_rsp_size
);
1512 rdata
->result
= -EIO
;
1513 return cifs_readv_discard(server
, mid
);
1516 data_offset
= server
->ops
->read_data_offset(buf
) + 4;
1517 if (data_offset
< server
->total_read
) {
1519 * win2k8 sometimes sends an offset of 0 when the read
1520 * is beyond the EOF. Treat it as if the data starts just after
1523 cifs_dbg(FYI
, "%s: data offset (%u) inside read response header\n",
1524 __func__
, data_offset
);
1525 data_offset
= server
->total_read
;
1526 } else if (data_offset
> MAX_CIFS_SMALL_BUFFER_SIZE
) {
1527 /* data_offset is beyond the end of smallbuf */
1528 cifs_dbg(FYI
, "%s: data offset (%u) beyond end of smallbuf\n",
1529 __func__
, data_offset
);
1530 rdata
->result
= -EIO
;
1531 return cifs_readv_discard(server
, mid
);
1534 cifs_dbg(FYI
, "%s: total_read=%u data_offset=%u\n",
1535 __func__
, server
->total_read
, data_offset
);
1537 len
= data_offset
- server
->total_read
;
1539 /* read any junk before data into the rest of smallbuf */
1540 rdata
->iov
.iov_base
= buf
+ server
->total_read
;
1541 rdata
->iov
.iov_len
= len
;
1542 length
= cifs_readv_from_socket(server
, &rdata
->iov
, 1, len
);
1545 server
->total_read
+= length
;
1548 /* set up first iov for signature check */
1549 rdata
->iov
.iov_base
= buf
;
1550 rdata
->iov
.iov_len
= server
->total_read
;
1551 cifs_dbg(FYI
, "0: iov_base=%p iov_len=%zu\n",
1552 rdata
->iov
.iov_base
, rdata
->iov
.iov_len
);
1554 /* how much data is in the response? */
1555 data_len
= server
->ops
->read_data_length(buf
);
1556 if (data_offset
+ data_len
> buflen
) {
1557 /* data_len is corrupt -- discard frame */
1558 rdata
->result
= -EIO
;
1559 return cifs_readv_discard(server
, mid
);
1562 length
= rdata
->read_into_pages(server
, rdata
, data_len
);
1566 server
->total_read
+= length
;
1568 cifs_dbg(FYI
, "total_read=%u buflen=%u remaining=%u\n",
1569 server
->total_read
, buflen
, data_len
);
1571 /* discard anything left over */
1572 if (server
->total_read
< buflen
)
1573 return cifs_readv_discard(server
, mid
);
1575 dequeue_mid(mid
, false);
1576 mid
->resp_buf
= server
->smallbuf
;
1577 server
->smallbuf
= NULL
;
1582 cifs_readv_callback(struct mid_q_entry
*mid
)
1584 struct cifs_readdata
*rdata
= mid
->callback_data
;
1585 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1586 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
1587 struct smb_rqst rqst
= { .rq_iov
= &rdata
->iov
,
1589 .rq_pages
= rdata
->pages
,
1590 .rq_npages
= rdata
->nr_pages
,
1591 .rq_pagesz
= rdata
->pagesz
,
1592 .rq_tailsz
= rdata
->tailsz
};
1594 cifs_dbg(FYI
, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1595 __func__
, mid
->mid
, mid
->mid_state
, rdata
->result
,
1598 switch (mid
->mid_state
) {
1599 case MID_RESPONSE_RECEIVED
:
1600 /* result already set, check signature */
1604 rc
= cifs_verify_signature(&rqst
, server
,
1605 mid
->sequence_number
);
1607 cifs_dbg(VFS
, "SMB signature verification returned error = %d\n",
1610 /* FIXME: should this be counted toward the initiating task? */
1611 task_io_account_read(rdata
->got_bytes
);
1612 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1614 case MID_REQUEST_SUBMITTED
:
1615 case MID_RETRY_NEEDED
:
1616 rdata
->result
= -EAGAIN
;
1617 if (server
->sign
&& rdata
->got_bytes
)
1618 /* reset bytes number since we can not check a sign */
1619 rdata
->got_bytes
= 0;
1620 /* FIXME: should this be counted toward the initiating task? */
1621 task_io_account_read(rdata
->got_bytes
);
1622 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1625 rdata
->result
= -EIO
;
1628 queue_work(cifsiod_wq
, &rdata
->work
);
1629 mutex_lock(&server
->srv_mutex
);
1630 DeleteMidQEntry(mid
);
1631 mutex_unlock(&server
->srv_mutex
);
1632 add_credits(server
, 1, 0);
1635 /* cifs_async_readv - send an async write, and set up mid to handle result */
1637 cifs_async_readv(struct cifs_readdata
*rdata
)
1640 READ_REQ
*smb
= NULL
;
1642 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1643 struct smb_rqst rqst
= { .rq_iov
= &rdata
->iov
,
1646 cifs_dbg(FYI
, "%s: offset=%llu bytes=%u\n",
1647 __func__
, rdata
->offset
, rdata
->bytes
);
1649 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1652 wct
= 10; /* old style read */
1653 if ((rdata
->offset
>> 32) > 0) {
1654 /* can not handle this big offset for old */
1659 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **)&smb
);
1663 smb
->hdr
.Pid
= cpu_to_le16((__u16
)rdata
->pid
);
1664 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(rdata
->pid
>> 16));
1666 smb
->AndXCommand
= 0xFF; /* none */
1667 smb
->Fid
= rdata
->cfile
->fid
.netfid
;
1668 smb
->OffsetLow
= cpu_to_le32(rdata
->offset
& 0xFFFFFFFF);
1670 smb
->OffsetHigh
= cpu_to_le32(rdata
->offset
>> 32);
1672 smb
->MaxCount
= cpu_to_le16(rdata
->bytes
& 0xFFFF);
1673 smb
->MaxCountHigh
= cpu_to_le32(rdata
->bytes
>> 16);
1677 /* old style read */
1678 struct smb_com_readx_req
*smbr
=
1679 (struct smb_com_readx_req
*)smb
;
1680 smbr
->ByteCount
= 0;
1683 /* 4 for RFC1001 length + 1 for BCC */
1684 rdata
->iov
.iov_base
= smb
;
1685 rdata
->iov
.iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4;
1687 kref_get(&rdata
->refcount
);
1688 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, cifs_readv_receive
,
1689 cifs_readv_callback
, rdata
, 0);
1692 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1694 kref_put(&rdata
->refcount
, cifs_readdata_release
);
1696 cifs_small_buf_release(smb
);
1701 CIFSSMBRead(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1702 unsigned int *nbytes
, char **buf
, int *pbuf_type
)
1705 READ_REQ
*pSMB
= NULL
;
1706 READ_RSP
*pSMBr
= NULL
;
1707 char *pReadData
= NULL
;
1709 int resp_buf_type
= 0;
1711 __u32 pid
= io_parms
->pid
;
1712 __u16 netfid
= io_parms
->netfid
;
1713 __u64 offset
= io_parms
->offset
;
1714 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1715 unsigned int count
= io_parms
->length
;
1717 cifs_dbg(FYI
, "Reading %d bytes on fid %d\n", count
, netfid
);
1718 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1721 wct
= 10; /* old style read */
1722 if ((offset
>> 32) > 0) {
1723 /* can not handle this big offset for old */
1729 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **) &pSMB
);
1733 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1734 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1736 /* tcon and ses pointer are checked in smb_init */
1737 if (tcon
->ses
->server
== NULL
)
1738 return -ECONNABORTED
;
1740 pSMB
->AndXCommand
= 0xFF; /* none */
1742 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1744 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1746 pSMB
->Remaining
= 0;
1747 pSMB
->MaxCount
= cpu_to_le16(count
& 0xFFFF);
1748 pSMB
->MaxCountHigh
= cpu_to_le32(count
>> 16);
1750 pSMB
->ByteCount
= 0; /* no need to do le conversion since 0 */
1752 /* old style read */
1753 struct smb_com_readx_req
*pSMBW
=
1754 (struct smb_com_readx_req
*)pSMB
;
1755 pSMBW
->ByteCount
= 0;
1758 iov
[0].iov_base
= (char *)pSMB
;
1759 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
1760 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
1761 &resp_buf_type
, CIFS_LOG_ERROR
);
1762 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1763 pSMBr
= (READ_RSP
*)iov
[0].iov_base
;
1765 cifs_dbg(VFS
, "Send error in read = %d\n", rc
);
1767 int data_length
= le16_to_cpu(pSMBr
->DataLengthHigh
);
1768 data_length
= data_length
<< 16;
1769 data_length
+= le16_to_cpu(pSMBr
->DataLength
);
1770 *nbytes
= data_length
;
1772 /*check that DataLength would not go beyond end of SMB */
1773 if ((data_length
> CIFSMaxBufSize
)
1774 || (data_length
> count
)) {
1775 cifs_dbg(FYI
, "bad length %d for count %d\n",
1776 data_length
, count
);
1780 pReadData
= (char *) (&pSMBr
->hdr
.Protocol
) +
1781 le16_to_cpu(pSMBr
->DataOffset
);
1782 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1783 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1785 }*/ /* can not use copy_to_user when using page cache*/
1787 memcpy(*buf
, pReadData
, data_length
);
1791 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1793 free_rsp_buf(resp_buf_type
, iov
[0].iov_base
);
1794 } else if (resp_buf_type
!= CIFS_NO_BUFFER
) {
1795 /* return buffer to caller to free */
1796 *buf
= iov
[0].iov_base
;
1797 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1798 *pbuf_type
= CIFS_SMALL_BUFFER
;
1799 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1800 *pbuf_type
= CIFS_LARGE_BUFFER
;
1801 } /* else no valid buffer on return - leave as null */
1803 /* Note: On -EAGAIN error only caller can retry on handle based calls
1804 since file handle passed in no longer valid */
1810 CIFSSMBWrite(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1811 unsigned int *nbytes
, const char *buf
,
1812 const char __user
*ubuf
, const int long_op
)
1815 WRITE_REQ
*pSMB
= NULL
;
1816 WRITE_RSP
*pSMBr
= NULL
;
1817 int bytes_returned
, wct
;
1820 __u32 pid
= io_parms
->pid
;
1821 __u16 netfid
= io_parms
->netfid
;
1822 __u64 offset
= io_parms
->offset
;
1823 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1824 unsigned int count
= io_parms
->length
;
1828 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1829 if (tcon
->ses
== NULL
)
1830 return -ECONNABORTED
;
1832 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1836 if ((offset
>> 32) > 0) {
1837 /* can not handle big offset for old srv */
1842 rc
= smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
,
1847 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1848 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1850 /* tcon and ses pointer are checked in smb_init */
1851 if (tcon
->ses
->server
== NULL
)
1852 return -ECONNABORTED
;
1854 pSMB
->AndXCommand
= 0xFF; /* none */
1856 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1858 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1860 pSMB
->Reserved
= 0xFFFFFFFF;
1861 pSMB
->WriteMode
= 0;
1862 pSMB
->Remaining
= 0;
1864 /* Can increase buffer size if buffer is big enough in some cases ie we
1865 can send more if LARGE_WRITE_X capability returned by the server and if
1866 our buffer is big enough or if we convert to iovecs on socket writes
1867 and eliminate the copy to the CIFS buffer */
1868 if (tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
) {
1869 bytes_sent
= min_t(const unsigned int, CIFSMaxBufSize
, count
);
1871 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
)
1875 if (bytes_sent
> count
)
1878 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1880 memcpy(pSMB
->Data
, buf
, bytes_sent
);
1882 if (copy_from_user(pSMB
->Data
, ubuf
, bytes_sent
)) {
1883 cifs_buf_release(pSMB
);
1886 } else if (count
!= 0) {
1888 cifs_buf_release(pSMB
);
1890 } /* else setting file size with write of zero bytes */
1892 byte_count
= bytes_sent
+ 1; /* pad */
1893 else /* wct == 12 */
1894 byte_count
= bytes_sent
+ 5; /* bigger pad, smaller smb hdr */
1896 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
& 0xFFFF);
1897 pSMB
->DataLengthHigh
= cpu_to_le16(bytes_sent
>> 16);
1898 inc_rfc1001_len(pSMB
, byte_count
);
1901 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1902 else { /* old style write has byte count 4 bytes earlier
1904 struct smb_com_writex_req
*pSMBW
=
1905 (struct smb_com_writex_req
*)pSMB
;
1906 pSMBW
->ByteCount
= cpu_to_le16(byte_count
);
1909 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1910 (struct smb_hdr
*) pSMBr
, &bytes_returned
, long_op
);
1911 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
1913 cifs_dbg(FYI
, "Send error in write = %d\n", rc
);
1915 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
1916 *nbytes
= (*nbytes
) << 16;
1917 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
1920 * Mask off high 16 bits when bytes written as returned by the
1921 * server is greater than bytes requested by the client. Some
1922 * OS/2 servers are known to set incorrect CountHigh values.
1924 if (*nbytes
> count
)
1928 cifs_buf_release(pSMB
);
1930 /* Note: On -EAGAIN error only caller can retry on handle based calls
1931 since file handle passed in no longer valid */
1937 cifs_writedata_release(struct kref
*refcount
)
1939 struct cifs_writedata
*wdata
= container_of(refcount
,
1940 struct cifs_writedata
, refcount
);
1943 cifsFileInfo_put(wdata
->cfile
);
1949 * Write failed with a retryable error. Resend the write request. It's also
1950 * possible that the page was redirtied so re-clean the page.
1953 cifs_writev_requeue(struct cifs_writedata
*wdata
)
1956 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
1957 struct TCP_Server_Info
*server
;
1958 unsigned int rest_len
;
1960 server
= tlink_tcon(wdata
->cfile
->tlink
)->ses
->server
;
1962 rest_len
= wdata
->bytes
;
1964 struct cifs_writedata
*wdata2
;
1965 unsigned int j
, nr_pages
, wsize
, tailsz
, cur_len
;
1967 wsize
= server
->ops
->wp_retry_size(inode
);
1968 if (wsize
< rest_len
) {
1969 nr_pages
= wsize
/ PAGE_CACHE_SIZE
;
1974 cur_len
= nr_pages
* PAGE_CACHE_SIZE
;
1975 tailsz
= PAGE_CACHE_SIZE
;
1977 nr_pages
= DIV_ROUND_UP(rest_len
, PAGE_CACHE_SIZE
);
1979 tailsz
= rest_len
- (nr_pages
- 1) * PAGE_CACHE_SIZE
;
1982 wdata2
= cifs_writedata_alloc(nr_pages
, cifs_writev_complete
);
1988 for (j
= 0; j
< nr_pages
; j
++) {
1989 wdata2
->pages
[j
] = wdata
->pages
[i
+ j
];
1990 lock_page(wdata2
->pages
[j
]);
1991 clear_page_dirty_for_io(wdata2
->pages
[j
]);
1994 wdata2
->sync_mode
= wdata
->sync_mode
;
1995 wdata2
->nr_pages
= nr_pages
;
1996 wdata2
->offset
= page_offset(wdata2
->pages
[0]);
1997 wdata2
->pagesz
= PAGE_CACHE_SIZE
;
1998 wdata2
->tailsz
= tailsz
;
1999 wdata2
->bytes
= cur_len
;
2001 wdata2
->cfile
= find_writable_file(CIFS_I(inode
), false);
2002 if (!wdata2
->cfile
) {
2003 cifs_dbg(VFS
, "No writable handles for inode\n");
2007 wdata2
->pid
= wdata2
->cfile
->pid
;
2008 rc
= server
->ops
->async_writev(wdata2
, cifs_writedata_release
);
2010 for (j
= 0; j
< nr_pages
; j
++) {
2011 unlock_page(wdata2
->pages
[j
]);
2012 if (rc
!= 0 && rc
!= -EAGAIN
) {
2013 SetPageError(wdata2
->pages
[j
]);
2014 end_page_writeback(wdata2
->pages
[j
]);
2015 page_cache_release(wdata2
->pages
[j
]);
2020 kref_put(&wdata2
->refcount
, cifs_writedata_release
);
2026 rest_len
-= cur_len
;
2028 } while (i
< wdata
->nr_pages
);
2030 mapping_set_error(inode
->i_mapping
, rc
);
2031 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2035 cifs_writev_complete(struct work_struct
*work
)
2037 struct cifs_writedata
*wdata
= container_of(work
,
2038 struct cifs_writedata
, work
);
2039 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
2042 if (wdata
->result
== 0) {
2043 spin_lock(&inode
->i_lock
);
2044 cifs_update_eof(CIFS_I(inode
), wdata
->offset
, wdata
->bytes
);
2045 spin_unlock(&inode
->i_lock
);
2046 cifs_stats_bytes_written(tlink_tcon(wdata
->cfile
->tlink
),
2048 } else if (wdata
->sync_mode
== WB_SYNC_ALL
&& wdata
->result
== -EAGAIN
)
2049 return cifs_writev_requeue(wdata
);
2051 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
2052 struct page
*page
= wdata
->pages
[i
];
2053 if (wdata
->result
== -EAGAIN
)
2054 __set_page_dirty_nobuffers(page
);
2055 else if (wdata
->result
< 0)
2057 end_page_writeback(page
);
2058 page_cache_release(page
);
2060 if (wdata
->result
!= -EAGAIN
)
2061 mapping_set_error(inode
->i_mapping
, wdata
->result
);
2062 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2065 struct cifs_writedata
*
2066 cifs_writedata_alloc(unsigned int nr_pages
, work_func_t complete
)
2068 struct cifs_writedata
*wdata
;
2070 /* writedata + number of page pointers */
2071 wdata
= kzalloc(sizeof(*wdata
) +
2072 sizeof(struct page
*) * nr_pages
, GFP_NOFS
);
2073 if (wdata
!= NULL
) {
2074 kref_init(&wdata
->refcount
);
2075 INIT_LIST_HEAD(&wdata
->list
);
2076 init_completion(&wdata
->done
);
2077 INIT_WORK(&wdata
->work
, complete
);
2083 * Check the mid_state and signature on received buffer (if any), and queue the
2084 * workqueue completion task.
2087 cifs_writev_callback(struct mid_q_entry
*mid
)
2089 struct cifs_writedata
*wdata
= mid
->callback_data
;
2090 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2091 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
2092 unsigned int written
;
2093 WRITE_RSP
*smb
= (WRITE_RSP
*)mid
->resp_buf
;
2095 switch (mid
->mid_state
) {
2096 case MID_RESPONSE_RECEIVED
:
2097 wdata
->result
= cifs_check_receive(mid
, tcon
->ses
->server
, 0);
2098 if (wdata
->result
!= 0)
2101 written
= le16_to_cpu(smb
->CountHigh
);
2103 written
+= le16_to_cpu(smb
->Count
);
2105 * Mask off high 16 bits when bytes written as returned
2106 * by the server is greater than bytes requested by the
2107 * client. OS/2 servers are known to set incorrect
2110 if (written
> wdata
->bytes
)
2113 if (written
< wdata
->bytes
)
2114 wdata
->result
= -ENOSPC
;
2116 wdata
->bytes
= written
;
2118 case MID_REQUEST_SUBMITTED
:
2119 case MID_RETRY_NEEDED
:
2120 wdata
->result
= -EAGAIN
;
2123 wdata
->result
= -EIO
;
2127 queue_work(cifsiod_wq
, &wdata
->work
);
2128 mutex_lock(&server
->srv_mutex
);
2129 DeleteMidQEntry(mid
);
2130 mutex_unlock(&server
->srv_mutex
);
2131 add_credits(tcon
->ses
->server
, 1, 0);
2134 /* cifs_async_writev - send an async write, and set up mid to handle result */
2136 cifs_async_writev(struct cifs_writedata
*wdata
,
2137 void (*release
)(struct kref
*kref
))
2140 WRITE_REQ
*smb
= NULL
;
2142 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2144 struct smb_rqst rqst
= { };
2146 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2150 if (wdata
->offset
>> 32 > 0) {
2151 /* can not handle big offset for old srv */
2156 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **)&smb
);
2158 goto async_writev_out
;
2160 smb
->hdr
.Pid
= cpu_to_le16((__u16
)wdata
->pid
);
2161 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(wdata
->pid
>> 16));
2163 smb
->AndXCommand
= 0xFF; /* none */
2164 smb
->Fid
= wdata
->cfile
->fid
.netfid
;
2165 smb
->OffsetLow
= cpu_to_le32(wdata
->offset
& 0xFFFFFFFF);
2167 smb
->OffsetHigh
= cpu_to_le32(wdata
->offset
>> 32);
2168 smb
->Reserved
= 0xFFFFFFFF;
2173 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2175 /* 4 for RFC1001 length + 1 for BCC */
2176 iov
.iov_len
= be32_to_cpu(smb
->hdr
.smb_buf_length
) + 4 + 1;
2181 rqst
.rq_pages
= wdata
->pages
;
2182 rqst
.rq_npages
= wdata
->nr_pages
;
2183 rqst
.rq_pagesz
= wdata
->pagesz
;
2184 rqst
.rq_tailsz
= wdata
->tailsz
;
2186 cifs_dbg(FYI
, "async write at %llu %u bytes\n",
2187 wdata
->offset
, wdata
->bytes
);
2189 smb
->DataLengthLow
= cpu_to_le16(wdata
->bytes
& 0xFFFF);
2190 smb
->DataLengthHigh
= cpu_to_le16(wdata
->bytes
>> 16);
2193 inc_rfc1001_len(&smb
->hdr
, wdata
->bytes
+ 1);
2194 put_bcc(wdata
->bytes
+ 1, &smb
->hdr
);
2197 struct smb_com_writex_req
*smbw
=
2198 (struct smb_com_writex_req
*)smb
;
2199 inc_rfc1001_len(&smbw
->hdr
, wdata
->bytes
+ 5);
2200 put_bcc(wdata
->bytes
+ 5, &smbw
->hdr
);
2201 iov
.iov_len
+= 4; /* pad bigger by four bytes */
2204 kref_get(&wdata
->refcount
);
2205 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, NULL
,
2206 cifs_writev_callback
, wdata
, 0);
2209 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2211 kref_put(&wdata
->refcount
, release
);
2214 cifs_small_buf_release(smb
);
2219 CIFSSMBWrite2(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
2220 unsigned int *nbytes
, struct kvec
*iov
, int n_vec
)
2223 WRITE_REQ
*pSMB
= NULL
;
2226 int resp_buf_type
= 0;
2227 __u32 pid
= io_parms
->pid
;
2228 __u16 netfid
= io_parms
->netfid
;
2229 __u64 offset
= io_parms
->offset
;
2230 struct cifs_tcon
*tcon
= io_parms
->tcon
;
2231 unsigned int count
= io_parms
->length
;
2235 cifs_dbg(FYI
, "write2 at %lld %d bytes\n", (long long)offset
, count
);
2237 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2241 if ((offset
>> 32) > 0) {
2242 /* can not handle big offset for old srv */
2246 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
);
2250 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
2251 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
2253 /* tcon and ses pointer are checked in smb_init */
2254 if (tcon
->ses
->server
== NULL
)
2255 return -ECONNABORTED
;
2257 pSMB
->AndXCommand
= 0xFF; /* none */
2259 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
2261 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
2262 pSMB
->Reserved
= 0xFFFFFFFF;
2263 pSMB
->WriteMode
= 0;
2264 pSMB
->Remaining
= 0;
2267 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2269 pSMB
->DataLengthLow
= cpu_to_le16(count
& 0xFFFF);
2270 pSMB
->DataLengthHigh
= cpu_to_le16(count
>> 16);
2271 /* header + 1 byte pad */
2272 smb_hdr_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 1;
2274 inc_rfc1001_len(pSMB
, count
+ 1);
2275 else /* wct == 12 */
2276 inc_rfc1001_len(pSMB
, count
+ 5); /* smb data starts later */
2278 pSMB
->ByteCount
= cpu_to_le16(count
+ 1);
2279 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2280 struct smb_com_writex_req
*pSMBW
=
2281 (struct smb_com_writex_req
*)pSMB
;
2282 pSMBW
->ByteCount
= cpu_to_le16(count
+ 5);
2284 iov
[0].iov_base
= pSMB
;
2286 iov
[0].iov_len
= smb_hdr_len
+ 4;
2287 else /* wct == 12 pad bigger by four bytes */
2288 iov
[0].iov_len
= smb_hdr_len
+ 8;
2291 rc
= SendReceive2(xid
, tcon
->ses
, iov
, n_vec
+ 1, &resp_buf_type
, 0);
2292 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2294 cifs_dbg(FYI
, "Send error Write2 = %d\n", rc
);
2295 } else if (resp_buf_type
== 0) {
2296 /* presumably this can not happen, but best to be safe */
2299 WRITE_RSP
*pSMBr
= (WRITE_RSP
*)iov
[0].iov_base
;
2300 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2301 *nbytes
= (*nbytes
) << 16;
2302 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2305 * Mask off high 16 bits when bytes written as returned by the
2306 * server is greater than bytes requested by the client. OS/2
2307 * servers are known to set incorrect CountHigh values.
2309 if (*nbytes
> count
)
2313 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2314 free_rsp_buf(resp_buf_type
, iov
[0].iov_base
);
2316 /* Note: On -EAGAIN error only caller can retry on handle based calls
2317 since file handle passed in no longer valid */
2322 int cifs_lockv(const unsigned int xid
, struct cifs_tcon
*tcon
,
2323 const __u16 netfid
, const __u8 lock_type
, const __u32 num_unlock
,
2324 const __u32 num_lock
, LOCKING_ANDX_RANGE
*buf
)
2327 LOCK_REQ
*pSMB
= NULL
;
2332 cifs_dbg(FYI
, "cifs_lockv num lock %d num unlock %d\n",
2333 num_lock
, num_unlock
);
2335 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2340 pSMB
->NumberOfLocks
= cpu_to_le16(num_lock
);
2341 pSMB
->NumberOfUnlocks
= cpu_to_le16(num_unlock
);
2342 pSMB
->LockType
= lock_type
;
2343 pSMB
->AndXCommand
= 0xFF; /* none */
2344 pSMB
->Fid
= netfid
; /* netfid stays le */
2346 count
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2347 inc_rfc1001_len(pSMB
, count
);
2348 pSMB
->ByteCount
= cpu_to_le16(count
);
2350 iov
[0].iov_base
= (char *)pSMB
;
2351 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4 -
2352 (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2353 iov
[1].iov_base
= (char *)buf
;
2354 iov
[1].iov_len
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2356 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2357 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 2, &resp_buf_type
, CIFS_NO_RESP
);
2359 cifs_dbg(FYI
, "Send error in cifs_lockv = %d\n", rc
);
2365 CIFSSMBLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2366 const __u16 smb_file_id
, const __u32 netpid
, const __u64 len
,
2367 const __u64 offset
, const __u32 numUnlock
,
2368 const __u32 numLock
, const __u8 lockType
,
2369 const bool waitFlag
, const __u8 oplock_level
)
2372 LOCK_REQ
*pSMB
= NULL
;
2373 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2378 cifs_dbg(FYI
, "CIFSSMBLock timeout %d numLock %d\n",
2379 (int)waitFlag
, numLock
);
2380 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2385 if (lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
2386 /* no response expected */
2387 flags
= CIFS_ASYNC_OP
| CIFS_OBREAK_OP
;
2389 } else if (waitFlag
) {
2390 flags
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2391 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
2396 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
2397 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
2398 pSMB
->LockType
= lockType
;
2399 pSMB
->OplockLevel
= oplock_level
;
2400 pSMB
->AndXCommand
= 0xFF; /* none */
2401 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
2403 if ((numLock
!= 0) || (numUnlock
!= 0)) {
2404 pSMB
->Locks
[0].Pid
= cpu_to_le16(netpid
);
2405 /* BB where to store pid high? */
2406 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
2407 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
2408 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
2409 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
2410 count
= sizeof(LOCKING_ANDX_RANGE
);
2415 inc_rfc1001_len(pSMB
, count
);
2416 pSMB
->ByteCount
= cpu_to_le16(count
);
2419 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2420 (struct smb_hdr
*) pSMB
, &bytes_returned
);
2421 cifs_small_buf_release(pSMB
);
2423 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)pSMB
, flags
);
2424 /* SMB buffer freed by function above */
2426 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2428 cifs_dbg(FYI
, "Send error in Lock = %d\n", rc
);
2430 /* Note: On -EAGAIN error only caller can retry on handle based calls
2431 since file handle passed in no longer valid */
2436 CIFSSMBPosixLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2437 const __u16 smb_file_id
, const __u32 netpid
,
2438 const loff_t start_offset
, const __u64 len
,
2439 struct file_lock
*pLockData
, const __u16 lock_type
,
2440 const bool waitFlag
)
2442 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2443 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2444 struct cifs_posix_lock
*parm_data
;
2447 int bytes_returned
= 0;
2448 int resp_buf_type
= 0;
2449 __u16 params
, param_offset
, offset
, byte_count
, count
;
2452 cifs_dbg(FYI
, "Posix Lock\n");
2454 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
2459 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)pSMB
;
2462 pSMB
->MaxSetupCount
= 0;
2465 pSMB
->Reserved2
= 0;
2466 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2467 offset
= param_offset
+ params
;
2469 count
= sizeof(struct cifs_posix_lock
);
2470 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2471 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2472 pSMB
->SetupCount
= 1;
2473 pSMB
->Reserved3
= 0;
2475 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
2477 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2478 byte_count
= 3 /* pad */ + params
+ count
;
2479 pSMB
->DataCount
= cpu_to_le16(count
);
2480 pSMB
->ParameterCount
= cpu_to_le16(params
);
2481 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2482 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2483 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2484 parm_data
= (struct cifs_posix_lock
*)
2485 (((char *) &pSMB
->hdr
.Protocol
) + offset
);
2487 parm_data
->lock_type
= cpu_to_le16(lock_type
);
2489 timeout
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2490 parm_data
->lock_flags
= cpu_to_le16(1);
2491 pSMB
->Timeout
= cpu_to_le32(-1);
2495 parm_data
->pid
= cpu_to_le32(netpid
);
2496 parm_data
->start
= cpu_to_le64(start_offset
);
2497 parm_data
->length
= cpu_to_le64(len
); /* normalize negative numbers */
2499 pSMB
->DataOffset
= cpu_to_le16(offset
);
2500 pSMB
->Fid
= smb_file_id
;
2501 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_LOCK
);
2502 pSMB
->Reserved4
= 0;
2503 inc_rfc1001_len(pSMB
, byte_count
);
2504 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2506 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2507 (struct smb_hdr
*) pSMBr
, &bytes_returned
);
2509 iov
[0].iov_base
= (char *)pSMB
;
2510 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
2511 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
2512 &resp_buf_type
, timeout
);
2513 pSMB
= NULL
; /* request buf already freed by SendReceive2. Do
2514 not try to free it twice below on exit */
2515 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)iov
[0].iov_base
;
2519 cifs_dbg(FYI
, "Send error in Posix Lock = %d\n", rc
);
2520 } else if (pLockData
) {
2521 /* lock structure can be returned on get */
2524 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2526 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(*parm_data
)) {
2527 rc
= -EIO
; /* bad smb */
2530 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
2531 data_count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2532 if (data_count
< sizeof(struct cifs_posix_lock
)) {
2536 parm_data
= (struct cifs_posix_lock
*)
2537 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2538 if (parm_data
->lock_type
== cpu_to_le16(CIFS_UNLCK
))
2539 pLockData
->fl_type
= F_UNLCK
;
2541 if (parm_data
->lock_type
==
2542 cpu_to_le16(CIFS_RDLCK
))
2543 pLockData
->fl_type
= F_RDLCK
;
2544 else if (parm_data
->lock_type
==
2545 cpu_to_le16(CIFS_WRLCK
))
2546 pLockData
->fl_type
= F_WRLCK
;
2548 pLockData
->fl_start
= le64_to_cpu(parm_data
->start
);
2549 pLockData
->fl_end
= pLockData
->fl_start
+
2550 le64_to_cpu(parm_data
->length
) - 1;
2551 pLockData
->fl_pid
= le32_to_cpu(parm_data
->pid
);
2557 cifs_small_buf_release(pSMB
);
2559 free_rsp_buf(resp_buf_type
, iov
[0].iov_base
);
2561 /* Note: On -EAGAIN error only caller can retry on handle based calls
2562 since file handle passed in no longer valid */
2569 CIFSSMBClose(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2572 CLOSE_REQ
*pSMB
= NULL
;
2573 cifs_dbg(FYI
, "In CIFSSMBClose\n");
2575 /* do not retry on dead session on close */
2576 rc
= small_smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
);
2582 pSMB
->FileID
= (__u16
) smb_file_id
;
2583 pSMB
->LastWriteTime
= 0xFFFFFFFF;
2584 pSMB
->ByteCount
= 0;
2585 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2586 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_closes
);
2589 /* EINTR is expected when user ctl-c to kill app */
2590 cifs_dbg(VFS
, "Send error in Close = %d\n", rc
);
2594 /* Since session is dead, file will be closed on server already */
2602 CIFSSMBFlush(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2605 FLUSH_REQ
*pSMB
= NULL
;
2606 cifs_dbg(FYI
, "In CIFSSMBFlush\n");
2608 rc
= small_smb_init(SMB_COM_FLUSH
, 1, tcon
, (void **) &pSMB
);
2612 pSMB
->FileID
= (__u16
) smb_file_id
;
2613 pSMB
->ByteCount
= 0;
2614 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2615 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_flushes
);
2617 cifs_dbg(VFS
, "Send error in Flush = %d\n", rc
);
2623 CIFSSMBRename(const unsigned int xid
, struct cifs_tcon
*tcon
,
2624 const char *from_name
, const char *to_name
,
2625 struct cifs_sb_info
*cifs_sb
)
2628 RENAME_REQ
*pSMB
= NULL
;
2629 RENAME_RSP
*pSMBr
= NULL
;
2631 int name_len
, name_len2
;
2633 int remap
= cifs_remap(cifs_sb
);
2635 cifs_dbg(FYI
, "In CIFSSMBRename\n");
2637 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
2642 pSMB
->BufferFormat
= 0x04;
2643 pSMB
->SearchAttributes
=
2644 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2647 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2648 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2649 from_name
, PATH_MAX
,
2650 cifs_sb
->local_nls
, remap
);
2651 name_len
++; /* trailing null */
2653 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2654 /* protocol requires ASCII signature byte on Unicode string */
2655 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2657 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2658 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2660 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2661 name_len2
*= 2; /* convert to bytes */
2662 } else { /* BB improve the check for buffer overruns BB */
2663 name_len
= strnlen(from_name
, PATH_MAX
);
2664 name_len
++; /* trailing null */
2665 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
2666 name_len2
= strnlen(to_name
, PATH_MAX
);
2667 name_len2
++; /* trailing null */
2668 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2669 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
2670 name_len2
++; /* trailing null */
2671 name_len2
++; /* signature byte */
2674 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2675 inc_rfc1001_len(pSMB
, count
);
2676 pSMB
->ByteCount
= cpu_to_le16(count
);
2678 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2679 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2680 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_renames
);
2682 cifs_dbg(FYI
, "Send error in rename = %d\n", rc
);
2684 cifs_buf_release(pSMB
);
2692 int CIFSSMBRenameOpenFile(const unsigned int xid
, struct cifs_tcon
*pTcon
,
2693 int netfid
, const char *target_name
,
2694 const struct nls_table
*nls_codepage
, int remap
)
2696 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2697 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2698 struct set_file_rename
*rename_info
;
2700 char dummy_string
[30];
2702 int bytes_returned
= 0;
2704 __u16 params
, param_offset
, offset
, count
, byte_count
;
2706 cifs_dbg(FYI
, "Rename to File by handle\n");
2707 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
2713 pSMB
->MaxSetupCount
= 0;
2717 pSMB
->Reserved2
= 0;
2718 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2719 offset
= param_offset
+ params
;
2721 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2722 rename_info
= (struct set_file_rename
*) data_offset
;
2723 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2724 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2725 pSMB
->SetupCount
= 1;
2726 pSMB
->Reserved3
= 0;
2727 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2728 byte_count
= 3 /* pad */ + params
;
2729 pSMB
->ParameterCount
= cpu_to_le16(params
);
2730 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2731 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2732 pSMB
->DataOffset
= cpu_to_le16(offset
);
2733 /* construct random name ".cifs_tmp<inodenum><mid>" */
2734 rename_info
->overwrite
= cpu_to_le32(1);
2735 rename_info
->root_fid
= 0;
2736 /* unicode only call */
2737 if (target_name
== NULL
) {
2738 sprintf(dummy_string
, "cifs%x", pSMB
->hdr
.Mid
);
2740 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2741 dummy_string
, 24, nls_codepage
, remap
);
2744 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2745 target_name
, PATH_MAX
, nls_codepage
,
2748 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
2749 count
= 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str
);
2750 byte_count
+= count
;
2751 pSMB
->DataCount
= cpu_to_le16(count
);
2752 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2754 pSMB
->InformationLevel
=
2755 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
2756 pSMB
->Reserved4
= 0;
2757 inc_rfc1001_len(pSMB
, byte_count
);
2758 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2759 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
2760 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2761 cifs_stats_inc(&pTcon
->stats
.cifs_stats
.num_t2renames
);
2763 cifs_dbg(FYI
, "Send error in Rename (by file handle) = %d\n",
2766 cifs_buf_release(pSMB
);
2768 /* Note: On -EAGAIN error only caller can retry on handle based calls
2769 since file handle passed in no longer valid */
2775 CIFSSMBCopy(const unsigned int xid
, struct cifs_tcon
*tcon
,
2776 const char *fromName
, const __u16 target_tid
, const char *toName
,
2777 const int flags
, const struct nls_table
*nls_codepage
, int remap
)
2780 COPY_REQ
*pSMB
= NULL
;
2781 COPY_RSP
*pSMBr
= NULL
;
2783 int name_len
, name_len2
;
2786 cifs_dbg(FYI
, "In CIFSSMBCopy\n");
2788 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
2793 pSMB
->BufferFormat
= 0x04;
2794 pSMB
->Tid2
= target_tid
;
2796 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
2798 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2799 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2800 fromName
, PATH_MAX
, nls_codepage
,
2802 name_len
++; /* trailing null */
2804 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2805 /* protocol requires ASCII signature byte on Unicode string */
2806 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2808 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2809 toName
, PATH_MAX
, nls_codepage
, remap
);
2810 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2811 name_len2
*= 2; /* convert to bytes */
2812 } else { /* BB improve the check for buffer overruns BB */
2813 name_len
= strnlen(fromName
, PATH_MAX
);
2814 name_len
++; /* trailing null */
2815 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
2816 name_len2
= strnlen(toName
, PATH_MAX
);
2817 name_len2
++; /* trailing null */
2818 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2819 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
2820 name_len2
++; /* trailing null */
2821 name_len2
++; /* signature byte */
2824 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2825 inc_rfc1001_len(pSMB
, count
);
2826 pSMB
->ByteCount
= cpu_to_le16(count
);
2828 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2829 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2831 cifs_dbg(FYI
, "Send error in copy = %d with %d files copied\n",
2832 rc
, le16_to_cpu(pSMBr
->CopyCount
));
2834 cifs_buf_release(pSMB
);
2843 CIFSUnixCreateSymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2844 const char *fromName
, const char *toName
,
2845 const struct nls_table
*nls_codepage
, int remap
)
2847 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2848 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2851 int name_len_target
;
2853 int bytes_returned
= 0;
2854 __u16 params
, param_offset
, offset
, byte_count
;
2856 cifs_dbg(FYI
, "In Symlink Unix style\n");
2858 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2863 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2865 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fromName
,
2866 /* find define for this maxpathcomponent */
2867 PATH_MAX
, nls_codepage
, remap
);
2868 name_len
++; /* trailing null */
2871 } else { /* BB improve the check for buffer overruns BB */
2872 name_len
= strnlen(fromName
, PATH_MAX
);
2873 name_len
++; /* trailing null */
2874 strncpy(pSMB
->FileName
, fromName
, name_len
);
2876 params
= 6 + name_len
;
2877 pSMB
->MaxSetupCount
= 0;
2881 pSMB
->Reserved2
= 0;
2882 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2883 InformationLevel
) - 4;
2884 offset
= param_offset
+ params
;
2886 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2887 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2889 cifsConvertToUTF16((__le16
*) data_offset
, toName
,
2890 /* find define for this maxpathcomponent */
2891 PATH_MAX
, nls_codepage
, remap
);
2892 name_len_target
++; /* trailing null */
2893 name_len_target
*= 2;
2894 } else { /* BB improve the check for buffer overruns BB */
2895 name_len_target
= strnlen(toName
, PATH_MAX
);
2896 name_len_target
++; /* trailing null */
2897 strncpy(data_offset
, toName
, name_len_target
);
2900 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2901 /* BB find exact max on data count below from sess */
2902 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2903 pSMB
->SetupCount
= 1;
2904 pSMB
->Reserved3
= 0;
2905 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2906 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2907 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2908 pSMB
->ParameterCount
= cpu_to_le16(params
);
2909 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2910 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2911 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2912 pSMB
->DataOffset
= cpu_to_le16(offset
);
2913 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
2914 pSMB
->Reserved4
= 0;
2915 inc_rfc1001_len(pSMB
, byte_count
);
2916 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2917 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2918 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2919 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_symlinks
);
2921 cifs_dbg(FYI
, "Send error in SetPathInfo create symlink = %d\n",
2924 cifs_buf_release(pSMB
);
2927 goto createSymLinkRetry
;
2933 CIFSUnixCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2934 const char *fromName
, const char *toName
,
2935 const struct nls_table
*nls_codepage
, int remap
)
2937 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2938 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2941 int name_len_target
;
2943 int bytes_returned
= 0;
2944 __u16 params
, param_offset
, offset
, byte_count
;
2946 cifs_dbg(FYI
, "In Create Hard link Unix style\n");
2947 createHardLinkRetry
:
2948 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2953 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2954 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->FileName
, toName
,
2955 PATH_MAX
, nls_codepage
, remap
);
2956 name_len
++; /* trailing null */
2959 } else { /* BB improve the check for buffer overruns BB */
2960 name_len
= strnlen(toName
, PATH_MAX
);
2961 name_len
++; /* trailing null */
2962 strncpy(pSMB
->FileName
, toName
, name_len
);
2964 params
= 6 + name_len
;
2965 pSMB
->MaxSetupCount
= 0;
2969 pSMB
->Reserved2
= 0;
2970 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2971 InformationLevel
) - 4;
2972 offset
= param_offset
+ params
;
2974 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2975 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2977 cifsConvertToUTF16((__le16
*) data_offset
, fromName
,
2978 PATH_MAX
, nls_codepage
, remap
);
2979 name_len_target
++; /* trailing null */
2980 name_len_target
*= 2;
2981 } else { /* BB improve the check for buffer overruns BB */
2982 name_len_target
= strnlen(fromName
, PATH_MAX
);
2983 name_len_target
++; /* trailing null */
2984 strncpy(data_offset
, fromName
, name_len_target
);
2987 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2988 /* BB find exact max on data count below from sess*/
2989 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2990 pSMB
->SetupCount
= 1;
2991 pSMB
->Reserved3
= 0;
2992 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2993 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2994 pSMB
->ParameterCount
= cpu_to_le16(params
);
2995 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2996 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2997 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2998 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2999 pSMB
->DataOffset
= cpu_to_le16(offset
);
3000 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
3001 pSMB
->Reserved4
= 0;
3002 inc_rfc1001_len(pSMB
, byte_count
);
3003 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3004 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3005 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3006 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3008 cifs_dbg(FYI
, "Send error in SetPathInfo (hard link) = %d\n",
3011 cifs_buf_release(pSMB
);
3013 goto createHardLinkRetry
;
3019 CIFSCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3020 const char *from_name
, const char *to_name
,
3021 struct cifs_sb_info
*cifs_sb
)
3024 NT_RENAME_REQ
*pSMB
= NULL
;
3025 RENAME_RSP
*pSMBr
= NULL
;
3027 int name_len
, name_len2
;
3029 int remap
= cifs_remap(cifs_sb
);
3031 cifs_dbg(FYI
, "In CIFSCreateHardLink\n");
3032 winCreateHardLinkRetry
:
3034 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
3039 pSMB
->SearchAttributes
=
3040 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
3042 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
3043 pSMB
->ClusterCount
= 0;
3045 pSMB
->BufferFormat
= 0x04;
3047 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3049 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, from_name
,
3050 PATH_MAX
, cifs_sb
->local_nls
, remap
);
3051 name_len
++; /* trailing null */
3054 /* protocol specifies ASCII buffer format (0x04) for unicode */
3055 pSMB
->OldFileName
[name_len
] = 0x04;
3056 pSMB
->OldFileName
[name_len
+ 1] = 0x00; /* pad */
3058 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
3059 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
3061 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
3062 name_len2
*= 2; /* convert to bytes */
3063 } else { /* BB improve the check for buffer overruns BB */
3064 name_len
= strnlen(from_name
, PATH_MAX
);
3065 name_len
++; /* trailing null */
3066 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
3067 name_len2
= strnlen(to_name
, PATH_MAX
);
3068 name_len2
++; /* trailing null */
3069 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
3070 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
3071 name_len2
++; /* trailing null */
3072 name_len2
++; /* signature byte */
3075 count
= 1 /* string type byte */ + name_len
+ name_len2
;
3076 inc_rfc1001_len(pSMB
, count
);
3077 pSMB
->ByteCount
= cpu_to_le16(count
);
3079 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3080 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3081 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3083 cifs_dbg(FYI
, "Send error in hard link (NT rename) = %d\n", rc
);
3085 cifs_buf_release(pSMB
);
3087 goto winCreateHardLinkRetry
;
3093 CIFSSMBUnixQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3094 const unsigned char *searchName
, char **symlinkinfo
,
3095 const struct nls_table
*nls_codepage
, int remap
)
3097 /* SMB_QUERY_FILE_UNIX_LINK */
3098 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3099 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3103 __u16 params
, byte_count
;
3106 cifs_dbg(FYI
, "In QPathSymLinkInfo (Unix) for path %s\n", searchName
);
3109 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3114 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3116 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3117 searchName
, PATH_MAX
, nls_codepage
,
3119 name_len
++; /* trailing null */
3121 } else { /* BB improve the check for buffer overruns BB */
3122 name_len
= strnlen(searchName
, PATH_MAX
);
3123 name_len
++; /* trailing null */
3124 strncpy(pSMB
->FileName
, searchName
, name_len
);
3127 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3128 pSMB
->TotalDataCount
= 0;
3129 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3130 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3131 pSMB
->MaxSetupCount
= 0;
3135 pSMB
->Reserved2
= 0;
3136 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3137 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3138 pSMB
->DataCount
= 0;
3139 pSMB
->DataOffset
= 0;
3140 pSMB
->SetupCount
= 1;
3141 pSMB
->Reserved3
= 0;
3142 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3143 byte_count
= params
+ 1 /* pad */ ;
3144 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3145 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3146 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
3147 pSMB
->Reserved4
= 0;
3148 inc_rfc1001_len(pSMB
, byte_count
);
3149 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3151 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3152 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3154 cifs_dbg(FYI
, "Send error in QuerySymLinkInfo = %d\n", rc
);
3156 /* decode response */
3158 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3159 /* BB also check enough total bytes returned */
3160 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3164 u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3166 data_start
= ((char *) &pSMBr
->hdr
.Protocol
) +
3167 le16_to_cpu(pSMBr
->t2
.DataOffset
);
3169 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3174 /* BB FIXME investigate remapping reserved chars here */
3175 *symlinkinfo
= cifs_strndup_from_utf16(data_start
,
3176 count
, is_unicode
, nls_codepage
);
3181 cifs_buf_release(pSMB
);
3183 goto querySymLinkRetry
;
3188 * Recent Windows versions now create symlinks more frequently
3189 * and they use the "reparse point" mechanism below. We can of course
3190 * do symlinks nicely to Samba and other servers which support the
3191 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3192 * "MF" symlinks optionally, but for recent Windows we really need to
3193 * reenable the code below and fix the cifs_symlink callers to handle this.
3194 * In the interim this code has been moved to its own config option so
3195 * it is not compiled in by default until callers fixed up and more tested.
3198 CIFSSMBQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3199 __u16 fid
, char **symlinkinfo
,
3200 const struct nls_table
*nls_codepage
)
3204 struct smb_com_transaction_ioctl_req
*pSMB
;
3205 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3207 unsigned int sub_len
;
3209 struct reparse_symlink_data
*reparse_buf
;
3210 struct reparse_posix_data
*posix_buf
;
3211 __u32 data_offset
, data_count
;
3214 cifs_dbg(FYI
, "In Windows reparse style QueryLink for fid %u\n", fid
);
3215 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3220 pSMB
->TotalParameterCount
= 0 ;
3221 pSMB
->TotalDataCount
= 0;
3222 pSMB
->MaxParameterCount
= cpu_to_le32(2);
3223 /* BB find exact data count max from sess structure BB */
3224 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3225 pSMB
->MaxSetupCount
= 4;
3227 pSMB
->ParameterOffset
= 0;
3228 pSMB
->DataCount
= 0;
3229 pSMB
->DataOffset
= 0;
3230 pSMB
->SetupCount
= 4;
3231 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3232 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3233 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
3234 pSMB
->IsFsctl
= 1; /* FSCTL */
3235 pSMB
->IsRootFlag
= 0;
3236 pSMB
->Fid
= fid
; /* file handle always le */
3237 pSMB
->ByteCount
= 0;
3239 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3240 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3242 cifs_dbg(FYI
, "Send error in QueryReparseLinkInfo = %d\n", rc
);
3246 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3247 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3248 if (get_bcc(&pSMBr
->hdr
) < 2 || data_offset
> 512) {
3249 /* BB also check enough total bytes returned */
3250 rc
= -EIO
; /* bad smb */
3253 if (!data_count
|| (data_count
> 2048)) {
3255 cifs_dbg(FYI
, "Invalid return data count on get reparse info ioctl\n");
3258 end_of_smb
= 2 + get_bcc(&pSMBr
->hdr
) + (char *)&pSMBr
->ByteCount
;
3259 reparse_buf
= (struct reparse_symlink_data
*)
3260 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
3261 if ((char *)reparse_buf
>= end_of_smb
) {
3265 if (reparse_buf
->ReparseTag
== cpu_to_le32(IO_REPARSE_TAG_NFS
)) {
3266 cifs_dbg(FYI
, "NFS style reparse tag\n");
3267 posix_buf
= (struct reparse_posix_data
*)reparse_buf
;
3269 if (posix_buf
->InodeType
!= cpu_to_le64(NFS_SPECFILE_LNK
)) {
3270 cifs_dbg(FYI
, "unsupported file type 0x%llx\n",
3271 le64_to_cpu(posix_buf
->InodeType
));
3276 sub_len
= le16_to_cpu(reparse_buf
->ReparseDataLength
);
3277 if (posix_buf
->PathBuffer
+ sub_len
> end_of_smb
) {
3278 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3282 *symlinkinfo
= cifs_strndup_from_utf16(posix_buf
->PathBuffer
,
3283 sub_len
, is_unicode
, nls_codepage
);
3285 } else if (reparse_buf
->ReparseTag
!=
3286 cpu_to_le32(IO_REPARSE_TAG_SYMLINK
)) {
3291 /* Reparse tag is NTFS symlink */
3292 sub_start
= le16_to_cpu(reparse_buf
->SubstituteNameOffset
) +
3293 reparse_buf
->PathBuffer
;
3294 sub_len
= le16_to_cpu(reparse_buf
->SubstituteNameLength
);
3295 if (sub_start
+ sub_len
> end_of_smb
) {
3296 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3300 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3305 /* BB FIXME investigate remapping reserved chars here */
3306 *symlinkinfo
= cifs_strndup_from_utf16(sub_start
, sub_len
, is_unicode
,
3311 cifs_buf_release(pSMB
);
3314 * Note: On -EAGAIN error only caller can retry on handle based calls
3315 * since file handle passed in no longer valid.
3321 CIFSSMB_set_compression(const unsigned int xid
, struct cifs_tcon
*tcon
,
3326 struct smb_com_transaction_compr_ioctl_req
*pSMB
;
3327 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3329 cifs_dbg(FYI
, "Set compression for %u\n", fid
);
3330 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3335 pSMB
->compression_state
= cpu_to_le16(COMPRESSION_FORMAT_DEFAULT
);
3337 pSMB
->TotalParameterCount
= 0;
3338 pSMB
->TotalDataCount
= cpu_to_le32(2);
3339 pSMB
->MaxParameterCount
= 0;
3340 pSMB
->MaxDataCount
= 0;
3341 pSMB
->MaxSetupCount
= 4;
3343 pSMB
->ParameterOffset
= 0;
3344 pSMB
->DataCount
= cpu_to_le32(2);
3346 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req
,
3347 compression_state
) - 4); /* 84 */
3348 pSMB
->SetupCount
= 4;
3349 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3350 pSMB
->ParameterCount
= 0;
3351 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_SET_COMPRESSION
);
3352 pSMB
->IsFsctl
= 1; /* FSCTL */
3353 pSMB
->IsRootFlag
= 0;
3354 pSMB
->Fid
= fid
; /* file handle always le */
3355 /* 3 byte pad, followed by 2 byte compress state */
3356 pSMB
->ByteCount
= cpu_to_le16(5);
3357 inc_rfc1001_len(pSMB
, 5);
3359 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3360 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3362 cifs_dbg(FYI
, "Send error in SetCompression = %d\n", rc
);
3364 cifs_buf_release(pSMB
);
3367 * Note: On -EAGAIN error only caller can retry on handle based calls
3368 * since file handle passed in no longer valid.
3374 #ifdef CONFIG_CIFS_POSIX
3376 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3377 static void cifs_convert_ace(posix_acl_xattr_entry
*ace
,
3378 struct cifs_posix_ace
*cifs_ace
)
3380 /* u8 cifs fields do not need le conversion */
3381 ace
->e_perm
= cpu_to_le16(cifs_ace
->cifs_e_perm
);
3382 ace
->e_tag
= cpu_to_le16(cifs_ace
->cifs_e_tag
);
3383 ace
->e_id
= cpu_to_le32(le64_to_cpu(cifs_ace
->cifs_uid
));
3385 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3386 ace->e_perm, ace->e_tag, ace->e_id);
3392 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3393 static int cifs_copy_posix_acl(char *trgt
, char *src
, const int buflen
,
3394 const int acl_type
, const int size_of_data_area
)
3399 struct cifs_posix_ace
*pACE
;
3400 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)src
;
3401 posix_acl_xattr_header
*local_acl
= (posix_acl_xattr_header
*)trgt
;
3403 if (le16_to_cpu(cifs_acl
->version
) != CIFS_ACL_VERSION
)
3406 if (acl_type
& ACL_TYPE_ACCESS
) {
3407 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3408 pACE
= &cifs_acl
->ace_array
[0];
3409 size
= sizeof(struct cifs_posix_acl
);
3410 size
+= sizeof(struct cifs_posix_ace
) * count
;
3411 /* check if we would go beyond end of SMB */
3412 if (size_of_data_area
< size
) {
3413 cifs_dbg(FYI
, "bad CIFS POSIX ACL size %d vs. %d\n",
3414 size_of_data_area
, size
);
3417 } else if (acl_type
& ACL_TYPE_DEFAULT
) {
3418 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3419 size
= sizeof(struct cifs_posix_acl
);
3420 size
+= sizeof(struct cifs_posix_ace
) * count
;
3421 /* skip past access ACEs to get to default ACEs */
3422 pACE
= &cifs_acl
->ace_array
[count
];
3423 count
= le16_to_cpu(cifs_acl
->default_entry_count
);
3424 size
+= sizeof(struct cifs_posix_ace
) * count
;
3425 /* check if we would go beyond end of SMB */
3426 if (size_of_data_area
< size
)
3433 size
= posix_acl_xattr_size(count
);
3434 if ((buflen
== 0) || (local_acl
== NULL
)) {
3435 /* used to query ACL EA size */
3436 } else if (size
> buflen
) {
3438 } else /* buffer big enough */ {
3439 local_acl
->a_version
= cpu_to_le32(POSIX_ACL_XATTR_VERSION
);
3440 for (i
= 0; i
< count
; i
++) {
3441 cifs_convert_ace(&local_acl
->a_entries
[i
], pACE
);
3448 static __u16
convert_ace_to_cifs_ace(struct cifs_posix_ace
*cifs_ace
,
3449 const posix_acl_xattr_entry
*local_ace
)
3451 __u16 rc
= 0; /* 0 = ACL converted ok */
3453 cifs_ace
->cifs_e_perm
= le16_to_cpu(local_ace
->e_perm
);
3454 cifs_ace
->cifs_e_tag
= le16_to_cpu(local_ace
->e_tag
);
3455 /* BB is there a better way to handle the large uid? */
3456 if (local_ace
->e_id
== cpu_to_le32(-1)) {
3457 /* Probably no need to le convert -1 on any arch but can not hurt */
3458 cifs_ace
->cifs_uid
= cpu_to_le64(-1);
3460 cifs_ace
->cifs_uid
= cpu_to_le64(le32_to_cpu(local_ace
->e_id
));
3462 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3463 ace->e_perm, ace->e_tag, ace->e_id);
3468 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3469 static __u16
ACL_to_cifs_posix(char *parm_data
, const char *pACL
,
3470 const int buflen
, const int acl_type
)
3473 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)parm_data
;
3474 posix_acl_xattr_header
*local_acl
= (posix_acl_xattr_header
*)pACL
;
3478 if ((buflen
== 0) || (pACL
== NULL
) || (cifs_acl
== NULL
))
3481 count
= posix_acl_xattr_count((size_t)buflen
);
3482 cifs_dbg(FYI
, "setting acl with %d entries from buf of length %d and version of %d\n",
3483 count
, buflen
, le32_to_cpu(local_acl
->a_version
));
3484 if (le32_to_cpu(local_acl
->a_version
) != 2) {
3485 cifs_dbg(FYI
, "unknown POSIX ACL version %d\n",
3486 le32_to_cpu(local_acl
->a_version
));
3489 cifs_acl
->version
= cpu_to_le16(1);
3490 if (acl_type
== ACL_TYPE_ACCESS
) {
3491 cifs_acl
->access_entry_count
= cpu_to_le16(count
);
3492 cifs_acl
->default_entry_count
= cpu_to_le16(0xFFFF);
3493 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3494 cifs_acl
->default_entry_count
= cpu_to_le16(count
);
3495 cifs_acl
->access_entry_count
= cpu_to_le16(0xFFFF);
3497 cifs_dbg(FYI
, "unknown ACL type %d\n", acl_type
);
3500 for (i
= 0; i
< count
; i
++) {
3501 rc
= convert_ace_to_cifs_ace(&cifs_acl
->ace_array
[i
],
3502 &local_acl
->a_entries
[i
]);
3504 /* ACE not converted */
3509 rc
= (__u16
)(count
* sizeof(struct cifs_posix_ace
));
3510 rc
+= sizeof(struct cifs_posix_acl
);
3511 /* BB add check to make sure ACL does not overflow SMB */
3517 CIFSSMBGetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3518 const unsigned char *searchName
,
3519 char *acl_inf
, const int buflen
, const int acl_type
,
3520 const struct nls_table
*nls_codepage
, int remap
)
3522 /* SMB_QUERY_POSIX_ACL */
3523 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3524 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3528 __u16 params
, byte_count
;
3530 cifs_dbg(FYI
, "In GetPosixACL (Unix) for path %s\n", searchName
);
3533 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3538 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3540 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3541 searchName
, PATH_MAX
, nls_codepage
,
3543 name_len
++; /* trailing null */
3545 pSMB
->FileName
[name_len
] = 0;
3546 pSMB
->FileName
[name_len
+1] = 0;
3547 } else { /* BB improve the check for buffer overruns BB */
3548 name_len
= strnlen(searchName
, PATH_MAX
);
3549 name_len
++; /* trailing null */
3550 strncpy(pSMB
->FileName
, searchName
, name_len
);
3553 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3554 pSMB
->TotalDataCount
= 0;
3555 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3556 /* BB find exact max data count below from sess structure BB */
3557 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3558 pSMB
->MaxSetupCount
= 0;
3562 pSMB
->Reserved2
= 0;
3563 pSMB
->ParameterOffset
= cpu_to_le16(
3564 offsetof(struct smb_com_transaction2_qpi_req
,
3565 InformationLevel
) - 4);
3566 pSMB
->DataCount
= 0;
3567 pSMB
->DataOffset
= 0;
3568 pSMB
->SetupCount
= 1;
3569 pSMB
->Reserved3
= 0;
3570 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3571 byte_count
= params
+ 1 /* pad */ ;
3572 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3573 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3574 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_ACL
);
3575 pSMB
->Reserved4
= 0;
3576 inc_rfc1001_len(pSMB
, byte_count
);
3577 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3579 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3580 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3581 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3583 cifs_dbg(FYI
, "Send error in Query POSIX ACL = %d\n", rc
);
3585 /* decode response */
3587 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3588 /* BB also check enough total bytes returned */
3589 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3590 rc
= -EIO
; /* bad smb */
3592 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3593 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3594 rc
= cifs_copy_posix_acl(acl_inf
,
3595 (char *)&pSMBr
->hdr
.Protocol
+data_offset
,
3596 buflen
, acl_type
, count
);
3599 cifs_buf_release(pSMB
);
3606 CIFSSMBSetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3607 const unsigned char *fileName
,
3608 const char *local_acl
, const int buflen
,
3610 const struct nls_table
*nls_codepage
, int remap
)
3612 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3613 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3617 int bytes_returned
= 0;
3618 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
3620 cifs_dbg(FYI
, "In SetPosixACL (Unix) for path %s\n", fileName
);
3622 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3626 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3628 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
3629 PATH_MAX
, nls_codepage
, remap
);
3630 name_len
++; /* trailing null */
3632 } else { /* BB improve the check for buffer overruns BB */
3633 name_len
= strnlen(fileName
, PATH_MAX
);
3634 name_len
++; /* trailing null */
3635 strncpy(pSMB
->FileName
, fileName
, name_len
);
3637 params
= 6 + name_len
;
3638 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3639 /* BB find max SMB size from sess */
3640 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3641 pSMB
->MaxSetupCount
= 0;
3645 pSMB
->Reserved2
= 0;
3646 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3647 InformationLevel
) - 4;
3648 offset
= param_offset
+ params
;
3649 parm_data
= ((char *) &pSMB
->hdr
.Protocol
) + offset
;
3650 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3652 /* convert to on the wire format for POSIX ACL */
3653 data_count
= ACL_to_cifs_posix(parm_data
, local_acl
, buflen
, acl_type
);
3655 if (data_count
== 0) {
3657 goto setACLerrorExit
;
3659 pSMB
->DataOffset
= cpu_to_le16(offset
);
3660 pSMB
->SetupCount
= 1;
3661 pSMB
->Reserved3
= 0;
3662 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3663 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_ACL
);
3664 byte_count
= 3 /* pad */ + params
+ data_count
;
3665 pSMB
->DataCount
= cpu_to_le16(data_count
);
3666 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3667 pSMB
->ParameterCount
= cpu_to_le16(params
);
3668 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3669 pSMB
->Reserved4
= 0;
3670 inc_rfc1001_len(pSMB
, byte_count
);
3671 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3672 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3673 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3675 cifs_dbg(FYI
, "Set POSIX ACL returned %d\n", rc
);
3678 cifs_buf_release(pSMB
);
3684 /* BB fix tabs in this function FIXME BB */
3686 CIFSGetExtAttr(const unsigned int xid
, struct cifs_tcon
*tcon
,
3687 const int netfid
, __u64
*pExtAttrBits
, __u64
*pMask
)
3690 struct smb_t2_qfi_req
*pSMB
= NULL
;
3691 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3693 __u16 params
, byte_count
;
3695 cifs_dbg(FYI
, "In GetExtAttr\n");
3700 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3705 params
= 2 /* level */ + 2 /* fid */;
3706 pSMB
->t2
.TotalDataCount
= 0;
3707 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3708 /* BB find exact max data count below from sess structure BB */
3709 pSMB
->t2
.MaxDataCount
= cpu_to_le16(4000);
3710 pSMB
->t2
.MaxSetupCount
= 0;
3711 pSMB
->t2
.Reserved
= 0;
3713 pSMB
->t2
.Timeout
= 0;
3714 pSMB
->t2
.Reserved2
= 0;
3715 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3717 pSMB
->t2
.DataCount
= 0;
3718 pSMB
->t2
.DataOffset
= 0;
3719 pSMB
->t2
.SetupCount
= 1;
3720 pSMB
->t2
.Reserved3
= 0;
3721 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3722 byte_count
= params
+ 1 /* pad */ ;
3723 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3724 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3725 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_ATTR_FLAGS
);
3728 inc_rfc1001_len(pSMB
, byte_count
);
3729 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3731 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3732 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3734 cifs_dbg(FYI
, "error %d in GetExtAttr\n", rc
);
3736 /* decode response */
3737 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3738 /* BB also check enough total bytes returned */
3739 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3740 /* If rc should we check for EOPNOSUPP and
3741 disable the srvino flag? or in caller? */
3742 rc
= -EIO
; /* bad smb */
3744 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3745 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3746 struct file_chattr_info
*pfinfo
;
3747 /* BB Do we need a cast or hash here ? */
3749 cifs_dbg(FYI
, "Illegal size ret in GetExtAttr\n");
3753 pfinfo
= (struct file_chattr_info
*)
3754 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
3755 *pExtAttrBits
= le64_to_cpu(pfinfo
->mode
);
3756 *pMask
= le64_to_cpu(pfinfo
->mask
);
3760 cifs_buf_release(pSMB
);
3762 goto GetExtAttrRetry
;
3766 #endif /* CONFIG_POSIX */
3768 #ifdef CONFIG_CIFS_ACL
3770 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3771 * all NT TRANSACTS that we init here have total parm and data under about 400
3772 * bytes (to fit in small cifs buffer size), which is the case so far, it
3773 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3774 * returned setup area) and MaxParameterCount (returned parms size) must be set
3778 smb_init_nttransact(const __u16 sub_command
, const int setup_count
,
3779 const int parm_len
, struct cifs_tcon
*tcon
,
3784 struct smb_com_ntransact_req
*pSMB
;
3786 rc
= small_smb_init(SMB_COM_NT_TRANSACT
, 19 + setup_count
, tcon
,
3790 *ret_buf
= (void *)pSMB
;
3792 pSMB
->TotalParameterCount
= cpu_to_le32(parm_len
);
3793 pSMB
->TotalDataCount
= 0;
3794 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3795 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3796 pSMB
->DataCount
= pSMB
->TotalDataCount
;
3797 temp_offset
= offsetof(struct smb_com_ntransact_req
, Parms
) +
3798 (setup_count
* 2) - 4 /* for rfc1001 length itself */;
3799 pSMB
->ParameterOffset
= cpu_to_le32(temp_offset
);
3800 pSMB
->DataOffset
= cpu_to_le32(temp_offset
+ parm_len
);
3801 pSMB
->SetupCount
= setup_count
; /* no need to le convert byte fields */
3802 pSMB
->SubCommand
= cpu_to_le16(sub_command
);
3807 validate_ntransact(char *buf
, char **ppparm
, char **ppdata
,
3808 __u32
*pparmlen
, __u32
*pdatalen
)
3811 __u32 data_count
, data_offset
, parm_count
, parm_offset
;
3812 struct smb_com_ntransact_rsp
*pSMBr
;
3821 pSMBr
= (struct smb_com_ntransact_rsp
*)buf
;
3823 bcc
= get_bcc(&pSMBr
->hdr
);
3824 end_of_smb
= 2 /* sizeof byte count */ + bcc
+
3825 (char *)&pSMBr
->ByteCount
;
3827 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3828 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3829 parm_offset
= le32_to_cpu(pSMBr
->ParameterOffset
);
3830 parm_count
= le32_to_cpu(pSMBr
->ParameterCount
);
3832 *ppparm
= (char *)&pSMBr
->hdr
.Protocol
+ parm_offset
;
3833 *ppdata
= (char *)&pSMBr
->hdr
.Protocol
+ data_offset
;
3835 /* should we also check that parm and data areas do not overlap? */
3836 if (*ppparm
> end_of_smb
) {
3837 cifs_dbg(FYI
, "parms start after end of smb\n");
3839 } else if (parm_count
+ *ppparm
> end_of_smb
) {
3840 cifs_dbg(FYI
, "parm end after end of smb\n");
3842 } else if (*ppdata
> end_of_smb
) {
3843 cifs_dbg(FYI
, "data starts after end of smb\n");
3845 } else if (data_count
+ *ppdata
> end_of_smb
) {
3846 cifs_dbg(FYI
, "data %p + count %d (%p) past smb end %p start %p\n",
3847 *ppdata
, data_count
, (data_count
+ *ppdata
),
3850 } else if (parm_count
+ data_count
> bcc
) {
3851 cifs_dbg(FYI
, "parm count and data count larger than SMB\n");
3854 *pdatalen
= data_count
;
3855 *pparmlen
= parm_count
;
3859 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3861 CIFSSMBGetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3862 struct cifs_ntsd
**acl_inf
, __u32
*pbuflen
)
3866 QUERY_SEC_DESC_REQ
*pSMB
;
3869 cifs_dbg(FYI
, "GetCifsACL\n");
3874 rc
= smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC
, 0,
3875 8 /* parm len */, tcon
, (void **) &pSMB
);
3879 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3880 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3881 pSMB
->MaxSetupCount
= 0;
3882 pSMB
->Fid
= fid
; /* file handle always le */
3883 pSMB
->AclFlags
= cpu_to_le32(CIFS_ACL_OWNER
| CIFS_ACL_GROUP
|
3885 pSMB
->ByteCount
= cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3886 inc_rfc1001_len(pSMB
, 11);
3887 iov
[0].iov_base
= (char *)pSMB
;
3888 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
3890 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovec */, &buf_type
,
3892 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3894 cifs_dbg(FYI
, "Send error in QuerySecDesc = %d\n", rc
);
3895 } else { /* decode response */
3899 struct smb_com_ntransact_rsp
*pSMBr
;
3902 /* validate_nttransact */
3903 rc
= validate_ntransact(iov
[0].iov_base
, (char **)&parm
,
3904 &pdata
, &parm_len
, pbuflen
);
3907 pSMBr
= (struct smb_com_ntransact_rsp
*)iov
[0].iov_base
;
3909 cifs_dbg(FYI
, "smb %p parm %p data %p\n",
3910 pSMBr
, parm
, *acl_inf
);
3912 if (le32_to_cpu(pSMBr
->ParameterCount
) != 4) {
3913 rc
= -EIO
; /* bad smb */
3918 /* BB check that data area is minimum length and as big as acl_len */
3920 acl_len
= le32_to_cpu(*parm
);
3921 if (acl_len
!= *pbuflen
) {
3922 cifs_dbg(VFS
, "acl length %d does not match %d\n",
3924 if (*pbuflen
> acl_len
)
3928 /* check if buffer is big enough for the acl
3929 header followed by the smallest SID */
3930 if ((*pbuflen
< sizeof(struct cifs_ntsd
) + 8) ||
3931 (*pbuflen
>= 64 * 1024)) {
3932 cifs_dbg(VFS
, "bad acl length %d\n", *pbuflen
);
3936 *acl_inf
= kmemdup(pdata
, *pbuflen
, GFP_KERNEL
);
3937 if (*acl_inf
== NULL
) {
3944 free_rsp_buf(buf_type
, iov
[0].iov_base
);
3945 /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3950 CIFSSMBSetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3951 struct cifs_ntsd
*pntsd
, __u32 acllen
, int aclflag
)
3953 __u16 byte_count
, param_count
, data_count
, param_offset
, data_offset
;
3955 int bytes_returned
= 0;
3956 SET_SEC_DESC_REQ
*pSMB
= NULL
;
3960 rc
= smb_init(SMB_COM_NT_TRANSACT
, 19, tcon
, (void **) &pSMB
, &pSMBr
);
3964 pSMB
->MaxSetupCount
= 0;
3968 param_offset
= offsetof(struct smb_com_transaction_ssec_req
, Fid
) - 4;
3969 data_count
= acllen
;
3970 data_offset
= param_offset
+ param_count
;
3971 byte_count
= 3 /* pad */ + param_count
;
3973 pSMB
->DataCount
= cpu_to_le32(data_count
);
3974 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3975 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3976 pSMB
->MaxDataCount
= cpu_to_le32(16384);
3977 pSMB
->ParameterCount
= cpu_to_le32(param_count
);
3978 pSMB
->ParameterOffset
= cpu_to_le32(param_offset
);
3979 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3980 pSMB
->DataOffset
= cpu_to_le32(data_offset
);
3981 pSMB
->SetupCount
= 0;
3982 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC
);
3983 pSMB
->ByteCount
= cpu_to_le16(byte_count
+data_count
);
3985 pSMB
->Fid
= fid
; /* file handle always le */
3986 pSMB
->Reserved2
= 0;
3987 pSMB
->AclFlags
= cpu_to_le32(aclflag
);
3989 if (pntsd
&& acllen
) {
3990 memcpy((char *)pSMBr
+ offsetof(struct smb_hdr
, Protocol
) +
3991 data_offset
, pntsd
, acllen
);
3992 inc_rfc1001_len(pSMB
, byte_count
+ data_count
);
3994 inc_rfc1001_len(pSMB
, byte_count
);
3996 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3997 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3999 cifs_dbg(FYI
, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4000 bytes_returned
, rc
);
4002 cifs_dbg(FYI
, "Set CIFS ACL returned %d\n", rc
);
4003 cifs_buf_release(pSMB
);
4006 goto setCifsAclRetry
;
4011 #endif /* CONFIG_CIFS_ACL */
4013 /* Legacy Query Path Information call for lookup to old servers such
4016 SMBQueryInformation(const unsigned int xid
, struct cifs_tcon
*tcon
,
4017 const char *search_name
, FILE_ALL_INFO
*data
,
4018 const struct nls_table
*nls_codepage
, int remap
)
4020 QUERY_INFORMATION_REQ
*pSMB
;
4021 QUERY_INFORMATION_RSP
*pSMBr
;
4026 cifs_dbg(FYI
, "In SMBQPath path %s\n", search_name
);
4028 rc
= smb_init(SMB_COM_QUERY_INFORMATION
, 0, tcon
, (void **) &pSMB
,
4033 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4035 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4036 search_name
, PATH_MAX
, nls_codepage
,
4038 name_len
++; /* trailing null */
4041 name_len
= strnlen(search_name
, PATH_MAX
);
4042 name_len
++; /* trailing null */
4043 strncpy(pSMB
->FileName
, search_name
, name_len
);
4045 pSMB
->BufferFormat
= 0x04;
4046 name_len
++; /* account for buffer type byte */
4047 inc_rfc1001_len(pSMB
, (__u16
)name_len
);
4048 pSMB
->ByteCount
= cpu_to_le16(name_len
);
4050 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4051 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4053 cifs_dbg(FYI
, "Send error in QueryInfo = %d\n", rc
);
4056 __u32 time
= le32_to_cpu(pSMBr
->last_write_time
);
4058 /* decode response */
4059 /* BB FIXME - add time zone adjustment BB */
4060 memset(data
, 0, sizeof(FILE_ALL_INFO
));
4063 /* decode time fields */
4064 data
->ChangeTime
= cpu_to_le64(cifs_UnixTimeToNT(ts
));
4065 data
->LastWriteTime
= data
->ChangeTime
;
4066 data
->LastAccessTime
= 0;
4067 data
->AllocationSize
=
4068 cpu_to_le64(le32_to_cpu(pSMBr
->size
));
4069 data
->EndOfFile
= data
->AllocationSize
;
4071 cpu_to_le32(le16_to_cpu(pSMBr
->attr
));
4073 rc
= -EIO
; /* bad buffer passed in */
4075 cifs_buf_release(pSMB
);
4084 CIFSSMBQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4085 u16 netfid
, FILE_ALL_INFO
*pFindData
)
4087 struct smb_t2_qfi_req
*pSMB
= NULL
;
4088 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4091 __u16 params
, byte_count
;
4094 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4099 params
= 2 /* level */ + 2 /* fid */;
4100 pSMB
->t2
.TotalDataCount
= 0;
4101 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4102 /* BB find exact max data count below from sess structure BB */
4103 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4104 pSMB
->t2
.MaxSetupCount
= 0;
4105 pSMB
->t2
.Reserved
= 0;
4107 pSMB
->t2
.Timeout
= 0;
4108 pSMB
->t2
.Reserved2
= 0;
4109 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4111 pSMB
->t2
.DataCount
= 0;
4112 pSMB
->t2
.DataOffset
= 0;
4113 pSMB
->t2
.SetupCount
= 1;
4114 pSMB
->t2
.Reserved3
= 0;
4115 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4116 byte_count
= params
+ 1 /* pad */ ;
4117 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4118 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4119 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4122 inc_rfc1001_len(pSMB
, byte_count
);
4123 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4125 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4126 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4128 cifs_dbg(FYI
, "Send error in QFileInfo = %d", rc
);
4129 } else { /* decode response */
4130 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4132 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4134 else if (get_bcc(&pSMBr
->hdr
) < 40)
4135 rc
= -EIO
; /* bad smb */
4136 else if (pFindData
) {
4137 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4138 memcpy((char *) pFindData
,
4139 (char *) &pSMBr
->hdr
.Protocol
+
4140 data_offset
, sizeof(FILE_ALL_INFO
));
4144 cifs_buf_release(pSMB
);
4146 goto QFileInfoRetry
;
4152 CIFSSMBQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4153 const char *search_name
, FILE_ALL_INFO
*data
,
4154 int legacy
/* old style infolevel */,
4155 const struct nls_table
*nls_codepage
, int remap
)
4157 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4158 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4159 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4163 __u16 params
, byte_count
;
4165 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4167 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4172 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4174 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, search_name
,
4175 PATH_MAX
, nls_codepage
, remap
);
4176 name_len
++; /* trailing null */
4178 } else { /* BB improve the check for buffer overruns BB */
4179 name_len
= strnlen(search_name
, PATH_MAX
);
4180 name_len
++; /* trailing null */
4181 strncpy(pSMB
->FileName
, search_name
, name_len
);
4184 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4185 pSMB
->TotalDataCount
= 0;
4186 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4187 /* BB find exact max SMB PDU from sess structure BB */
4188 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4189 pSMB
->MaxSetupCount
= 0;
4193 pSMB
->Reserved2
= 0;
4194 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4195 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4196 pSMB
->DataCount
= 0;
4197 pSMB
->DataOffset
= 0;
4198 pSMB
->SetupCount
= 1;
4199 pSMB
->Reserved3
= 0;
4200 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4201 byte_count
= params
+ 1 /* pad */ ;
4202 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4203 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4205 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
4207 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4208 pSMB
->Reserved4
= 0;
4209 inc_rfc1001_len(pSMB
, byte_count
);
4210 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4212 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4213 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4215 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4216 } else { /* decode response */
4217 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4219 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4221 else if (!legacy
&& get_bcc(&pSMBr
->hdr
) < 40)
4222 rc
= -EIO
; /* bad smb */
4223 else if (legacy
&& get_bcc(&pSMBr
->hdr
) < 24)
4224 rc
= -EIO
; /* 24 or 26 expected but we do not read
4228 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4231 * On legacy responses we do not read the last field,
4232 * EAsize, fortunately since it varies by subdialect and
4233 * also note it differs on Set vs Get, ie two bytes or 4
4234 * bytes depending but we don't care here.
4237 size
= sizeof(FILE_INFO_STANDARD
);
4239 size
= sizeof(FILE_ALL_INFO
);
4240 memcpy((char *) data
, (char *) &pSMBr
->hdr
.Protocol
+
4245 cifs_buf_release(pSMB
);
4247 goto QPathInfoRetry
;
4253 CIFSSMBUnixQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4254 u16 netfid
, FILE_UNIX_BASIC_INFO
*pFindData
)
4256 struct smb_t2_qfi_req
*pSMB
= NULL
;
4257 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4260 __u16 params
, byte_count
;
4263 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4268 params
= 2 /* level */ + 2 /* fid */;
4269 pSMB
->t2
.TotalDataCount
= 0;
4270 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4271 /* BB find exact max data count below from sess structure BB */
4272 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4273 pSMB
->t2
.MaxSetupCount
= 0;
4274 pSMB
->t2
.Reserved
= 0;
4276 pSMB
->t2
.Timeout
= 0;
4277 pSMB
->t2
.Reserved2
= 0;
4278 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4280 pSMB
->t2
.DataCount
= 0;
4281 pSMB
->t2
.DataOffset
= 0;
4282 pSMB
->t2
.SetupCount
= 1;
4283 pSMB
->t2
.Reserved3
= 0;
4284 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4285 byte_count
= params
+ 1 /* pad */ ;
4286 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4287 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4288 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4291 inc_rfc1001_len(pSMB
, byte_count
);
4292 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4294 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4295 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4297 cifs_dbg(FYI
, "Send error in UnixQFileInfo = %d", rc
);
4298 } else { /* decode response */
4299 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4301 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4302 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4303 rc
= -EIO
; /* bad smb */
4305 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4306 memcpy((char *) pFindData
,
4307 (char *) &pSMBr
->hdr
.Protocol
+
4309 sizeof(FILE_UNIX_BASIC_INFO
));
4313 cifs_buf_release(pSMB
);
4315 goto UnixQFileInfoRetry
;
4321 CIFSSMBUnixQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4322 const unsigned char *searchName
,
4323 FILE_UNIX_BASIC_INFO
*pFindData
,
4324 const struct nls_table
*nls_codepage
, int remap
)
4326 /* SMB_QUERY_FILE_UNIX_BASIC */
4327 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4328 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4330 int bytes_returned
= 0;
4332 __u16 params
, byte_count
;
4334 cifs_dbg(FYI
, "In QPathInfo (Unix) the path %s\n", searchName
);
4336 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4341 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4343 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4344 PATH_MAX
, nls_codepage
, remap
);
4345 name_len
++; /* trailing null */
4347 } else { /* BB improve the check for buffer overruns BB */
4348 name_len
= strnlen(searchName
, PATH_MAX
);
4349 name_len
++; /* trailing null */
4350 strncpy(pSMB
->FileName
, searchName
, name_len
);
4353 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4354 pSMB
->TotalDataCount
= 0;
4355 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4356 /* BB find exact max SMB PDU from sess structure BB */
4357 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4358 pSMB
->MaxSetupCount
= 0;
4362 pSMB
->Reserved2
= 0;
4363 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4364 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4365 pSMB
->DataCount
= 0;
4366 pSMB
->DataOffset
= 0;
4367 pSMB
->SetupCount
= 1;
4368 pSMB
->Reserved3
= 0;
4369 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4370 byte_count
= params
+ 1 /* pad */ ;
4371 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4372 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4373 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4374 pSMB
->Reserved4
= 0;
4375 inc_rfc1001_len(pSMB
, byte_count
);
4376 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4378 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4379 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4381 cifs_dbg(FYI
, "Send error in UnixQPathInfo = %d", rc
);
4382 } else { /* decode response */
4383 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4385 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4386 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4387 rc
= -EIO
; /* bad smb */
4389 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4390 memcpy((char *) pFindData
,
4391 (char *) &pSMBr
->hdr
.Protocol
+
4393 sizeof(FILE_UNIX_BASIC_INFO
));
4396 cifs_buf_release(pSMB
);
4398 goto UnixQPathInfoRetry
;
4403 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4405 CIFSFindFirst(const unsigned int xid
, struct cifs_tcon
*tcon
,
4406 const char *searchName
, struct cifs_sb_info
*cifs_sb
,
4407 __u16
*pnetfid
, __u16 search_flags
,
4408 struct cifs_search_info
*psrch_inf
, bool msearch
)
4410 /* level 257 SMB_ */
4411 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
4412 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
4413 T2_FFIRST_RSP_PARMS
*parms
;
4415 int bytes_returned
= 0;
4416 int name_len
, remap
;
4417 __u16 params
, byte_count
;
4418 struct nls_table
*nls_codepage
;
4420 cifs_dbg(FYI
, "In FindFirst for %s\n", searchName
);
4423 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4428 nls_codepage
= cifs_sb
->local_nls
;
4429 remap
= cifs_remap(cifs_sb
);
4431 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4433 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4434 PATH_MAX
, nls_codepage
, remap
);
4435 /* We can not add the asterik earlier in case
4436 it got remapped to 0xF03A as if it were part of the
4437 directory name instead of a wildcard */
4440 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4441 pSMB
->FileName
[name_len
+1] = 0;
4442 pSMB
->FileName
[name_len
+2] = '*';
4443 pSMB
->FileName
[name_len
+3] = 0;
4444 name_len
+= 4; /* now the trailing null */
4445 /* null terminate just in case */
4446 pSMB
->FileName
[name_len
] = 0;
4447 pSMB
->FileName
[name_len
+1] = 0;
4450 } else { /* BB add check for overrun of SMB buf BB */
4451 name_len
= strnlen(searchName
, PATH_MAX
);
4452 /* BB fix here and in unicode clause above ie
4453 if (name_len > buffersize-header)
4454 free buffer exit; BB */
4455 strncpy(pSMB
->FileName
, searchName
, name_len
);
4457 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4458 pSMB
->FileName
[name_len
+1] = '*';
4459 pSMB
->FileName
[name_len
+2] = 0;
4464 params
= 12 + name_len
/* includes null */ ;
4465 pSMB
->TotalDataCount
= 0; /* no EAs */
4466 pSMB
->MaxParameterCount
= cpu_to_le16(10);
4467 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4468 pSMB
->MaxSetupCount
= 0;
4472 pSMB
->Reserved2
= 0;
4473 byte_count
= params
+ 1 /* pad */ ;
4474 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4475 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4476 pSMB
->ParameterOffset
= cpu_to_le16(
4477 offsetof(struct smb_com_transaction2_ffirst_req
, SearchAttributes
)
4479 pSMB
->DataCount
= 0;
4480 pSMB
->DataOffset
= 0;
4481 pSMB
->SetupCount
= 1; /* one byte, no need to make endian neutral */
4482 pSMB
->Reserved3
= 0;
4483 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
4484 pSMB
->SearchAttributes
=
4485 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
4487 pSMB
->SearchCount
= cpu_to_le16(CIFSMaxBufSize
/sizeof(FILE_UNIX_INFO
));
4488 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4489 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4491 /* BB what should we set StorageType to? Does it matter? BB */
4492 pSMB
->SearchStorageType
= 0;
4493 inc_rfc1001_len(pSMB
, byte_count
);
4494 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4496 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4497 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4498 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_ffirst
);
4500 if (rc
) {/* BB add logic to retry regular search if Unix search
4501 rejected unexpectedly by server */
4502 /* BB Add code to handle unsupported level rc */
4503 cifs_dbg(FYI
, "Error in FindFirst = %d\n", rc
);
4505 cifs_buf_release(pSMB
);
4507 /* BB eventually could optimize out free and realloc of buf */
4510 goto findFirstRetry
;
4511 } else { /* decode response */
4512 /* BB remember to free buffer if error BB */
4513 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4517 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4518 psrch_inf
->unicode
= true;
4520 psrch_inf
->unicode
= false;
4522 psrch_inf
->ntwrk_buf_start
= (char *)pSMBr
;
4523 psrch_inf
->smallBuf
= 0;
4524 psrch_inf
->srch_entries_start
=
4525 (char *) &pSMBr
->hdr
.Protocol
+
4526 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4527 parms
= (T2_FFIRST_RSP_PARMS
*)((char *) &pSMBr
->hdr
.Protocol
+
4528 le16_to_cpu(pSMBr
->t2
.ParameterOffset
));
4530 if (parms
->EndofSearch
)
4531 psrch_inf
->endOfSearch
= true;
4533 psrch_inf
->endOfSearch
= false;
4535 psrch_inf
->entries_in_buffer
=
4536 le16_to_cpu(parms
->SearchCount
);
4537 psrch_inf
->index_of_last_entry
= 2 /* skip . and .. */ +
4538 psrch_inf
->entries_in_buffer
;
4539 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4540 if (CIFSMaxBufSize
< lnoff
) {
4541 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4542 psrch_inf
->last_entry
= NULL
;
4546 psrch_inf
->last_entry
= psrch_inf
->srch_entries_start
+
4550 *pnetfid
= parms
->SearchHandle
;
4552 cifs_buf_release(pSMB
);
4559 int CIFSFindNext(const unsigned int xid
, struct cifs_tcon
*tcon
,
4560 __u16 searchHandle
, __u16 search_flags
,
4561 struct cifs_search_info
*psrch_inf
)
4563 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
4564 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
4565 T2_FNEXT_RSP_PARMS
*parms
;
4566 char *response_data
;
4569 unsigned int name_len
;
4570 __u16 params
, byte_count
;
4572 cifs_dbg(FYI
, "In FindNext\n");
4574 if (psrch_inf
->endOfSearch
)
4577 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4582 params
= 14; /* includes 2 bytes of null string, converted to LE below*/
4584 pSMB
->TotalDataCount
= 0; /* no EAs */
4585 pSMB
->MaxParameterCount
= cpu_to_le16(8);
4586 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4587 pSMB
->MaxSetupCount
= 0;
4591 pSMB
->Reserved2
= 0;
4592 pSMB
->ParameterOffset
= cpu_to_le16(
4593 offsetof(struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
4594 pSMB
->DataCount
= 0;
4595 pSMB
->DataOffset
= 0;
4596 pSMB
->SetupCount
= 1;
4597 pSMB
->Reserved3
= 0;
4598 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
4599 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
4601 cpu_to_le16(CIFSMaxBufSize
/ sizeof(FILE_UNIX_INFO
));
4602 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4603 pSMB
->ResumeKey
= psrch_inf
->resume_key
;
4604 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4606 name_len
= psrch_inf
->resume_name_len
;
4608 if (name_len
< PATH_MAX
) {
4609 memcpy(pSMB
->ResumeFileName
, psrch_inf
->presume_name
, name_len
);
4610 byte_count
+= name_len
;
4611 /* 14 byte parm len above enough for 2 byte null terminator */
4612 pSMB
->ResumeFileName
[name_len
] = 0;
4613 pSMB
->ResumeFileName
[name_len
+1] = 0;
4616 goto FNext2_err_exit
;
4618 byte_count
= params
+ 1 /* pad */ ;
4619 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4620 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4621 inc_rfc1001_len(pSMB
, byte_count
);
4622 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4624 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4625 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4626 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fnext
);
4629 psrch_inf
->endOfSearch
= true;
4630 cifs_buf_release(pSMB
);
4631 rc
= 0; /* search probably was closed at end of search*/
4633 cifs_dbg(FYI
, "FindNext returned = %d\n", rc
);
4634 } else { /* decode response */
4635 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4640 /* BB fixme add lock for file (srch_info) struct here */
4641 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4642 psrch_inf
->unicode
= true;
4644 psrch_inf
->unicode
= false;
4645 response_data
= (char *) &pSMBr
->hdr
.Protocol
+
4646 le16_to_cpu(pSMBr
->t2
.ParameterOffset
);
4647 parms
= (T2_FNEXT_RSP_PARMS
*)response_data
;
4648 response_data
= (char *)&pSMBr
->hdr
.Protocol
+
4649 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4650 if (psrch_inf
->smallBuf
)
4651 cifs_small_buf_release(
4652 psrch_inf
->ntwrk_buf_start
);
4654 cifs_buf_release(psrch_inf
->ntwrk_buf_start
);
4655 psrch_inf
->srch_entries_start
= response_data
;
4656 psrch_inf
->ntwrk_buf_start
= (char *)pSMB
;
4657 psrch_inf
->smallBuf
= 0;
4658 if (parms
->EndofSearch
)
4659 psrch_inf
->endOfSearch
= true;
4661 psrch_inf
->endOfSearch
= false;
4662 psrch_inf
->entries_in_buffer
=
4663 le16_to_cpu(parms
->SearchCount
);
4664 psrch_inf
->index_of_last_entry
+=
4665 psrch_inf
->entries_in_buffer
;
4666 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4667 if (CIFSMaxBufSize
< lnoff
) {
4668 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4669 psrch_inf
->last_entry
= NULL
;
4672 psrch_inf
->last_entry
=
4673 psrch_inf
->srch_entries_start
+ lnoff
;
4675 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4676 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4678 /* BB fixme add unlock here */
4683 /* BB On error, should we leave previous search buf (and count and
4684 last entry fields) intact or free the previous one? */
4686 /* Note: On -EAGAIN error only caller can retry on handle based calls
4687 since file handle passed in no longer valid */
4690 cifs_buf_release(pSMB
);
4695 CIFSFindClose(const unsigned int xid
, struct cifs_tcon
*tcon
,
4696 const __u16 searchHandle
)
4699 FINDCLOSE_REQ
*pSMB
= NULL
;
4701 cifs_dbg(FYI
, "In CIFSSMBFindClose\n");
4702 rc
= small_smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **)&pSMB
);
4704 /* no sense returning error if session restarted
4705 as file handle has been closed */
4711 pSMB
->FileID
= searchHandle
;
4712 pSMB
->ByteCount
= 0;
4713 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
4715 cifs_dbg(VFS
, "Send error in FindClose = %d\n", rc
);
4717 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fclose
);
4719 /* Since session is dead, search handle closed on server already */
4727 CIFSGetSrvInodeNumber(const unsigned int xid
, struct cifs_tcon
*tcon
,
4728 const char *search_name
, __u64
*inode_number
,
4729 const struct nls_table
*nls_codepage
, int remap
)
4732 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4733 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4734 int name_len
, bytes_returned
;
4735 __u16 params
, byte_count
;
4737 cifs_dbg(FYI
, "In GetSrvInodeNum for %s\n", search_name
);
4741 GetInodeNumberRetry
:
4742 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4747 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4749 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4750 search_name
, PATH_MAX
, nls_codepage
,
4752 name_len
++; /* trailing null */
4754 } else { /* BB improve the check for buffer overruns BB */
4755 name_len
= strnlen(search_name
, PATH_MAX
);
4756 name_len
++; /* trailing null */
4757 strncpy(pSMB
->FileName
, search_name
, name_len
);
4760 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
4761 pSMB
->TotalDataCount
= 0;
4762 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4763 /* BB find exact max data count below from sess structure BB */
4764 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4765 pSMB
->MaxSetupCount
= 0;
4769 pSMB
->Reserved2
= 0;
4770 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4771 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4772 pSMB
->DataCount
= 0;
4773 pSMB
->DataOffset
= 0;
4774 pSMB
->SetupCount
= 1;
4775 pSMB
->Reserved3
= 0;
4776 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4777 byte_count
= params
+ 1 /* pad */ ;
4778 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4779 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4780 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO
);
4781 pSMB
->Reserved4
= 0;
4782 inc_rfc1001_len(pSMB
, byte_count
);
4783 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4785 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4786 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4788 cifs_dbg(FYI
, "error %d in QueryInternalInfo\n", rc
);
4790 /* decode response */
4791 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4792 /* BB also check enough total bytes returned */
4793 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
4794 /* If rc should we check for EOPNOSUPP and
4795 disable the srvino flag? or in caller? */
4796 rc
= -EIO
; /* bad smb */
4798 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4799 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
4800 struct file_internal_info
*pfinfo
;
4801 /* BB Do we need a cast or hash here ? */
4803 cifs_dbg(FYI
, "Illegal size ret in QryIntrnlInf\n");
4805 goto GetInodeNumOut
;
4807 pfinfo
= (struct file_internal_info
*)
4808 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
4809 *inode_number
= le64_to_cpu(pfinfo
->UniqueId
);
4813 cifs_buf_release(pSMB
);
4815 goto GetInodeNumberRetry
;
4819 /* parses DFS refferal V3 structure
4820 * caller is responsible for freeing target_nodes
4823 * on failure - errno
4826 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
,
4827 unsigned int *num_of_nodes
,
4828 struct dfs_info3_param
**target_nodes
,
4829 const struct nls_table
*nls_codepage
, int remap
,
4830 const char *searchName
)
4835 struct dfs_referral_level_3
*ref
;
4837 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4841 *num_of_nodes
= le16_to_cpu(pSMBr
->NumberOfReferrals
);
4843 if (*num_of_nodes
< 1) {
4844 cifs_dbg(VFS
, "num_referrals: must be at least > 0, but we get num_referrals = %d\n",
4847 goto parse_DFS_referrals_exit
;
4850 ref
= (struct dfs_referral_level_3
*) &(pSMBr
->referrals
);
4851 if (ref
->VersionNumber
!= cpu_to_le16(3)) {
4852 cifs_dbg(VFS
, "Referrals of V%d version are not supported, should be V3\n",
4853 le16_to_cpu(ref
->VersionNumber
));
4855 goto parse_DFS_referrals_exit
;
4858 /* get the upper boundary of the resp buffer */
4859 data_end
= (char *)(&(pSMBr
->PathConsumed
)) +
4860 le16_to_cpu(pSMBr
->t2
.DataCount
);
4862 cifs_dbg(FYI
, "num_referrals: %d dfs flags: 0x%x ...\n",
4863 *num_of_nodes
, le32_to_cpu(pSMBr
->DFSFlags
));
4865 *target_nodes
= kcalloc(*num_of_nodes
, sizeof(struct dfs_info3_param
),
4867 if (*target_nodes
== NULL
) {
4869 goto parse_DFS_referrals_exit
;
4872 /* collect necessary data from referrals */
4873 for (i
= 0; i
< *num_of_nodes
; i
++) {
4876 struct dfs_info3_param
*node
= (*target_nodes
)+i
;
4878 node
->flags
= le32_to_cpu(pSMBr
->DFSFlags
);
4880 __le16
*tmp
= kmalloc(strlen(searchName
)*2 + 2,
4884 goto parse_DFS_referrals_exit
;
4886 cifsConvertToUTF16((__le16
*) tmp
, searchName
,
4887 PATH_MAX
, nls_codepage
, remap
);
4888 node
->path_consumed
= cifs_utf16_bytes(tmp
,
4889 le16_to_cpu(pSMBr
->PathConsumed
),
4893 node
->path_consumed
= le16_to_cpu(pSMBr
->PathConsumed
);
4895 node
->server_type
= le16_to_cpu(ref
->ServerType
);
4896 node
->ref_flag
= le16_to_cpu(ref
->ReferralEntryFlags
);
4899 temp
= (char *)ref
+ le16_to_cpu(ref
->DfsPathOffset
);
4900 max_len
= data_end
- temp
;
4901 node
->path_name
= cifs_strndup_from_utf16(temp
, max_len
,
4902 is_unicode
, nls_codepage
);
4903 if (!node
->path_name
) {
4905 goto parse_DFS_referrals_exit
;
4908 /* copy link target UNC */
4909 temp
= (char *)ref
+ le16_to_cpu(ref
->NetworkAddressOffset
);
4910 max_len
= data_end
- temp
;
4911 node
->node_name
= cifs_strndup_from_utf16(temp
, max_len
,
4912 is_unicode
, nls_codepage
);
4913 if (!node
->node_name
) {
4915 goto parse_DFS_referrals_exit
;
4921 parse_DFS_referrals_exit
:
4923 free_dfs_info_array(*target_nodes
, *num_of_nodes
);
4924 *target_nodes
= NULL
;
4931 CIFSGetDFSRefer(const unsigned int xid
, struct cifs_ses
*ses
,
4932 const char *search_name
, struct dfs_info3_param
**target_nodes
,
4933 unsigned int *num_of_nodes
,
4934 const struct nls_table
*nls_codepage
, int remap
)
4936 /* TRANS2_GET_DFS_REFERRAL */
4937 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
4938 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
4942 __u16 params
, byte_count
;
4944 *target_nodes
= NULL
;
4946 cifs_dbg(FYI
, "In GetDFSRefer the path %s\n", search_name
);
4950 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, NULL
, (void **) &pSMB
,
4955 /* server pointer checked in called function,
4956 but should never be null here anyway */
4957 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
4958 pSMB
->hdr
.Tid
= ses
->ipc_tid
;
4959 pSMB
->hdr
.Uid
= ses
->Suid
;
4960 if (ses
->capabilities
& CAP_STATUS32
)
4961 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
4962 if (ses
->capabilities
& CAP_DFS
)
4963 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
4965 if (ses
->capabilities
& CAP_UNICODE
) {
4966 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
4968 cifsConvertToUTF16((__le16
*) pSMB
->RequestFileName
,
4969 search_name
, PATH_MAX
, nls_codepage
,
4971 name_len
++; /* trailing null */
4973 } else { /* BB improve the check for buffer overruns BB */
4974 name_len
= strnlen(search_name
, PATH_MAX
);
4975 name_len
++; /* trailing null */
4976 strncpy(pSMB
->RequestFileName
, search_name
, name_len
);
4979 if (ses
->server
->sign
)
4980 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
4982 pSMB
->hdr
.Uid
= ses
->Suid
;
4984 params
= 2 /* level */ + name_len
/*includes null */ ;
4985 pSMB
->TotalDataCount
= 0;
4986 pSMB
->DataCount
= 0;
4987 pSMB
->DataOffset
= 0;
4988 pSMB
->MaxParameterCount
= 0;
4989 /* BB find exact max SMB PDU from sess structure BB */
4990 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4991 pSMB
->MaxSetupCount
= 0;
4995 pSMB
->Reserved2
= 0;
4996 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4997 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
4998 pSMB
->SetupCount
= 1;
4999 pSMB
->Reserved3
= 0;
5000 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
5001 byte_count
= params
+ 3 /* pad */ ;
5002 pSMB
->ParameterCount
= cpu_to_le16(params
);
5003 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5004 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
5005 inc_rfc1001_len(pSMB
, byte_count
);
5006 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5008 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
5009 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5011 cifs_dbg(FYI
, "Send error in GetDFSRefer = %d\n", rc
);
5014 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5016 /* BB Also check if enough total bytes returned? */
5017 if (rc
|| get_bcc(&pSMBr
->hdr
) < 17) {
5018 rc
= -EIO
; /* bad smb */
5022 cifs_dbg(FYI
, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
5023 get_bcc(&pSMBr
->hdr
), le16_to_cpu(pSMBr
->t2
.DataOffset
));
5025 /* parse returned result into more usable form */
5026 rc
= parse_DFS_referrals(pSMBr
, num_of_nodes
,
5027 target_nodes
, nls_codepage
, remap
,
5031 cifs_buf_release(pSMB
);
5039 /* Query File System Info such as free space to old servers such as Win 9x */
5041 SMBOldQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5042 struct kstatfs
*FSData
)
5044 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
5045 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5046 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5047 FILE_SYSTEM_ALLOC_INFO
*response_data
;
5049 int bytes_returned
= 0;
5050 __u16 params
, byte_count
;
5052 cifs_dbg(FYI
, "OldQFSInfo\n");
5054 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5059 params
= 2; /* level */
5060 pSMB
->TotalDataCount
= 0;
5061 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5062 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5063 pSMB
->MaxSetupCount
= 0;
5067 pSMB
->Reserved2
= 0;
5068 byte_count
= params
+ 1 /* pad */ ;
5069 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5070 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5071 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5072 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5073 pSMB
->DataCount
= 0;
5074 pSMB
->DataOffset
= 0;
5075 pSMB
->SetupCount
= 1;
5076 pSMB
->Reserved3
= 0;
5077 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5078 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_ALLOCATION
);
5079 inc_rfc1001_len(pSMB
, byte_count
);
5080 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5082 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5083 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5085 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5086 } else { /* decode response */
5087 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5089 if (rc
|| get_bcc(&pSMBr
->hdr
) < 18)
5090 rc
= -EIO
; /* bad smb */
5092 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5093 cifs_dbg(FYI
, "qfsinf resp BCC: %d Offset %d\n",
5094 get_bcc(&pSMBr
->hdr
), data_offset
);
5096 response_data
= (FILE_SYSTEM_ALLOC_INFO
*)
5097 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
5099 le16_to_cpu(response_data
->BytesPerSector
) *
5100 le32_to_cpu(response_data
->
5101 SectorsPerAllocationUnit
);
5103 le32_to_cpu(response_data
->TotalAllocationUnits
);
5104 FSData
->f_bfree
= FSData
->f_bavail
=
5105 le32_to_cpu(response_data
->FreeAllocationUnits
);
5106 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5107 (unsigned long long)FSData
->f_blocks
,
5108 (unsigned long long)FSData
->f_bfree
,
5112 cifs_buf_release(pSMB
);
5115 goto oldQFSInfoRetry
;
5121 CIFSSMBQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5122 struct kstatfs
*FSData
)
5124 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5125 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5126 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5127 FILE_SYSTEM_INFO
*response_data
;
5129 int bytes_returned
= 0;
5130 __u16 params
, byte_count
;
5132 cifs_dbg(FYI
, "In QFSInfo\n");
5134 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5139 params
= 2; /* level */
5140 pSMB
->TotalDataCount
= 0;
5141 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5142 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5143 pSMB
->MaxSetupCount
= 0;
5147 pSMB
->Reserved2
= 0;
5148 byte_count
= params
+ 1 /* pad */ ;
5149 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5150 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5151 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5152 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5153 pSMB
->DataCount
= 0;
5154 pSMB
->DataOffset
= 0;
5155 pSMB
->SetupCount
= 1;
5156 pSMB
->Reserved3
= 0;
5157 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5158 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
5159 inc_rfc1001_len(pSMB
, byte_count
);
5160 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5162 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5163 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5165 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5166 } else { /* decode response */
5167 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5169 if (rc
|| get_bcc(&pSMBr
->hdr
) < 24)
5170 rc
= -EIO
; /* bad smb */
5172 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5176 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5179 le32_to_cpu(response_data
->BytesPerSector
) *
5180 le32_to_cpu(response_data
->
5181 SectorsPerAllocationUnit
);
5183 le64_to_cpu(response_data
->TotalAllocationUnits
);
5184 FSData
->f_bfree
= FSData
->f_bavail
=
5185 le64_to_cpu(response_data
->FreeAllocationUnits
);
5186 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5187 (unsigned long long)FSData
->f_blocks
,
5188 (unsigned long long)FSData
->f_bfree
,
5192 cifs_buf_release(pSMB
);
5201 CIFSSMBQFSAttributeInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5203 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5204 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5205 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5206 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
5208 int bytes_returned
= 0;
5209 __u16 params
, byte_count
;
5211 cifs_dbg(FYI
, "In QFSAttributeInfo\n");
5213 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5218 params
= 2; /* level */
5219 pSMB
->TotalDataCount
= 0;
5220 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5221 /* BB find exact max SMB PDU from sess structure BB */
5222 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5223 pSMB
->MaxSetupCount
= 0;
5227 pSMB
->Reserved2
= 0;
5228 byte_count
= params
+ 1 /* pad */ ;
5229 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5230 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5231 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5232 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5233 pSMB
->DataCount
= 0;
5234 pSMB
->DataOffset
= 0;
5235 pSMB
->SetupCount
= 1;
5236 pSMB
->Reserved3
= 0;
5237 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5238 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
5239 inc_rfc1001_len(pSMB
, byte_count
);
5240 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5242 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5243 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5245 cifs_dbg(VFS
, "Send error in QFSAttributeInfo = %d\n", rc
);
5246 } else { /* decode response */
5247 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5249 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5250 /* BB also check if enough bytes returned */
5251 rc
= -EIO
; /* bad smb */
5253 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5255 (FILE_SYSTEM_ATTRIBUTE_INFO
5256 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5258 memcpy(&tcon
->fsAttrInfo
, response_data
,
5259 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO
));
5262 cifs_buf_release(pSMB
);
5265 goto QFSAttributeRetry
;
5271 CIFSSMBQFSDeviceInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5273 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5274 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5275 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5276 FILE_SYSTEM_DEVICE_INFO
*response_data
;
5278 int bytes_returned
= 0;
5279 __u16 params
, byte_count
;
5281 cifs_dbg(FYI
, "In QFSDeviceInfo\n");
5283 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5288 params
= 2; /* level */
5289 pSMB
->TotalDataCount
= 0;
5290 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5291 /* BB find exact max SMB PDU from sess structure BB */
5292 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5293 pSMB
->MaxSetupCount
= 0;
5297 pSMB
->Reserved2
= 0;
5298 byte_count
= params
+ 1 /* pad */ ;
5299 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5300 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5301 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5302 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5304 pSMB
->DataCount
= 0;
5305 pSMB
->DataOffset
= 0;
5306 pSMB
->SetupCount
= 1;
5307 pSMB
->Reserved3
= 0;
5308 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5309 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
5310 inc_rfc1001_len(pSMB
, byte_count
);
5311 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5313 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5314 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5316 cifs_dbg(FYI
, "Send error in QFSDeviceInfo = %d\n", rc
);
5317 } else { /* decode response */
5318 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5320 if (rc
|| get_bcc(&pSMBr
->hdr
) <
5321 sizeof(FILE_SYSTEM_DEVICE_INFO
))
5322 rc
= -EIO
; /* bad smb */
5324 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5326 (FILE_SYSTEM_DEVICE_INFO
*)
5327 (((char *) &pSMBr
->hdr
.Protocol
) +
5329 memcpy(&tcon
->fsDevInfo
, response_data
,
5330 sizeof(FILE_SYSTEM_DEVICE_INFO
));
5333 cifs_buf_release(pSMB
);
5336 goto QFSDeviceRetry
;
5342 CIFSSMBQFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5344 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5345 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5346 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5347 FILE_SYSTEM_UNIX_INFO
*response_data
;
5349 int bytes_returned
= 0;
5350 __u16 params
, byte_count
;
5352 cifs_dbg(FYI
, "In QFSUnixInfo\n");
5354 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5355 (void **) &pSMB
, (void **) &pSMBr
);
5359 params
= 2; /* level */
5360 pSMB
->TotalDataCount
= 0;
5361 pSMB
->DataCount
= 0;
5362 pSMB
->DataOffset
= 0;
5363 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5364 /* BB find exact max SMB PDU from sess structure BB */
5365 pSMB
->MaxDataCount
= cpu_to_le16(100);
5366 pSMB
->MaxSetupCount
= 0;
5370 pSMB
->Reserved2
= 0;
5371 byte_count
= params
+ 1 /* pad */ ;
5372 pSMB
->ParameterCount
= cpu_to_le16(params
);
5373 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5374 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5375 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5376 pSMB
->SetupCount
= 1;
5377 pSMB
->Reserved3
= 0;
5378 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5379 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
5380 inc_rfc1001_len(pSMB
, byte_count
);
5381 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5383 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5384 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5386 cifs_dbg(VFS
, "Send error in QFSUnixInfo = %d\n", rc
);
5387 } else { /* decode response */
5388 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5390 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5391 rc
= -EIO
; /* bad smb */
5393 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5395 (FILE_SYSTEM_UNIX_INFO
5396 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5398 memcpy(&tcon
->fsUnixInfo
, response_data
,
5399 sizeof(FILE_SYSTEM_UNIX_INFO
));
5402 cifs_buf_release(pSMB
);
5412 CIFSSMBSetFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
, __u64 cap
)
5414 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5415 TRANSACTION2_SETFSI_REQ
*pSMB
= NULL
;
5416 TRANSACTION2_SETFSI_RSP
*pSMBr
= NULL
;
5418 int bytes_returned
= 0;
5419 __u16 params
, param_offset
, offset
, byte_count
;
5421 cifs_dbg(FYI
, "In SETFSUnixInfo\n");
5423 /* BB switch to small buf init to save memory */
5424 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5425 (void **) &pSMB
, (void **) &pSMBr
);
5429 params
= 4; /* 2 bytes zero followed by info level. */
5430 pSMB
->MaxSetupCount
= 0;
5434 pSMB
->Reserved2
= 0;
5435 param_offset
= offsetof(struct smb_com_transaction2_setfsi_req
, FileNum
)
5437 offset
= param_offset
+ params
;
5439 pSMB
->MaxParameterCount
= cpu_to_le16(4);
5440 /* BB find exact max SMB PDU from sess structure BB */
5441 pSMB
->MaxDataCount
= cpu_to_le16(100);
5442 pSMB
->SetupCount
= 1;
5443 pSMB
->Reserved3
= 0;
5444 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FS_INFORMATION
);
5445 byte_count
= 1 /* pad */ + params
+ 12;
5447 pSMB
->DataCount
= cpu_to_le16(12);
5448 pSMB
->ParameterCount
= cpu_to_le16(params
);
5449 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5450 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5451 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5452 pSMB
->DataOffset
= cpu_to_le16(offset
);
5456 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_CIFS_UNIX_INFO
);
5459 pSMB
->ClientUnixMajor
= cpu_to_le16(CIFS_UNIX_MAJOR_VERSION
);
5460 pSMB
->ClientUnixMinor
= cpu_to_le16(CIFS_UNIX_MINOR_VERSION
);
5461 pSMB
->ClientUnixCap
= cpu_to_le64(cap
);
5463 inc_rfc1001_len(pSMB
, byte_count
);
5464 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5466 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5467 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5469 cifs_dbg(VFS
, "Send error in SETFSUnixInfo = %d\n", rc
);
5470 } else { /* decode response */
5471 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5473 rc
= -EIO
; /* bad smb */
5475 cifs_buf_release(pSMB
);
5478 goto SETFSUnixRetry
;
5486 CIFSSMBQFSPosixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5487 struct kstatfs
*FSData
)
5489 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5490 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5491 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5492 FILE_SYSTEM_POSIX_INFO
*response_data
;
5494 int bytes_returned
= 0;
5495 __u16 params
, byte_count
;
5497 cifs_dbg(FYI
, "In QFSPosixInfo\n");
5499 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5504 params
= 2; /* level */
5505 pSMB
->TotalDataCount
= 0;
5506 pSMB
->DataCount
= 0;
5507 pSMB
->DataOffset
= 0;
5508 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5509 /* BB find exact max SMB PDU from sess structure BB */
5510 pSMB
->MaxDataCount
= cpu_to_le16(100);
5511 pSMB
->MaxSetupCount
= 0;
5515 pSMB
->Reserved2
= 0;
5516 byte_count
= params
+ 1 /* pad */ ;
5517 pSMB
->ParameterCount
= cpu_to_le16(params
);
5518 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5519 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5520 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5521 pSMB
->SetupCount
= 1;
5522 pSMB
->Reserved3
= 0;
5523 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5524 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_FS_INFO
);
5525 inc_rfc1001_len(pSMB
, byte_count
);
5526 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5528 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5529 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5531 cifs_dbg(FYI
, "Send error in QFSUnixInfo = %d\n", rc
);
5532 } else { /* decode response */
5533 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5535 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5536 rc
= -EIO
; /* bad smb */
5538 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5540 (FILE_SYSTEM_POSIX_INFO
5541 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5544 le32_to_cpu(response_data
->BlockSize
);
5546 le64_to_cpu(response_data
->TotalBlocks
);
5548 le64_to_cpu(response_data
->BlocksAvail
);
5549 if (response_data
->UserBlocksAvail
== cpu_to_le64(-1)) {
5550 FSData
->f_bavail
= FSData
->f_bfree
;
5553 le64_to_cpu(response_data
->UserBlocksAvail
);
5555 if (response_data
->TotalFileNodes
!= cpu_to_le64(-1))
5557 le64_to_cpu(response_data
->TotalFileNodes
);
5558 if (response_data
->FreeFileNodes
!= cpu_to_le64(-1))
5560 le64_to_cpu(response_data
->FreeFileNodes
);
5563 cifs_buf_release(pSMB
);
5573 * We can not use write of zero bytes trick to set file size due to need for
5574 * large file support. Also note that this SetPathInfo is preferred to
5575 * SetFileInfo based method in next routine which is only needed to work around
5576 * a sharing violation bugin Samba which this routine can run into.
5579 CIFSSMBSetEOF(const unsigned int xid
, struct cifs_tcon
*tcon
,
5580 const char *file_name
, __u64 size
, struct cifs_sb_info
*cifs_sb
,
5581 bool set_allocation
)
5583 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5584 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5585 struct file_end_of_file_info
*parm_data
;
5588 int bytes_returned
= 0;
5589 int remap
= cifs_remap(cifs_sb
);
5591 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
5593 cifs_dbg(FYI
, "In SetEOF\n");
5595 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5600 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5602 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5603 PATH_MAX
, cifs_sb
->local_nls
, remap
);
5604 name_len
++; /* trailing null */
5606 } else { /* BB improve the check for buffer overruns BB */
5607 name_len
= strnlen(file_name
, PATH_MAX
);
5608 name_len
++; /* trailing null */
5609 strncpy(pSMB
->FileName
, file_name
, name_len
);
5611 params
= 6 + name_len
;
5612 data_count
= sizeof(struct file_end_of_file_info
);
5613 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5614 pSMB
->MaxDataCount
= cpu_to_le16(4100);
5615 pSMB
->MaxSetupCount
= 0;
5619 pSMB
->Reserved2
= 0;
5620 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5621 InformationLevel
) - 4;
5622 offset
= param_offset
+ params
;
5623 if (set_allocation
) {
5624 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5625 pSMB
->InformationLevel
=
5626 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5628 pSMB
->InformationLevel
=
5629 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5630 } else /* Set File Size */ {
5631 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5632 pSMB
->InformationLevel
=
5633 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5635 pSMB
->InformationLevel
=
5636 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5640 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
5642 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5643 pSMB
->DataOffset
= cpu_to_le16(offset
);
5644 pSMB
->SetupCount
= 1;
5645 pSMB
->Reserved3
= 0;
5646 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5647 byte_count
= 3 /* pad */ + params
+ data_count
;
5648 pSMB
->DataCount
= cpu_to_le16(data_count
);
5649 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5650 pSMB
->ParameterCount
= cpu_to_le16(params
);
5651 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5652 pSMB
->Reserved4
= 0;
5653 inc_rfc1001_len(pSMB
, byte_count
);
5654 parm_data
->FileSize
= cpu_to_le64(size
);
5655 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5656 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5657 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5659 cifs_dbg(FYI
, "SetPathInfo (file size) returned %d\n", rc
);
5661 cifs_buf_release(pSMB
);
5670 CIFSSMBSetFileSize(const unsigned int xid
, struct cifs_tcon
*tcon
,
5671 struct cifsFileInfo
*cfile
, __u64 size
, bool set_allocation
)
5673 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5674 struct file_end_of_file_info
*parm_data
;
5676 __u16 params
, param_offset
, offset
, byte_count
, count
;
5678 cifs_dbg(FYI
, "SetFileSize (via SetFileInfo) %lld\n",
5680 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5685 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)cfile
->pid
);
5686 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(cfile
->pid
>> 16));
5689 pSMB
->MaxSetupCount
= 0;
5693 pSMB
->Reserved2
= 0;
5694 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5695 offset
= param_offset
+ params
;
5697 count
= sizeof(struct file_end_of_file_info
);
5698 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5699 /* BB find exact max SMB PDU from sess structure BB */
5700 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5701 pSMB
->SetupCount
= 1;
5702 pSMB
->Reserved3
= 0;
5703 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5704 byte_count
= 3 /* pad */ + params
+ count
;
5705 pSMB
->DataCount
= cpu_to_le16(count
);
5706 pSMB
->ParameterCount
= cpu_to_le16(params
);
5707 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5708 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5709 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5711 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
)
5713 pSMB
->DataOffset
= cpu_to_le16(offset
);
5714 parm_data
->FileSize
= cpu_to_le64(size
);
5715 pSMB
->Fid
= cfile
->fid
.netfid
;
5716 if (set_allocation
) {
5717 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5718 pSMB
->InformationLevel
=
5719 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5721 pSMB
->InformationLevel
=
5722 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5723 } else /* Set File Size */ {
5724 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5725 pSMB
->InformationLevel
=
5726 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5728 pSMB
->InformationLevel
=
5729 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5731 pSMB
->Reserved4
= 0;
5732 inc_rfc1001_len(pSMB
, byte_count
);
5733 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5734 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5736 cifs_dbg(FYI
, "Send error in SetFileInfo (SetFileSize) = %d\n",
5740 /* Note: On -EAGAIN error only caller can retry on handle based calls
5741 since file handle passed in no longer valid */
5746 /* Some legacy servers such as NT4 require that the file times be set on
5747 an open handle, rather than by pathname - this is awkward due to
5748 potential access conflicts on the open, but it is unavoidable for these
5749 old servers since the only other choice is to go from 100 nanosecond DCE
5750 time and resort to the original setpathinfo level which takes the ancient
5751 DOS time format with 2 second granularity */
5753 CIFSSMBSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5754 const FILE_BASIC_INFO
*data
, __u16 fid
, __u32 pid_of_opener
)
5756 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5759 __u16 params
, param_offset
, offset
, byte_count
, count
;
5761 cifs_dbg(FYI
, "Set Times (via SetFileInfo)\n");
5762 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5767 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5768 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5771 pSMB
->MaxSetupCount
= 0;
5775 pSMB
->Reserved2
= 0;
5776 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5777 offset
= param_offset
+ params
;
5779 data_offset
= (char *)pSMB
+
5780 offsetof(struct smb_hdr
, Protocol
) + offset
;
5782 count
= sizeof(FILE_BASIC_INFO
);
5783 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5784 /* BB find max SMB PDU from sess */
5785 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5786 pSMB
->SetupCount
= 1;
5787 pSMB
->Reserved3
= 0;
5788 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5789 byte_count
= 3 /* pad */ + params
+ count
;
5790 pSMB
->DataCount
= cpu_to_le16(count
);
5791 pSMB
->ParameterCount
= cpu_to_le16(params
);
5792 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5793 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5794 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5795 pSMB
->DataOffset
= cpu_to_le16(offset
);
5797 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5798 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5800 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5801 pSMB
->Reserved4
= 0;
5802 inc_rfc1001_len(pSMB
, byte_count
);
5803 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5804 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5805 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5807 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5810 /* Note: On -EAGAIN error only caller can retry on handle based calls
5811 since file handle passed in no longer valid */
5817 CIFSSMBSetFileDisposition(const unsigned int xid
, struct cifs_tcon
*tcon
,
5818 bool delete_file
, __u16 fid
, __u32 pid_of_opener
)
5820 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5823 __u16 params
, param_offset
, offset
, byte_count
, count
;
5825 cifs_dbg(FYI
, "Set File Disposition (via SetFileInfo)\n");
5826 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5831 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5832 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5835 pSMB
->MaxSetupCount
= 0;
5839 pSMB
->Reserved2
= 0;
5840 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5841 offset
= param_offset
+ params
;
5843 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5846 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5847 /* BB find max SMB PDU from sess */
5848 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5849 pSMB
->SetupCount
= 1;
5850 pSMB
->Reserved3
= 0;
5851 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5852 byte_count
= 3 /* pad */ + params
+ count
;
5853 pSMB
->DataCount
= cpu_to_le16(count
);
5854 pSMB
->ParameterCount
= cpu_to_le16(params
);
5855 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5856 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5857 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5858 pSMB
->DataOffset
= cpu_to_le16(offset
);
5860 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO
);
5861 pSMB
->Reserved4
= 0;
5862 inc_rfc1001_len(pSMB
, byte_count
);
5863 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5864 *data_offset
= delete_file
? 1 : 0;
5865 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5867 cifs_dbg(FYI
, "Send error in SetFileDisposition = %d\n", rc
);
5873 CIFSSMBSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5874 const char *fileName
, const FILE_BASIC_INFO
*data
,
5875 const struct nls_table
*nls_codepage
, int remap
)
5877 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5878 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5881 int bytes_returned
= 0;
5883 __u16 params
, param_offset
, offset
, byte_count
, count
;
5885 cifs_dbg(FYI
, "In SetTimes\n");
5888 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5893 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5895 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5896 PATH_MAX
, nls_codepage
, remap
);
5897 name_len
++; /* trailing null */
5899 } else { /* BB improve the check for buffer overruns BB */
5900 name_len
= strnlen(fileName
, PATH_MAX
);
5901 name_len
++; /* trailing null */
5902 strncpy(pSMB
->FileName
, fileName
, name_len
);
5905 params
= 6 + name_len
;
5906 count
= sizeof(FILE_BASIC_INFO
);
5907 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5908 /* BB find max SMB PDU from sess structure BB */
5909 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5910 pSMB
->MaxSetupCount
= 0;
5914 pSMB
->Reserved2
= 0;
5915 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5916 InformationLevel
) - 4;
5917 offset
= param_offset
+ params
;
5918 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5919 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5920 pSMB
->DataOffset
= cpu_to_le16(offset
);
5921 pSMB
->SetupCount
= 1;
5922 pSMB
->Reserved3
= 0;
5923 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5924 byte_count
= 3 /* pad */ + params
+ count
;
5926 pSMB
->DataCount
= cpu_to_le16(count
);
5927 pSMB
->ParameterCount
= cpu_to_le16(params
);
5928 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5929 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5930 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5931 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5933 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5934 pSMB
->Reserved4
= 0;
5935 inc_rfc1001_len(pSMB
, byte_count
);
5936 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5937 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5938 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5939 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5941 cifs_dbg(FYI
, "SetPathInfo (times) returned %d\n", rc
);
5943 cifs_buf_release(pSMB
);
5951 /* Can not be used to set time stamps yet (due to old DOS time format) */
5952 /* Can be used to set attributes */
5953 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5954 handling it anyway and NT4 was what we thought it would be needed for
5955 Do not delete it until we prove whether needed for Win9x though */
5957 CIFSSMBSetAttrLegacy(unsigned int xid
, struct cifs_tcon
*tcon
, char *fileName
,
5958 __u16 dos_attrs
, const struct nls_table
*nls_codepage
)
5960 SETATTR_REQ
*pSMB
= NULL
;
5961 SETATTR_RSP
*pSMBr
= NULL
;
5966 cifs_dbg(FYI
, "In SetAttrLegacy\n");
5969 rc
= smb_init(SMB_COM_SETATTR
, 8, tcon
, (void **) &pSMB
,
5974 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5976 ConvertToUTF16((__le16
*) pSMB
->fileName
, fileName
,
5977 PATH_MAX
, nls_codepage
);
5978 name_len
++; /* trailing null */
5980 } else { /* BB improve the check for buffer overruns BB */
5981 name_len
= strnlen(fileName
, PATH_MAX
);
5982 name_len
++; /* trailing null */
5983 strncpy(pSMB
->fileName
, fileName
, name_len
);
5985 pSMB
->attr
= cpu_to_le16(dos_attrs
);
5986 pSMB
->BufferFormat
= 0x04;
5987 inc_rfc1001_len(pSMB
, name_len
+ 1);
5988 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
5989 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5990 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5992 cifs_dbg(FYI
, "Error in LegacySetAttr = %d\n", rc
);
5994 cifs_buf_release(pSMB
);
5997 goto SetAttrLgcyRetry
;
6001 #endif /* temporarily unneeded SetAttr legacy function */
6004 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO
*data_offset
,
6005 const struct cifs_unix_set_info_args
*args
)
6007 u64 uid
= NO_CHANGE_64
, gid
= NO_CHANGE_64
;
6008 u64 mode
= args
->mode
;
6010 if (uid_valid(args
->uid
))
6011 uid
= from_kuid(&init_user_ns
, args
->uid
);
6012 if (gid_valid(args
->gid
))
6013 gid
= from_kgid(&init_user_ns
, args
->gid
);
6016 * Samba server ignores set of file size to zero due to bugs in some
6017 * older clients, but we should be precise - we use SetFileSize to
6018 * set file size and do not want to truncate file size to zero
6019 * accidentally as happened on one Samba server beta by putting
6020 * zero instead of -1 here
6022 data_offset
->EndOfFile
= cpu_to_le64(NO_CHANGE_64
);
6023 data_offset
->NumOfBytes
= cpu_to_le64(NO_CHANGE_64
);
6024 data_offset
->LastStatusChange
= cpu_to_le64(args
->ctime
);
6025 data_offset
->LastAccessTime
= cpu_to_le64(args
->atime
);
6026 data_offset
->LastModificationTime
= cpu_to_le64(args
->mtime
);
6027 data_offset
->Uid
= cpu_to_le64(uid
);
6028 data_offset
->Gid
= cpu_to_le64(gid
);
6029 /* better to leave device as zero when it is */
6030 data_offset
->DevMajor
= cpu_to_le64(MAJOR(args
->device
));
6031 data_offset
->DevMinor
= cpu_to_le64(MINOR(args
->device
));
6032 data_offset
->Permissions
= cpu_to_le64(mode
);
6035 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
6036 else if (S_ISDIR(mode
))
6037 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
6038 else if (S_ISLNK(mode
))
6039 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
6040 else if (S_ISCHR(mode
))
6041 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
6042 else if (S_ISBLK(mode
))
6043 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
6044 else if (S_ISFIFO(mode
))
6045 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
6046 else if (S_ISSOCK(mode
))
6047 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
6051 CIFSSMBUnixSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6052 const struct cifs_unix_set_info_args
*args
,
6053 u16 fid
, u32 pid_of_opener
)
6055 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
6058 u16 params
, param_offset
, offset
, byte_count
, count
;
6060 cifs_dbg(FYI
, "Set Unix Info (via SetFileInfo)\n");
6061 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
6066 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
6067 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
6070 pSMB
->MaxSetupCount
= 0;
6074 pSMB
->Reserved2
= 0;
6075 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
6076 offset
= param_offset
+ params
;
6078 data_offset
= (char *)pSMB
+
6079 offsetof(struct smb_hdr
, Protocol
) + offset
;
6081 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6083 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6084 /* BB find max SMB PDU from sess */
6085 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6086 pSMB
->SetupCount
= 1;
6087 pSMB
->Reserved3
= 0;
6088 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
6089 byte_count
= 3 /* pad */ + params
+ count
;
6090 pSMB
->DataCount
= cpu_to_le16(count
);
6091 pSMB
->ParameterCount
= cpu_to_le16(params
);
6092 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6093 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6094 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6095 pSMB
->DataOffset
= cpu_to_le16(offset
);
6097 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6098 pSMB
->Reserved4
= 0;
6099 inc_rfc1001_len(pSMB
, byte_count
);
6100 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6102 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO
*)data_offset
, args
);
6104 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
6106 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
6109 /* Note: On -EAGAIN error only caller can retry on handle based calls
6110 since file handle passed in no longer valid */
6116 CIFSSMBUnixSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6117 const char *file_name
,
6118 const struct cifs_unix_set_info_args
*args
,
6119 const struct nls_table
*nls_codepage
, int remap
)
6121 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
6122 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
6125 int bytes_returned
= 0;
6126 FILE_UNIX_BASIC_INFO
*data_offset
;
6127 __u16 params
, param_offset
, offset
, count
, byte_count
;
6129 cifs_dbg(FYI
, "In SetUID/GID/Mode\n");
6131 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6136 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6138 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
6139 PATH_MAX
, nls_codepage
, remap
);
6140 name_len
++; /* trailing null */
6142 } else { /* BB improve the check for buffer overruns BB */
6143 name_len
= strnlen(file_name
, PATH_MAX
);
6144 name_len
++; /* trailing null */
6145 strncpy(pSMB
->FileName
, file_name
, name_len
);
6148 params
= 6 + name_len
;
6149 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6150 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6151 /* BB find max SMB PDU from sess structure BB */
6152 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6153 pSMB
->MaxSetupCount
= 0;
6157 pSMB
->Reserved2
= 0;
6158 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6159 InformationLevel
) - 4;
6160 offset
= param_offset
+ params
;
6162 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
6164 memset(data_offset
, 0, count
);
6165 pSMB
->DataOffset
= cpu_to_le16(offset
);
6166 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6167 pSMB
->SetupCount
= 1;
6168 pSMB
->Reserved3
= 0;
6169 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6170 byte_count
= 3 /* pad */ + params
+ count
;
6171 pSMB
->ParameterCount
= cpu_to_le16(params
);
6172 pSMB
->DataCount
= cpu_to_le16(count
);
6173 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6174 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6175 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6176 pSMB
->Reserved4
= 0;
6177 inc_rfc1001_len(pSMB
, byte_count
);
6179 cifs_fill_unix_set_info(data_offset
, args
);
6181 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6182 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6183 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6185 cifs_dbg(FYI
, "SetPathInfo (perms) returned %d\n", rc
);
6187 cifs_buf_release(pSMB
);
6193 #ifdef CONFIG_CIFS_XATTR
6195 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6196 * function used by listxattr and getxattr type calls. When ea_name is set,
6197 * it looks for that attribute name and stuffs that value into the EAData
6198 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6199 * buffer. In both cases, the return value is either the length of the
6200 * resulting data or a negative error code. If EAData is a NULL pointer then
6201 * the data isn't copied to it, but the length is returned.
6204 CIFSSMBQAllEAs(const unsigned int xid
, struct cifs_tcon
*tcon
,
6205 const unsigned char *searchName
, const unsigned char *ea_name
,
6206 char *EAData
, size_t buf_size
,
6207 const struct nls_table
*nls_codepage
, int remap
)
6209 /* BB assumes one setup word */
6210 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
6211 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
6215 struct fealist
*ea_response_data
;
6216 struct fea
*temp_fea
;
6219 __u16 params
, byte_count
, data_offset
;
6220 unsigned int ea_name_len
= ea_name
? strlen(ea_name
) : 0;
6222 cifs_dbg(FYI
, "In Query All EAs path %s\n", searchName
);
6224 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6229 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6231 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
6232 PATH_MAX
, nls_codepage
, remap
);
6233 list_len
++; /* trailing null */
6235 } else { /* BB improve the check for buffer overruns BB */
6236 list_len
= strnlen(searchName
, PATH_MAX
);
6237 list_len
++; /* trailing null */
6238 strncpy(pSMB
->FileName
, searchName
, list_len
);
6241 params
= 2 /* level */ + 4 /* reserved */ + list_len
/* includes NUL */;
6242 pSMB
->TotalDataCount
= 0;
6243 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6244 /* BB find exact max SMB PDU from sess structure BB */
6245 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
6246 pSMB
->MaxSetupCount
= 0;
6250 pSMB
->Reserved2
= 0;
6251 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
6252 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
6253 pSMB
->DataCount
= 0;
6254 pSMB
->DataOffset
= 0;
6255 pSMB
->SetupCount
= 1;
6256 pSMB
->Reserved3
= 0;
6257 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
6258 byte_count
= params
+ 1 /* pad */ ;
6259 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
6260 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6261 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
6262 pSMB
->Reserved4
= 0;
6263 inc_rfc1001_len(pSMB
, byte_count
);
6264 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6266 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6267 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6269 cifs_dbg(FYI
, "Send error in QueryAllEAs = %d\n", rc
);
6274 /* BB also check enough total bytes returned */
6275 /* BB we need to improve the validity checking
6276 of these trans2 responses */
6278 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
6279 if (rc
|| get_bcc(&pSMBr
->hdr
) < 4) {
6280 rc
= -EIO
; /* bad smb */
6284 /* check that length of list is not more than bcc */
6285 /* check that each entry does not go beyond length
6287 /* check that each element of each entry does not
6288 go beyond end of list */
6289 /* validate_trans2_offsets() */
6290 /* BB check if start of smb + data_offset > &bcc+ bcc */
6292 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
6293 ea_response_data
= (struct fealist
*)
6294 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
6296 list_len
= le32_to_cpu(ea_response_data
->list_len
);
6297 cifs_dbg(FYI
, "ea length %d\n", list_len
);
6298 if (list_len
<= 8) {
6299 cifs_dbg(FYI
, "empty EA list returned from server\n");
6300 /* didn't find the named attribute */
6306 /* make sure list_len doesn't go past end of SMB */
6307 end_of_smb
= (char *)pByteArea(&pSMBr
->hdr
) + get_bcc(&pSMBr
->hdr
);
6308 if ((char *)ea_response_data
+ list_len
> end_of_smb
) {
6309 cifs_dbg(FYI
, "EA list appears to go beyond SMB\n");
6314 /* account for ea list len */
6316 temp_fea
= ea_response_data
->list
;
6317 temp_ptr
= (char *)temp_fea
;
6318 while (list_len
> 0) {
6319 unsigned int name_len
;
6324 /* make sure we can read name_len and value_len */
6326 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6331 name_len
= temp_fea
->name_len
;
6332 value_len
= le16_to_cpu(temp_fea
->value_len
);
6333 list_len
-= name_len
+ 1 + value_len
;
6335 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6341 if (ea_name_len
== name_len
&&
6342 memcmp(ea_name
, temp_ptr
, name_len
) == 0) {
6343 temp_ptr
+= name_len
+ 1;
6347 if ((size_t)value_len
> buf_size
) {
6351 memcpy(EAData
, temp_ptr
, value_len
);
6355 /* account for prefix user. and trailing null */
6356 rc
+= (5 + 1 + name_len
);
6357 if (rc
< (int) buf_size
) {
6358 memcpy(EAData
, "user.", 5);
6360 memcpy(EAData
, temp_ptr
, name_len
);
6362 /* null terminate name */
6365 } else if (buf_size
== 0) {
6366 /* skip copy - calc size only */
6368 /* stop before overrun buffer */
6373 temp_ptr
+= name_len
+ 1 + value_len
;
6374 temp_fea
= (struct fea
*)temp_ptr
;
6377 /* didn't find the named attribute */
6382 cifs_buf_release(pSMB
);
6390 CIFSSMBSetEA(const unsigned int xid
, struct cifs_tcon
*tcon
,
6391 const char *fileName
, const char *ea_name
, const void *ea_value
,
6392 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
,
6395 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
6396 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
6397 struct fealist
*parm_data
;
6400 int bytes_returned
= 0;
6401 __u16 params
, param_offset
, byte_count
, offset
, count
;
6403 cifs_dbg(FYI
, "In SetEA\n");
6405 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6410 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6412 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
6413 PATH_MAX
, nls_codepage
, remap
);
6414 name_len
++; /* trailing null */
6416 } else { /* BB improve the check for buffer overruns BB */
6417 name_len
= strnlen(fileName
, PATH_MAX
);
6418 name_len
++; /* trailing null */
6419 strncpy(pSMB
->FileName
, fileName
, name_len
);
6422 params
= 6 + name_len
;
6424 /* done calculating parms using name_len of file name,
6425 now use name_len to calculate length of ea name
6426 we are going to create in the inode xattrs */
6427 if (ea_name
== NULL
)
6430 name_len
= strnlen(ea_name
, 255);
6432 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
;
6433 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6434 /* BB find max SMB PDU from sess */
6435 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6436 pSMB
->MaxSetupCount
= 0;
6440 pSMB
->Reserved2
= 0;
6441 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6442 InformationLevel
) - 4;
6443 offset
= param_offset
+ params
;
6444 pSMB
->InformationLevel
=
6445 cpu_to_le16(SMB_SET_FILE_EA
);
6447 parm_data
= (void *)pSMB
+ offsetof(struct smb_hdr
, Protocol
) + offset
;
6448 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6449 pSMB
->DataOffset
= cpu_to_le16(offset
);
6450 pSMB
->SetupCount
= 1;
6451 pSMB
->Reserved3
= 0;
6452 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6453 byte_count
= 3 /* pad */ + params
+ count
;
6454 pSMB
->DataCount
= cpu_to_le16(count
);
6455 parm_data
->list_len
= cpu_to_le32(count
);
6456 parm_data
->list
[0].EA_flags
= 0;
6457 /* we checked above that name len is less than 255 */
6458 parm_data
->list
[0].name_len
= (__u8
)name_len
;
6459 /* EA names are always ASCII */
6461 strncpy(parm_data
->list
[0].name
, ea_name
, name_len
);
6462 parm_data
->list
[0].name
[name_len
] = 0;
6463 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
6464 /* caller ensures that ea_value_len is less than 64K but
6465 we need to ensure that it fits within the smb */
6467 /*BB add length check to see if it would fit in
6468 negotiated SMB buffer size BB */
6469 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6471 memcpy(parm_data
->list
[0].name
+name_len
+1,
6472 ea_value
, ea_value_len
);
6474 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6475 pSMB
->ParameterCount
= cpu_to_le16(params
);
6476 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6477 pSMB
->Reserved4
= 0;
6478 inc_rfc1001_len(pSMB
, byte_count
);
6479 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6480 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6481 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6483 cifs_dbg(FYI
, "SetPathInfo (EA) returned %d\n", rc
);
6485 cifs_buf_release(pSMB
);
6494 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6496 * Years ago the kernel added a "dnotify" function for Samba server,
6497 * to allow network clients (such as Windows) to display updated
6498 * lists of files in directory listings automatically when
6499 * files are added by one user when another user has the
6500 * same directory open on their desktop. The Linux cifs kernel
6501 * client hooked into the kernel side of this interface for
6502 * the same reason, but ironically when the VFS moved from
6503 * "dnotify" to "inotify" it became harder to plug in Linux
6504 * network file system clients (the most obvious use case
6505 * for notify interfaces is when multiple users can update
6506 * the contents of the same directory - exactly what network
6507 * file systems can do) although the server (Samba) could
6508 * still use it. For the short term we leave the worker
6509 * function ifdeffed out (below) until inotify is fixed
6510 * in the VFS to make it easier to plug in network file
6511 * system clients. If inotify turns out to be permanently
6512 * incompatible for network fs clients, we could instead simply
6513 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6515 int CIFSSMBNotify(const unsigned int xid
, struct cifs_tcon
*tcon
,
6516 const int notify_subdirs
, const __u16 netfid
,
6517 __u32 filter
, struct file
*pfile
, int multishot
,
6518 const struct nls_table
*nls_codepage
)
6521 struct smb_com_transaction_change_notify_req
*pSMB
= NULL
;
6522 struct smb_com_ntransaction_change_notify_rsp
*pSMBr
= NULL
;
6523 struct dir_notify_req
*dnotify_req
;
6526 cifs_dbg(FYI
, "In CIFSSMBNotify for file handle %d\n", (int)netfid
);
6527 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
6532 pSMB
->TotalParameterCount
= 0 ;
6533 pSMB
->TotalDataCount
= 0;
6534 pSMB
->MaxParameterCount
= cpu_to_le32(2);
6535 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
6536 pSMB
->MaxSetupCount
= 4;
6538 pSMB
->ParameterOffset
= 0;
6539 pSMB
->DataCount
= 0;
6540 pSMB
->DataOffset
= 0;
6541 pSMB
->SetupCount
= 4; /* single byte does not need le conversion */
6542 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE
);
6543 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6545 pSMB
->WatchTree
= 1; /* one byte - no le conversion needed */
6546 pSMB
->Reserved2
= 0;
6547 pSMB
->CompletionFilter
= cpu_to_le32(filter
);
6548 pSMB
->Fid
= netfid
; /* file handle always le */
6549 pSMB
->ByteCount
= 0;
6551 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6552 (struct smb_hdr
*)pSMBr
, &bytes_returned
,
6555 cifs_dbg(FYI
, "Error in Notify = %d\n", rc
);
6557 /* Add file to outstanding requests */
6558 /* BB change to kmem cache alloc */
6559 dnotify_req
= kmalloc(
6560 sizeof(struct dir_notify_req
),
6563 dnotify_req
->Pid
= pSMB
->hdr
.Pid
;
6564 dnotify_req
->PidHigh
= pSMB
->hdr
.PidHigh
;
6565 dnotify_req
->Mid
= pSMB
->hdr
.Mid
;
6566 dnotify_req
->Tid
= pSMB
->hdr
.Tid
;
6567 dnotify_req
->Uid
= pSMB
->hdr
.Uid
;
6568 dnotify_req
->netfid
= netfid
;
6569 dnotify_req
->pfile
= pfile
;
6570 dnotify_req
->filter
= filter
;
6571 dnotify_req
->multishot
= multishot
;
6572 spin_lock(&GlobalMid_Lock
);
6573 list_add_tail(&dnotify_req
->lhead
,
6574 &GlobalDnotifyReqList
);
6575 spin_unlock(&GlobalMid_Lock
);
6579 cifs_buf_release(pSMB
);
6582 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */