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 <linux/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
;
500 unsigned long utc
= ktime_get_real_seconds();
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
,
505 (int)(utc
- ts
.tv_sec
));
506 val
= (int)(utc
- 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);
699 cifs_small_buf_release(smb_buffer
);
701 cifs_dbg(FYI
, "Tree disconnect failed %d\n", rc
);
703 /* No need to return error on this operation if tid invalidated and
704 closed on server already e.g. due to tcp session crashing */
712 * This is a no-op for now. We're not really interested in the reply, but
713 * rather in the fact that the server sent one and that server->lstrp
716 * FIXME: maybe we should consider checking that the reply matches request?
719 cifs_echo_callback(struct mid_q_entry
*mid
)
721 struct TCP_Server_Info
*server
= mid
->callback_data
;
723 DeleteMidQEntry(mid
);
724 add_credits(server
, 1, CIFS_ECHO_OP
);
728 CIFSSMBEcho(struct TCP_Server_Info
*server
)
733 struct smb_rqst rqst
= { .rq_iov
= iov
,
736 cifs_dbg(FYI
, "In echo request\n");
738 rc
= small_smb_init(SMB_COM_ECHO
, 0, NULL
, (void **)&smb
);
742 if (server
->capabilities
& CAP_UNICODE
)
743 smb
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
745 /* set up echo request */
746 smb
->hdr
.Tid
= 0xffff;
747 smb
->hdr
.WordCount
= 1;
748 put_unaligned_le16(1, &smb
->EchoCount
);
749 put_bcc(1, &smb
->hdr
);
751 inc_rfc1001_len(smb
, 3);
754 iov
[0].iov_base
= smb
;
755 iov
[1].iov_len
= get_rfc1002_length(smb
);
756 iov
[1].iov_base
= (char *)smb
+ 4;
758 rc
= cifs_call_async(server
, &rqst
, NULL
, cifs_echo_callback
, NULL
,
759 server
, CIFS_ASYNC_OP
| CIFS_ECHO_OP
);
761 cifs_dbg(FYI
, "Echo request failed: %d\n", rc
);
763 cifs_small_buf_release(smb
);
769 CIFSSMBLogoff(const unsigned int xid
, struct cifs_ses
*ses
)
771 LOGOFF_ANDX_REQ
*pSMB
;
774 cifs_dbg(FYI
, "In SMBLogoff for session disconnect\n");
777 * BB: do we need to check validity of ses and server? They should
778 * always be valid since we have an active reference. If not, that
779 * should probably be a BUG()
781 if (!ses
|| !ses
->server
)
784 mutex_lock(&ses
->session_mutex
);
785 if (ses
->need_reconnect
)
786 goto session_already_dead
; /* no need to send SMBlogoff if uid
787 already closed due to reconnect */
788 rc
= small_smb_init(SMB_COM_LOGOFF_ANDX
, 2, NULL
, (void **)&pSMB
);
790 mutex_unlock(&ses
->session_mutex
);
794 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
796 if (ses
->server
->sign
)
797 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
799 pSMB
->hdr
.Uid
= ses
->Suid
;
801 pSMB
->AndXCommand
= 0xFF;
802 rc
= SendReceiveNoRsp(xid
, ses
, (char *) pSMB
, 0);
803 cifs_small_buf_release(pSMB
);
804 session_already_dead
:
805 mutex_unlock(&ses
->session_mutex
);
807 /* if session dead then we do not need to do ulogoff,
808 since server closed smb session, no sense reporting
816 CIFSPOSIXDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
,
817 const char *fileName
, __u16 type
,
818 const struct nls_table
*nls_codepage
, int remap
)
820 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
821 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
822 struct unlink_psx_rq
*pRqD
;
825 int bytes_returned
= 0;
826 __u16 params
, param_offset
, offset
, byte_count
;
828 cifs_dbg(FYI
, "In POSIX delete\n");
830 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
835 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
837 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
838 PATH_MAX
, nls_codepage
, remap
);
839 name_len
++; /* trailing null */
841 } else { /* BB add path length overrun check */
842 name_len
= strnlen(fileName
, PATH_MAX
);
843 name_len
++; /* trailing null */
844 strncpy(pSMB
->FileName
, fileName
, name_len
);
847 params
= 6 + name_len
;
848 pSMB
->MaxParameterCount
= cpu_to_le16(2);
849 pSMB
->MaxDataCount
= 0; /* BB double check this with jra */
850 pSMB
->MaxSetupCount
= 0;
855 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
856 InformationLevel
) - 4;
857 offset
= param_offset
+ params
;
859 /* Setup pointer to Request Data (inode type) */
860 pRqD
= (struct unlink_psx_rq
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
861 pRqD
->type
= cpu_to_le16(type
);
862 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
863 pSMB
->DataOffset
= cpu_to_le16(offset
);
864 pSMB
->SetupCount
= 1;
866 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
867 byte_count
= 3 /* pad */ + params
+ sizeof(struct unlink_psx_rq
);
869 pSMB
->DataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
870 pSMB
->TotalDataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
871 pSMB
->ParameterCount
= cpu_to_le16(params
);
872 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
873 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_UNLINK
);
875 inc_rfc1001_len(pSMB
, byte_count
);
876 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
877 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
878 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
880 cifs_dbg(FYI
, "Posix delete returned %d\n", rc
);
881 cifs_buf_release(pSMB
);
883 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
892 CIFSSMBDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
893 struct cifs_sb_info
*cifs_sb
)
895 DELETE_FILE_REQ
*pSMB
= NULL
;
896 DELETE_FILE_RSP
*pSMBr
= NULL
;
900 int remap
= cifs_remap(cifs_sb
);
903 rc
= smb_init(SMB_COM_DELETE
, 1, tcon
, (void **) &pSMB
,
908 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
909 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->fileName
, name
,
910 PATH_MAX
, cifs_sb
->local_nls
,
912 name_len
++; /* trailing null */
914 } else { /* BB improve check for buffer overruns BB */
915 name_len
= strnlen(name
, PATH_MAX
);
916 name_len
++; /* trailing null */
917 strncpy(pSMB
->fileName
, name
, name_len
);
919 pSMB
->SearchAttributes
=
920 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
);
921 pSMB
->BufferFormat
= 0x04;
922 inc_rfc1001_len(pSMB
, name_len
+ 1);
923 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
924 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
925 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
926 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
928 cifs_dbg(FYI
, "Error in RMFile = %d\n", rc
);
930 cifs_buf_release(pSMB
);
938 CIFSSMBRmDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
939 struct cifs_sb_info
*cifs_sb
)
941 DELETE_DIRECTORY_REQ
*pSMB
= NULL
;
942 DELETE_DIRECTORY_RSP
*pSMBr
= NULL
;
946 int remap
= cifs_remap(cifs_sb
);
948 cifs_dbg(FYI
, "In CIFSSMBRmDir\n");
950 rc
= smb_init(SMB_COM_DELETE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
955 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
956 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
957 PATH_MAX
, cifs_sb
->local_nls
,
959 name_len
++; /* trailing null */
961 } else { /* BB improve check for buffer overruns BB */
962 name_len
= strnlen(name
, PATH_MAX
);
963 name_len
++; /* trailing null */
964 strncpy(pSMB
->DirName
, name
, name_len
);
967 pSMB
->BufferFormat
= 0x04;
968 inc_rfc1001_len(pSMB
, name_len
+ 1);
969 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
970 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
971 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
972 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_rmdirs
);
974 cifs_dbg(FYI
, "Error in RMDir = %d\n", rc
);
976 cifs_buf_release(pSMB
);
983 CIFSSMBMkDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
984 struct cifs_sb_info
*cifs_sb
)
987 CREATE_DIRECTORY_REQ
*pSMB
= NULL
;
988 CREATE_DIRECTORY_RSP
*pSMBr
= NULL
;
991 int remap
= cifs_remap(cifs_sb
);
993 cifs_dbg(FYI
, "In CIFSSMBMkDir\n");
995 rc
= smb_init(SMB_COM_CREATE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
1000 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1001 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
1002 PATH_MAX
, cifs_sb
->local_nls
,
1004 name_len
++; /* trailing null */
1006 } else { /* BB improve check for buffer overruns BB */
1007 name_len
= strnlen(name
, PATH_MAX
);
1008 name_len
++; /* trailing null */
1009 strncpy(pSMB
->DirName
, name
, name_len
);
1012 pSMB
->BufferFormat
= 0x04;
1013 inc_rfc1001_len(pSMB
, name_len
+ 1);
1014 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1015 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1016 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1017 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_mkdirs
);
1019 cifs_dbg(FYI
, "Error in Mkdir = %d\n", rc
);
1021 cifs_buf_release(pSMB
);
1028 CIFSPOSIXCreate(const unsigned int xid
, struct cifs_tcon
*tcon
,
1029 __u32 posix_flags
, __u64 mode
, __u16
*netfid
,
1030 FILE_UNIX_BASIC_INFO
*pRetData
, __u32
*pOplock
,
1031 const char *name
, const struct nls_table
*nls_codepage
,
1034 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
1035 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
1038 int bytes_returned
= 0;
1039 __u16 params
, param_offset
, offset
, byte_count
, count
;
1040 OPEN_PSX_REQ
*pdata
;
1041 OPEN_PSX_RSP
*psx_rsp
;
1043 cifs_dbg(FYI
, "In POSIX Create\n");
1045 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1050 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1052 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, name
,
1053 PATH_MAX
, nls_codepage
, remap
);
1054 name_len
++; /* trailing null */
1056 } else { /* BB improve the check for buffer overruns BB */
1057 name_len
= strnlen(name
, PATH_MAX
);
1058 name_len
++; /* trailing null */
1059 strncpy(pSMB
->FileName
, name
, name_len
);
1062 params
= 6 + name_len
;
1063 count
= sizeof(OPEN_PSX_REQ
);
1064 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1065 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* large enough */
1066 pSMB
->MaxSetupCount
= 0;
1070 pSMB
->Reserved2
= 0;
1071 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
1072 InformationLevel
) - 4;
1073 offset
= param_offset
+ params
;
1074 pdata
= (OPEN_PSX_REQ
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
1075 pdata
->Level
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
1076 pdata
->Permissions
= cpu_to_le64(mode
);
1077 pdata
->PosixOpenFlags
= cpu_to_le32(posix_flags
);
1078 pdata
->OpenFlags
= cpu_to_le32(*pOplock
);
1079 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
1080 pSMB
->DataOffset
= cpu_to_le16(offset
);
1081 pSMB
->SetupCount
= 1;
1082 pSMB
->Reserved3
= 0;
1083 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
1084 byte_count
= 3 /* pad */ + params
+ count
;
1086 pSMB
->DataCount
= cpu_to_le16(count
);
1087 pSMB
->ParameterCount
= cpu_to_le16(params
);
1088 pSMB
->TotalDataCount
= pSMB
->DataCount
;
1089 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1090 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_OPEN
);
1091 pSMB
->Reserved4
= 0;
1092 inc_rfc1001_len(pSMB
, byte_count
);
1093 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1094 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1095 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1097 cifs_dbg(FYI
, "Posix create returned %d\n", rc
);
1098 goto psx_create_err
;
1101 cifs_dbg(FYI
, "copying inode info\n");
1102 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
1104 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)) {
1105 rc
= -EIO
; /* bad smb */
1106 goto psx_create_err
;
1109 /* copy return information to pRetData */
1110 psx_rsp
= (OPEN_PSX_RSP
*)((char *) &pSMBr
->hdr
.Protocol
1111 + le16_to_cpu(pSMBr
->t2
.DataOffset
));
1113 *pOplock
= le16_to_cpu(psx_rsp
->OplockFlags
);
1115 *netfid
= psx_rsp
->Fid
; /* cifs fid stays in le */
1116 /* Let caller know file was created so we can set the mode. */
1117 /* Do we care about the CreateAction in any other cases? */
1118 if (cpu_to_le32(FILE_CREATE
) == psx_rsp
->CreateAction
)
1119 *pOplock
|= CIFS_CREATE_ACTION
;
1120 /* check to make sure response data is there */
1121 if (psx_rsp
->ReturnedLevel
!= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
)) {
1122 pRetData
->Type
= cpu_to_le32(-1); /* unknown */
1123 cifs_dbg(NOISY
, "unknown type\n");
1125 if (get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)
1126 + sizeof(FILE_UNIX_BASIC_INFO
)) {
1127 cifs_dbg(VFS
, "Open response data too small\n");
1128 pRetData
->Type
= cpu_to_le32(-1);
1129 goto psx_create_err
;
1131 memcpy((char *) pRetData
,
1132 (char *)psx_rsp
+ sizeof(OPEN_PSX_RSP
),
1133 sizeof(FILE_UNIX_BASIC_INFO
));
1137 cifs_buf_release(pSMB
);
1139 if (posix_flags
& SMB_O_DIRECTORY
)
1140 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixmkdirs
);
1142 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixopens
);
1150 static __u16
convert_disposition(int disposition
)
1154 switch (disposition
) {
1155 case FILE_SUPERSEDE
:
1156 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1159 ofun
= SMBOPEN_OAPPEND
;
1162 ofun
= SMBOPEN_OCREATE
;
1165 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OAPPEND
;
1167 case FILE_OVERWRITE
:
1168 ofun
= SMBOPEN_OTRUNC
;
1170 case FILE_OVERWRITE_IF
:
1171 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1174 cifs_dbg(FYI
, "unknown disposition %d\n", disposition
);
1175 ofun
= SMBOPEN_OAPPEND
; /* regular open */
1181 access_flags_to_smbopen_mode(const int access_flags
)
1183 int masked_flags
= access_flags
& (GENERIC_READ
| GENERIC_WRITE
);
1185 if (masked_flags
== GENERIC_READ
)
1186 return SMBOPEN_READ
;
1187 else if (masked_flags
== GENERIC_WRITE
)
1188 return SMBOPEN_WRITE
;
1190 /* just go for read/write */
1191 return SMBOPEN_READWRITE
;
1195 SMBLegacyOpen(const unsigned int xid
, struct cifs_tcon
*tcon
,
1196 const char *fileName
, const int openDisposition
,
1197 const int access_flags
, const int create_options
, __u16
*netfid
,
1198 int *pOplock
, FILE_ALL_INFO
*pfile_info
,
1199 const struct nls_table
*nls_codepage
, int remap
)
1202 OPENX_REQ
*pSMB
= NULL
;
1203 OPENX_RSP
*pSMBr
= NULL
;
1209 rc
= smb_init(SMB_COM_OPEN_ANDX
, 15, tcon
, (void **) &pSMB
,
1214 pSMB
->AndXCommand
= 0xFF; /* none */
1216 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1217 count
= 1; /* account for one byte pad to word boundary */
1219 cifsConvertToUTF16((__le16
*) (pSMB
->fileName
+ 1),
1220 fileName
, PATH_MAX
, nls_codepage
, remap
);
1221 name_len
++; /* trailing null */
1223 } else { /* BB improve check for buffer overruns BB */
1224 count
= 0; /* no pad */
1225 name_len
= strnlen(fileName
, PATH_MAX
);
1226 name_len
++; /* trailing null */
1227 strncpy(pSMB
->fileName
, fileName
, name_len
);
1229 if (*pOplock
& REQ_OPLOCK
)
1230 pSMB
->OpenFlags
= cpu_to_le16(REQ_OPLOCK
);
1231 else if (*pOplock
& REQ_BATCHOPLOCK
)
1232 pSMB
->OpenFlags
= cpu_to_le16(REQ_BATCHOPLOCK
);
1234 pSMB
->OpenFlags
|= cpu_to_le16(REQ_MORE_INFO
);
1235 pSMB
->Mode
= cpu_to_le16(access_flags_to_smbopen_mode(access_flags
));
1236 pSMB
->Mode
|= cpu_to_le16(0x40); /* deny none */
1237 /* set file as system file if special file such
1238 as fifo and server expecting SFU style and
1239 no Unix extensions */
1241 if (create_options
& CREATE_OPTION_SPECIAL
)
1242 pSMB
->FileAttributes
= cpu_to_le16(ATTR_SYSTEM
);
1243 else /* BB FIXME BB */
1244 pSMB
->FileAttributes
= cpu_to_le16(0/*ATTR_NORMAL*/);
1246 if (create_options
& CREATE_OPTION_READONLY
)
1247 pSMB
->FileAttributes
|= cpu_to_le16(ATTR_READONLY
);
1250 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1251 CREATE_OPTIONS_MASK); */
1252 /* BB FIXME END BB */
1254 pSMB
->Sattr
= cpu_to_le16(ATTR_HIDDEN
| ATTR_SYSTEM
| ATTR_DIRECTORY
);
1255 pSMB
->OpenFunction
= cpu_to_le16(convert_disposition(openDisposition
));
1257 inc_rfc1001_len(pSMB
, count
);
1259 pSMB
->ByteCount
= cpu_to_le16(count
);
1260 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1261 (struct smb_hdr
*)pSMBr
, &bytes_returned
, 0);
1262 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1264 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1266 /* BB verify if wct == 15 */
1268 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1270 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
1271 /* Let caller know file was created so we can set the mode. */
1272 /* Do we care about the CreateAction in any other cases? */
1274 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1275 *pOplock |= CIFS_CREATE_ACTION; */
1279 pfile_info
->CreationTime
= 0; /* BB convert CreateTime*/
1280 pfile_info
->LastAccessTime
= 0; /* BB fixme */
1281 pfile_info
->LastWriteTime
= 0; /* BB fixme */
1282 pfile_info
->ChangeTime
= 0; /* BB fixme */
1283 pfile_info
->Attributes
=
1284 cpu_to_le32(le16_to_cpu(pSMBr
->FileAttributes
));
1285 /* the file_info buf is endian converted by caller */
1286 pfile_info
->AllocationSize
=
1287 cpu_to_le64(le32_to_cpu(pSMBr
->EndOfFile
));
1288 pfile_info
->EndOfFile
= pfile_info
->AllocationSize
;
1289 pfile_info
->NumberOfLinks
= cpu_to_le32(1);
1290 pfile_info
->DeletePending
= 0;
1294 cifs_buf_release(pSMB
);
1301 CIFS_open(const unsigned int xid
, struct cifs_open_parms
*oparms
, int *oplock
,
1305 OPEN_REQ
*req
= NULL
;
1306 OPEN_RSP
*rsp
= NULL
;
1310 struct cifs_sb_info
*cifs_sb
= oparms
->cifs_sb
;
1311 struct cifs_tcon
*tcon
= oparms
->tcon
;
1312 int remap
= cifs_remap(cifs_sb
);
1313 const struct nls_table
*nls
= cifs_sb
->local_nls
;
1314 int create_options
= oparms
->create_options
;
1315 int desired_access
= oparms
->desired_access
;
1316 int disposition
= oparms
->disposition
;
1317 const char *path
= oparms
->path
;
1320 rc
= smb_init(SMB_COM_NT_CREATE_ANDX
, 24, tcon
, (void **)&req
,
1325 /* no commands go after this */
1326 req
->AndXCommand
= 0xFF;
1328 if (req
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1329 /* account for one byte pad to word boundary */
1331 name_len
= cifsConvertToUTF16((__le16
*)(req
->fileName
+ 1),
1332 path
, PATH_MAX
, nls
, remap
);
1336 req
->NameLength
= cpu_to_le16(name_len
);
1338 /* BB improve check for buffer overruns BB */
1341 name_len
= strnlen(path
, PATH_MAX
);
1344 req
->NameLength
= cpu_to_le16(name_len
);
1345 strncpy(req
->fileName
, path
, name_len
);
1348 if (*oplock
& REQ_OPLOCK
)
1349 req
->OpenFlags
= cpu_to_le32(REQ_OPLOCK
);
1350 else if (*oplock
& REQ_BATCHOPLOCK
)
1351 req
->OpenFlags
= cpu_to_le32(REQ_BATCHOPLOCK
);
1353 req
->DesiredAccess
= cpu_to_le32(desired_access
);
1354 req
->AllocationSize
= 0;
1357 * Set file as system file if special file such as fifo and server
1358 * expecting SFU style and no Unix extensions.
1360 if (create_options
& CREATE_OPTION_SPECIAL
)
1361 req
->FileAttributes
= cpu_to_le32(ATTR_SYSTEM
);
1363 req
->FileAttributes
= cpu_to_le32(ATTR_NORMAL
);
1366 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1367 * sensitive checks for other servers such as Samba.
1369 if (tcon
->ses
->capabilities
& CAP_UNIX
)
1370 req
->FileAttributes
|= cpu_to_le32(ATTR_POSIX_SEMANTICS
);
1372 if (create_options
& CREATE_OPTION_READONLY
)
1373 req
->FileAttributes
|= cpu_to_le32(ATTR_READONLY
);
1375 req
->ShareAccess
= cpu_to_le32(FILE_SHARE_ALL
);
1376 req
->CreateDisposition
= cpu_to_le32(disposition
);
1377 req
->CreateOptions
= cpu_to_le32(create_options
& CREATE_OPTIONS_MASK
);
1379 /* BB Expirement with various impersonation levels and verify */
1380 req
->ImpersonationLevel
= cpu_to_le32(SECURITY_IMPERSONATION
);
1381 req
->SecurityFlags
= SECURITY_CONTEXT_TRACKING
|SECURITY_EFFECTIVE_ONLY
;
1384 inc_rfc1001_len(req
, count
);
1386 req
->ByteCount
= cpu_to_le16(count
);
1387 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*)req
,
1388 (struct smb_hdr
*)rsp
, &bytes_returned
, 0);
1389 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1391 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1392 cifs_buf_release(req
);
1398 /* 1 byte no need to le_to_cpu */
1399 *oplock
= rsp
->OplockLevel
;
1400 /* cifs fid stays in le */
1401 oparms
->fid
->netfid
= rsp
->Fid
;
1403 /* Let caller know file was created so we can set the mode. */
1404 /* Do we care about the CreateAction in any other cases? */
1405 if (cpu_to_le32(FILE_CREATE
) == rsp
->CreateAction
)
1406 *oplock
|= CIFS_CREATE_ACTION
;
1409 /* copy from CreationTime to Attributes */
1410 memcpy((char *)buf
, (char *)&rsp
->CreationTime
, 36);
1411 /* the file_info buf is endian converted by caller */
1412 buf
->AllocationSize
= rsp
->AllocationSize
;
1413 buf
->EndOfFile
= rsp
->EndOfFile
;
1414 buf
->NumberOfLinks
= cpu_to_le32(1);
1415 buf
->DeletePending
= 0;
1418 cifs_buf_release(req
);
1423 * Discard any remaining data in the current SMB. To do this, we borrow the
1427 cifs_discard_remaining_data(struct TCP_Server_Info
*server
)
1429 unsigned int rfclen
= get_rfc1002_length(server
->smallbuf
);
1430 int remaining
= rfclen
+ 4 - server
->total_read
;
1432 while (remaining
> 0) {
1435 length
= cifs_read_from_socket(server
, server
->bigbuf
,
1436 min_t(unsigned int, remaining
,
1437 CIFSMaxBufSize
+ MAX_HEADER_SIZE(server
)));
1440 server
->total_read
+= length
;
1441 remaining
-= length
;
1448 __cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
,
1453 length
= cifs_discard_remaining_data(server
);
1454 dequeue_mid(mid
, malformed
);
1455 mid
->resp_buf
= server
->smallbuf
;
1456 server
->smallbuf
= NULL
;
1461 cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1463 struct cifs_readdata
*rdata
= mid
->callback_data
;
1465 return __cifs_readv_discard(server
, mid
, rdata
->result
);
1469 cifs_readv_receive(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1472 unsigned int data_offset
, data_len
;
1473 struct cifs_readdata
*rdata
= mid
->callback_data
;
1474 char *buf
= server
->smallbuf
;
1475 unsigned int buflen
= get_rfc1002_length(buf
) + 4;
1477 cifs_dbg(FYI
, "%s: mid=%llu offset=%llu bytes=%u\n",
1478 __func__
, mid
->mid
, rdata
->offset
, rdata
->bytes
);
1481 * read the rest of READ_RSP header (sans Data array), or whatever we
1482 * can if there's not enough data. At this point, we've read down to
1485 len
= min_t(unsigned int, buflen
, server
->vals
->read_rsp_size
) -
1486 HEADER_SIZE(server
) + 1;
1488 length
= cifs_read_from_socket(server
,
1489 buf
+ HEADER_SIZE(server
) - 1, len
);
1492 server
->total_read
+= length
;
1494 if (server
->ops
->is_session_expired
&&
1495 server
->ops
->is_session_expired(buf
)) {
1496 cifs_reconnect(server
);
1497 wake_up(&server
->response_q
);
1501 if (server
->ops
->is_status_pending
&&
1502 server
->ops
->is_status_pending(buf
, server
, 0)) {
1503 cifs_discard_remaining_data(server
);
1507 /* set up first two iov for signature check and to get credits */
1508 rdata
->iov
[0].iov_base
= buf
;
1509 rdata
->iov
[0].iov_len
= 4;
1510 rdata
->iov
[1].iov_base
= buf
+ 4;
1511 rdata
->iov
[1].iov_len
= server
->total_read
- 4;
1512 cifs_dbg(FYI
, "0: iov_base=%p iov_len=%zu\n",
1513 rdata
->iov
[0].iov_base
, rdata
->iov
[0].iov_len
);
1514 cifs_dbg(FYI
, "1: iov_base=%p iov_len=%zu\n",
1515 rdata
->iov
[1].iov_base
, rdata
->iov
[1].iov_len
);
1517 /* Was the SMB read successful? */
1518 rdata
->result
= server
->ops
->map_error(buf
, false);
1519 if (rdata
->result
!= 0) {
1520 cifs_dbg(FYI
, "%s: server returned error %d\n",
1521 __func__
, rdata
->result
);
1522 /* normal error on read response */
1523 return __cifs_readv_discard(server
, mid
, false);
1526 /* Is there enough to get to the rest of the READ_RSP header? */
1527 if (server
->total_read
< server
->vals
->read_rsp_size
) {
1528 cifs_dbg(FYI
, "%s: server returned short header. got=%u expected=%zu\n",
1529 __func__
, server
->total_read
,
1530 server
->vals
->read_rsp_size
);
1531 rdata
->result
= -EIO
;
1532 return cifs_readv_discard(server
, mid
);
1535 data_offset
= server
->ops
->read_data_offset(buf
) + 4;
1536 if (data_offset
< server
->total_read
) {
1538 * win2k8 sometimes sends an offset of 0 when the read
1539 * is beyond the EOF. Treat it as if the data starts just after
1542 cifs_dbg(FYI
, "%s: data offset (%u) inside read response header\n",
1543 __func__
, data_offset
);
1544 data_offset
= server
->total_read
;
1545 } else if (data_offset
> MAX_CIFS_SMALL_BUFFER_SIZE
) {
1546 /* data_offset is beyond the end of smallbuf */
1547 cifs_dbg(FYI
, "%s: data offset (%u) beyond end of smallbuf\n",
1548 __func__
, data_offset
);
1549 rdata
->result
= -EIO
;
1550 return cifs_readv_discard(server
, mid
);
1553 cifs_dbg(FYI
, "%s: total_read=%u data_offset=%u\n",
1554 __func__
, server
->total_read
, data_offset
);
1556 len
= data_offset
- server
->total_read
;
1558 /* read any junk before data into the rest of smallbuf */
1559 length
= cifs_read_from_socket(server
,
1560 buf
+ server
->total_read
, len
);
1563 server
->total_read
+= length
;
1566 /* how much data is in the response? */
1567 data_len
= server
->ops
->read_data_length(buf
);
1568 if (data_offset
+ data_len
> buflen
) {
1569 /* data_len is corrupt -- discard frame */
1570 rdata
->result
= -EIO
;
1571 return cifs_readv_discard(server
, mid
);
1574 length
= rdata
->read_into_pages(server
, rdata
, data_len
);
1578 server
->total_read
+= length
;
1580 cifs_dbg(FYI
, "total_read=%u buflen=%u remaining=%u\n",
1581 server
->total_read
, buflen
, data_len
);
1583 /* discard anything left over */
1584 if (server
->total_read
< buflen
)
1585 return cifs_readv_discard(server
, mid
);
1587 dequeue_mid(mid
, false);
1588 mid
->resp_buf
= server
->smallbuf
;
1589 server
->smallbuf
= NULL
;
1594 cifs_readv_callback(struct mid_q_entry
*mid
)
1596 struct cifs_readdata
*rdata
= mid
->callback_data
;
1597 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1598 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
1599 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1601 .rq_pages
= rdata
->pages
,
1602 .rq_npages
= rdata
->nr_pages
,
1603 .rq_pagesz
= rdata
->pagesz
,
1604 .rq_tailsz
= rdata
->tailsz
};
1606 cifs_dbg(FYI
, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1607 __func__
, mid
->mid
, mid
->mid_state
, rdata
->result
,
1610 switch (mid
->mid_state
) {
1611 case MID_RESPONSE_RECEIVED
:
1612 /* result already set, check signature */
1616 rc
= cifs_verify_signature(&rqst
, server
,
1617 mid
->sequence_number
);
1619 cifs_dbg(VFS
, "SMB signature verification returned error = %d\n",
1622 /* FIXME: should this be counted toward the initiating task? */
1623 task_io_account_read(rdata
->got_bytes
);
1624 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1626 case MID_REQUEST_SUBMITTED
:
1627 case MID_RETRY_NEEDED
:
1628 rdata
->result
= -EAGAIN
;
1629 if (server
->sign
&& rdata
->got_bytes
)
1630 /* reset bytes number since we can not check a sign */
1631 rdata
->got_bytes
= 0;
1632 /* FIXME: should this be counted toward the initiating task? */
1633 task_io_account_read(rdata
->got_bytes
);
1634 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1637 rdata
->result
= -EIO
;
1640 queue_work(cifsiod_wq
, &rdata
->work
);
1641 DeleteMidQEntry(mid
);
1642 add_credits(server
, 1, 0);
1645 /* cifs_async_readv - send an async write, and set up mid to handle result */
1647 cifs_async_readv(struct cifs_readdata
*rdata
)
1650 READ_REQ
*smb
= NULL
;
1652 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1653 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1656 cifs_dbg(FYI
, "%s: offset=%llu bytes=%u\n",
1657 __func__
, rdata
->offset
, rdata
->bytes
);
1659 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1662 wct
= 10; /* old style read */
1663 if ((rdata
->offset
>> 32) > 0) {
1664 /* can not handle this big offset for old */
1669 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **)&smb
);
1673 smb
->hdr
.Pid
= cpu_to_le16((__u16
)rdata
->pid
);
1674 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(rdata
->pid
>> 16));
1676 smb
->AndXCommand
= 0xFF; /* none */
1677 smb
->Fid
= rdata
->cfile
->fid
.netfid
;
1678 smb
->OffsetLow
= cpu_to_le32(rdata
->offset
& 0xFFFFFFFF);
1680 smb
->OffsetHigh
= cpu_to_le32(rdata
->offset
>> 32);
1682 smb
->MaxCount
= cpu_to_le16(rdata
->bytes
& 0xFFFF);
1683 smb
->MaxCountHigh
= cpu_to_le32(rdata
->bytes
>> 16);
1687 /* old style read */
1688 struct smb_com_readx_req
*smbr
=
1689 (struct smb_com_readx_req
*)smb
;
1690 smbr
->ByteCount
= 0;
1693 /* 4 for RFC1001 length + 1 for BCC */
1694 rdata
->iov
[0].iov_base
= smb
;
1695 rdata
->iov
[0].iov_len
= 4;
1696 rdata
->iov
[1].iov_base
= (char *)smb
+ 4;
1697 rdata
->iov
[1].iov_len
= get_rfc1002_length(smb
);
1699 kref_get(&rdata
->refcount
);
1700 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, cifs_readv_receive
,
1701 cifs_readv_callback
, NULL
, rdata
, 0);
1704 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1706 kref_put(&rdata
->refcount
, cifs_readdata_release
);
1708 cifs_small_buf_release(smb
);
1713 CIFSSMBRead(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1714 unsigned int *nbytes
, char **buf
, int *pbuf_type
)
1717 READ_REQ
*pSMB
= NULL
;
1718 READ_RSP
*pSMBr
= NULL
;
1719 char *pReadData
= NULL
;
1721 int resp_buf_type
= 0;
1723 struct kvec rsp_iov
;
1724 __u32 pid
= io_parms
->pid
;
1725 __u16 netfid
= io_parms
->netfid
;
1726 __u64 offset
= io_parms
->offset
;
1727 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1728 unsigned int count
= io_parms
->length
;
1730 cifs_dbg(FYI
, "Reading %d bytes on fid %d\n", count
, netfid
);
1731 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1734 wct
= 10; /* old style read */
1735 if ((offset
>> 32) > 0) {
1736 /* can not handle this big offset for old */
1742 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **) &pSMB
);
1746 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1747 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1749 /* tcon and ses pointer are checked in smb_init */
1750 if (tcon
->ses
->server
== NULL
)
1751 return -ECONNABORTED
;
1753 pSMB
->AndXCommand
= 0xFF; /* none */
1755 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1757 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1759 pSMB
->Remaining
= 0;
1760 pSMB
->MaxCount
= cpu_to_le16(count
& 0xFFFF);
1761 pSMB
->MaxCountHigh
= cpu_to_le32(count
>> 16);
1763 pSMB
->ByteCount
= 0; /* no need to do le conversion since 0 */
1765 /* old style read */
1766 struct smb_com_readx_req
*pSMBW
=
1767 (struct smb_com_readx_req
*)pSMB
;
1768 pSMBW
->ByteCount
= 0;
1771 iov
[0].iov_base
= (char *)pSMB
;
1772 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
1773 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1, &resp_buf_type
,
1774 CIFS_LOG_ERROR
, &rsp_iov
);
1775 cifs_small_buf_release(pSMB
);
1776 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1777 pSMBr
= (READ_RSP
*)rsp_iov
.iov_base
;
1779 cifs_dbg(VFS
, "Send error in read = %d\n", rc
);
1781 int data_length
= le16_to_cpu(pSMBr
->DataLengthHigh
);
1782 data_length
= data_length
<< 16;
1783 data_length
+= le16_to_cpu(pSMBr
->DataLength
);
1784 *nbytes
= data_length
;
1786 /*check that DataLength would not go beyond end of SMB */
1787 if ((data_length
> CIFSMaxBufSize
)
1788 || (data_length
> count
)) {
1789 cifs_dbg(FYI
, "bad length %d for count %d\n",
1790 data_length
, count
);
1794 pReadData
= (char *) (&pSMBr
->hdr
.Protocol
) +
1795 le16_to_cpu(pSMBr
->DataOffset
);
1796 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1797 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1799 }*/ /* can not use copy_to_user when using page cache*/
1801 memcpy(*buf
, pReadData
, data_length
);
1806 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
1807 } else if (resp_buf_type
!= CIFS_NO_BUFFER
) {
1808 /* return buffer to caller to free */
1809 *buf
= rsp_iov
.iov_base
;
1810 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1811 *pbuf_type
= CIFS_SMALL_BUFFER
;
1812 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1813 *pbuf_type
= CIFS_LARGE_BUFFER
;
1814 } /* else no valid buffer on return - leave as null */
1816 /* Note: On -EAGAIN error only caller can retry on handle based calls
1817 since file handle passed in no longer valid */
1823 CIFSSMBWrite(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1824 unsigned int *nbytes
, const char *buf
)
1827 WRITE_REQ
*pSMB
= NULL
;
1828 WRITE_RSP
*pSMBr
= NULL
;
1829 int bytes_returned
, wct
;
1832 __u32 pid
= io_parms
->pid
;
1833 __u16 netfid
= io_parms
->netfid
;
1834 __u64 offset
= io_parms
->offset
;
1835 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1836 unsigned int count
= io_parms
->length
;
1840 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1841 if (tcon
->ses
== NULL
)
1842 return -ECONNABORTED
;
1844 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1848 if ((offset
>> 32) > 0) {
1849 /* can not handle big offset for old srv */
1854 rc
= smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
,
1859 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1860 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1862 /* tcon and ses pointer are checked in smb_init */
1863 if (tcon
->ses
->server
== NULL
)
1864 return -ECONNABORTED
;
1866 pSMB
->AndXCommand
= 0xFF; /* none */
1868 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1870 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1872 pSMB
->Reserved
= 0xFFFFFFFF;
1873 pSMB
->WriteMode
= 0;
1874 pSMB
->Remaining
= 0;
1876 /* Can increase buffer size if buffer is big enough in some cases ie we
1877 can send more if LARGE_WRITE_X capability returned by the server and if
1878 our buffer is big enough or if we convert to iovecs on socket writes
1879 and eliminate the copy to the CIFS buffer */
1880 if (tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
) {
1881 bytes_sent
= min_t(const unsigned int, CIFSMaxBufSize
, count
);
1883 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
)
1887 if (bytes_sent
> count
)
1890 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1892 memcpy(pSMB
->Data
, buf
, bytes_sent
);
1893 else if (count
!= 0) {
1895 cifs_buf_release(pSMB
);
1897 } /* else setting file size with write of zero bytes */
1899 byte_count
= bytes_sent
+ 1; /* pad */
1900 else /* wct == 12 */
1901 byte_count
= bytes_sent
+ 5; /* bigger pad, smaller smb hdr */
1903 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
& 0xFFFF);
1904 pSMB
->DataLengthHigh
= cpu_to_le16(bytes_sent
>> 16);
1905 inc_rfc1001_len(pSMB
, byte_count
);
1908 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1909 else { /* old style write has byte count 4 bytes earlier
1911 struct smb_com_writex_req
*pSMBW
=
1912 (struct smb_com_writex_req
*)pSMB
;
1913 pSMBW
->ByteCount
= cpu_to_le16(byte_count
);
1916 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1917 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1918 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
1920 cifs_dbg(FYI
, "Send error in write = %d\n", rc
);
1922 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
1923 *nbytes
= (*nbytes
) << 16;
1924 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
1927 * Mask off high 16 bits when bytes written as returned by the
1928 * server is greater than bytes requested by the client. Some
1929 * OS/2 servers are known to set incorrect CountHigh values.
1931 if (*nbytes
> count
)
1935 cifs_buf_release(pSMB
);
1937 /* Note: On -EAGAIN error only caller can retry on handle based calls
1938 since file handle passed in no longer valid */
1944 cifs_writedata_release(struct kref
*refcount
)
1946 struct cifs_writedata
*wdata
= container_of(refcount
,
1947 struct cifs_writedata
, refcount
);
1950 cifsFileInfo_put(wdata
->cfile
);
1956 * Write failed with a retryable error. Resend the write request. It's also
1957 * possible that the page was redirtied so re-clean the page.
1960 cifs_writev_requeue(struct cifs_writedata
*wdata
)
1963 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
1964 struct TCP_Server_Info
*server
;
1965 unsigned int rest_len
;
1967 server
= tlink_tcon(wdata
->cfile
->tlink
)->ses
->server
;
1969 rest_len
= wdata
->bytes
;
1971 struct cifs_writedata
*wdata2
;
1972 unsigned int j
, nr_pages
, wsize
, tailsz
, cur_len
;
1974 wsize
= server
->ops
->wp_retry_size(inode
);
1975 if (wsize
< rest_len
) {
1976 nr_pages
= wsize
/ PAGE_SIZE
;
1981 cur_len
= nr_pages
* PAGE_SIZE
;
1984 nr_pages
= DIV_ROUND_UP(rest_len
, PAGE_SIZE
);
1986 tailsz
= rest_len
- (nr_pages
- 1) * PAGE_SIZE
;
1989 wdata2
= cifs_writedata_alloc(nr_pages
, cifs_writev_complete
);
1995 for (j
= 0; j
< nr_pages
; j
++) {
1996 wdata2
->pages
[j
] = wdata
->pages
[i
+ j
];
1997 lock_page(wdata2
->pages
[j
]);
1998 clear_page_dirty_for_io(wdata2
->pages
[j
]);
2001 wdata2
->sync_mode
= wdata
->sync_mode
;
2002 wdata2
->nr_pages
= nr_pages
;
2003 wdata2
->offset
= page_offset(wdata2
->pages
[0]);
2004 wdata2
->pagesz
= PAGE_SIZE
;
2005 wdata2
->tailsz
= tailsz
;
2006 wdata2
->bytes
= cur_len
;
2008 wdata2
->cfile
= find_writable_file(CIFS_I(inode
), false);
2009 if (!wdata2
->cfile
) {
2010 cifs_dbg(VFS
, "No writable handle to retry writepages\n");
2013 wdata2
->pid
= wdata2
->cfile
->pid
;
2014 rc
= server
->ops
->async_writev(wdata2
,
2015 cifs_writedata_release
);
2018 for (j
= 0; j
< nr_pages
; j
++) {
2019 unlock_page(wdata2
->pages
[j
]);
2020 if (rc
!= 0 && !is_retryable_error(rc
)) {
2021 SetPageError(wdata2
->pages
[j
]);
2022 end_page_writeback(wdata2
->pages
[j
]);
2023 put_page(wdata2
->pages
[j
]);
2028 kref_put(&wdata2
->refcount
, cifs_writedata_release
);
2029 if (is_retryable_error(rc
))
2035 rest_len
-= cur_len
;
2037 } while (i
< wdata
->nr_pages
);
2039 /* cleanup remaining pages from the original wdata */
2040 for (; i
< wdata
->nr_pages
; i
++) {
2041 SetPageError(wdata
->pages
[i
]);
2042 end_page_writeback(wdata
->pages
[i
]);
2043 put_page(wdata
->pages
[i
]);
2046 if (rc
!= 0 && !is_retryable_error(rc
))
2047 mapping_set_error(inode
->i_mapping
, rc
);
2048 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2052 cifs_writev_complete(struct work_struct
*work
)
2054 struct cifs_writedata
*wdata
= container_of(work
,
2055 struct cifs_writedata
, work
);
2056 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
2059 if (wdata
->result
== 0) {
2060 spin_lock(&inode
->i_lock
);
2061 cifs_update_eof(CIFS_I(inode
), wdata
->offset
, wdata
->bytes
);
2062 spin_unlock(&inode
->i_lock
);
2063 cifs_stats_bytes_written(tlink_tcon(wdata
->cfile
->tlink
),
2065 } else if (wdata
->sync_mode
== WB_SYNC_ALL
&& wdata
->result
== -EAGAIN
)
2066 return cifs_writev_requeue(wdata
);
2068 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
2069 struct page
*page
= wdata
->pages
[i
];
2070 if (wdata
->result
== -EAGAIN
)
2071 __set_page_dirty_nobuffers(page
);
2072 else if (wdata
->result
< 0)
2074 end_page_writeback(page
);
2077 if (wdata
->result
!= -EAGAIN
)
2078 mapping_set_error(inode
->i_mapping
, wdata
->result
);
2079 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2082 struct cifs_writedata
*
2083 cifs_writedata_alloc(unsigned int nr_pages
, work_func_t complete
)
2085 struct cifs_writedata
*wdata
;
2087 /* writedata + number of page pointers */
2088 wdata
= kzalloc(sizeof(*wdata
) +
2089 sizeof(struct page
*) * nr_pages
, GFP_NOFS
);
2090 if (wdata
!= NULL
) {
2091 kref_init(&wdata
->refcount
);
2092 INIT_LIST_HEAD(&wdata
->list
);
2093 init_completion(&wdata
->done
);
2094 INIT_WORK(&wdata
->work
, complete
);
2100 * Check the mid_state and signature on received buffer (if any), and queue the
2101 * workqueue completion task.
2104 cifs_writev_callback(struct mid_q_entry
*mid
)
2106 struct cifs_writedata
*wdata
= mid
->callback_data
;
2107 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2108 unsigned int written
;
2109 WRITE_RSP
*smb
= (WRITE_RSP
*)mid
->resp_buf
;
2111 switch (mid
->mid_state
) {
2112 case MID_RESPONSE_RECEIVED
:
2113 wdata
->result
= cifs_check_receive(mid
, tcon
->ses
->server
, 0);
2114 if (wdata
->result
!= 0)
2117 written
= le16_to_cpu(smb
->CountHigh
);
2119 written
+= le16_to_cpu(smb
->Count
);
2121 * Mask off high 16 bits when bytes written as returned
2122 * by the server is greater than bytes requested by the
2123 * client. OS/2 servers are known to set incorrect
2126 if (written
> wdata
->bytes
)
2129 if (written
< wdata
->bytes
)
2130 wdata
->result
= -ENOSPC
;
2132 wdata
->bytes
= written
;
2134 case MID_REQUEST_SUBMITTED
:
2135 case MID_RETRY_NEEDED
:
2136 wdata
->result
= -EAGAIN
;
2139 wdata
->result
= -EIO
;
2143 queue_work(cifsiod_wq
, &wdata
->work
);
2144 DeleteMidQEntry(mid
);
2145 add_credits(tcon
->ses
->server
, 1, 0);
2148 /* cifs_async_writev - send an async write, and set up mid to handle result */
2150 cifs_async_writev(struct cifs_writedata
*wdata
,
2151 void (*release
)(struct kref
*kref
))
2154 WRITE_REQ
*smb
= NULL
;
2156 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2158 struct smb_rqst rqst
= { };
2160 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2164 if (wdata
->offset
>> 32 > 0) {
2165 /* can not handle big offset for old srv */
2170 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **)&smb
);
2172 goto async_writev_out
;
2174 smb
->hdr
.Pid
= cpu_to_le16((__u16
)wdata
->pid
);
2175 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(wdata
->pid
>> 16));
2177 smb
->AndXCommand
= 0xFF; /* none */
2178 smb
->Fid
= wdata
->cfile
->fid
.netfid
;
2179 smb
->OffsetLow
= cpu_to_le32(wdata
->offset
& 0xFFFFFFFF);
2181 smb
->OffsetHigh
= cpu_to_le32(wdata
->offset
>> 32);
2182 smb
->Reserved
= 0xFFFFFFFF;
2187 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2189 /* 4 for RFC1001 length + 1 for BCC */
2191 iov
[0].iov_base
= smb
;
2192 iov
[1].iov_len
= get_rfc1002_length(smb
) + 1;
2193 iov
[1].iov_base
= (char *)smb
+ 4;
2197 rqst
.rq_pages
= wdata
->pages
;
2198 rqst
.rq_npages
= wdata
->nr_pages
;
2199 rqst
.rq_pagesz
= wdata
->pagesz
;
2200 rqst
.rq_tailsz
= wdata
->tailsz
;
2202 cifs_dbg(FYI
, "async write at %llu %u bytes\n",
2203 wdata
->offset
, wdata
->bytes
);
2205 smb
->DataLengthLow
= cpu_to_le16(wdata
->bytes
& 0xFFFF);
2206 smb
->DataLengthHigh
= cpu_to_le16(wdata
->bytes
>> 16);
2209 inc_rfc1001_len(&smb
->hdr
, wdata
->bytes
+ 1);
2210 put_bcc(wdata
->bytes
+ 1, &smb
->hdr
);
2213 struct smb_com_writex_req
*smbw
=
2214 (struct smb_com_writex_req
*)smb
;
2215 inc_rfc1001_len(&smbw
->hdr
, wdata
->bytes
+ 5);
2216 put_bcc(wdata
->bytes
+ 5, &smbw
->hdr
);
2217 iov
[1].iov_len
+= 4; /* pad bigger by four bytes */
2220 kref_get(&wdata
->refcount
);
2221 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, NULL
,
2222 cifs_writev_callback
, NULL
, wdata
, 0);
2225 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2227 kref_put(&wdata
->refcount
, release
);
2230 cifs_small_buf_release(smb
);
2235 CIFSSMBWrite2(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
2236 unsigned int *nbytes
, struct kvec
*iov
, int n_vec
)
2239 WRITE_REQ
*pSMB
= NULL
;
2242 int resp_buf_type
= 0;
2243 __u32 pid
= io_parms
->pid
;
2244 __u16 netfid
= io_parms
->netfid
;
2245 __u64 offset
= io_parms
->offset
;
2246 struct cifs_tcon
*tcon
= io_parms
->tcon
;
2247 unsigned int count
= io_parms
->length
;
2248 struct kvec rsp_iov
;
2252 cifs_dbg(FYI
, "write2 at %lld %d bytes\n", (long long)offset
, count
);
2254 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2258 if ((offset
>> 32) > 0) {
2259 /* can not handle big offset for old srv */
2263 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
);
2267 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
2268 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
2270 /* tcon and ses pointer are checked in smb_init */
2271 if (tcon
->ses
->server
== NULL
)
2272 return -ECONNABORTED
;
2274 pSMB
->AndXCommand
= 0xFF; /* none */
2276 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
2278 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
2279 pSMB
->Reserved
= 0xFFFFFFFF;
2280 pSMB
->WriteMode
= 0;
2281 pSMB
->Remaining
= 0;
2284 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2286 pSMB
->DataLengthLow
= cpu_to_le16(count
& 0xFFFF);
2287 pSMB
->DataLengthHigh
= cpu_to_le16(count
>> 16);
2288 /* header + 1 byte pad */
2289 smb_hdr_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 1;
2291 inc_rfc1001_len(pSMB
, count
+ 1);
2292 else /* wct == 12 */
2293 inc_rfc1001_len(pSMB
, count
+ 5); /* smb data starts later */
2295 pSMB
->ByteCount
= cpu_to_le16(count
+ 1);
2296 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2297 struct smb_com_writex_req
*pSMBW
=
2298 (struct smb_com_writex_req
*)pSMB
;
2299 pSMBW
->ByteCount
= cpu_to_le16(count
+ 5);
2301 iov
[0].iov_base
= pSMB
;
2303 iov
[0].iov_len
= smb_hdr_len
+ 4;
2304 else /* wct == 12 pad bigger by four bytes */
2305 iov
[0].iov_len
= smb_hdr_len
+ 8;
2307 rc
= SendReceive2(xid
, tcon
->ses
, iov
, n_vec
+ 1, &resp_buf_type
, 0,
2309 cifs_small_buf_release(pSMB
);
2310 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2312 cifs_dbg(FYI
, "Send error Write2 = %d\n", rc
);
2313 } else if (resp_buf_type
== 0) {
2314 /* presumably this can not happen, but best to be safe */
2317 WRITE_RSP
*pSMBr
= (WRITE_RSP
*)rsp_iov
.iov_base
;
2318 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2319 *nbytes
= (*nbytes
) << 16;
2320 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2323 * Mask off high 16 bits when bytes written as returned by the
2324 * server is greater than bytes requested by the client. OS/2
2325 * servers are known to set incorrect CountHigh values.
2327 if (*nbytes
> count
)
2331 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2333 /* Note: On -EAGAIN error only caller can retry on handle based calls
2334 since file handle passed in no longer valid */
2339 int cifs_lockv(const unsigned int xid
, struct cifs_tcon
*tcon
,
2340 const __u16 netfid
, const __u8 lock_type
, const __u32 num_unlock
,
2341 const __u32 num_lock
, LOCKING_ANDX_RANGE
*buf
)
2344 LOCK_REQ
*pSMB
= NULL
;
2346 struct kvec rsp_iov
;
2350 cifs_dbg(FYI
, "cifs_lockv num lock %d num unlock %d\n",
2351 num_lock
, num_unlock
);
2353 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2358 pSMB
->NumberOfLocks
= cpu_to_le16(num_lock
);
2359 pSMB
->NumberOfUnlocks
= cpu_to_le16(num_unlock
);
2360 pSMB
->LockType
= lock_type
;
2361 pSMB
->AndXCommand
= 0xFF; /* none */
2362 pSMB
->Fid
= netfid
; /* netfid stays le */
2364 count
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2365 inc_rfc1001_len(pSMB
, count
);
2366 pSMB
->ByteCount
= cpu_to_le16(count
);
2368 iov
[0].iov_base
= (char *)pSMB
;
2369 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4 -
2370 (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2371 iov
[1].iov_base
= (char *)buf
;
2372 iov
[1].iov_len
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2374 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2375 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 2, &resp_buf_type
, CIFS_NO_RESP
,
2377 cifs_small_buf_release(pSMB
);
2379 cifs_dbg(FYI
, "Send error in cifs_lockv = %d\n", rc
);
2385 CIFSSMBLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2386 const __u16 smb_file_id
, const __u32 netpid
, const __u64 len
,
2387 const __u64 offset
, const __u32 numUnlock
,
2388 const __u32 numLock
, const __u8 lockType
,
2389 const bool waitFlag
, const __u8 oplock_level
)
2392 LOCK_REQ
*pSMB
= NULL
;
2393 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2398 cifs_dbg(FYI
, "CIFSSMBLock timeout %d numLock %d\n",
2399 (int)waitFlag
, numLock
);
2400 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2405 if (lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
2406 /* no response expected */
2407 flags
= CIFS_ASYNC_OP
| CIFS_OBREAK_OP
;
2409 } else if (waitFlag
) {
2410 flags
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2411 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
2416 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
2417 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
2418 pSMB
->LockType
= lockType
;
2419 pSMB
->OplockLevel
= oplock_level
;
2420 pSMB
->AndXCommand
= 0xFF; /* none */
2421 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
2423 if ((numLock
!= 0) || (numUnlock
!= 0)) {
2424 pSMB
->Locks
[0].Pid
= cpu_to_le16(netpid
);
2425 /* BB where to store pid high? */
2426 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
2427 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
2428 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
2429 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
2430 count
= sizeof(LOCKING_ANDX_RANGE
);
2435 inc_rfc1001_len(pSMB
, count
);
2436 pSMB
->ByteCount
= cpu_to_le16(count
);
2439 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2440 (struct smb_hdr
*) pSMB
, &bytes_returned
);
2442 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)pSMB
, flags
);
2443 cifs_small_buf_release(pSMB
);
2444 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2446 cifs_dbg(FYI
, "Send error in Lock = %d\n", rc
);
2448 /* Note: On -EAGAIN error only caller can retry on handle based calls
2449 since file handle passed in no longer valid */
2454 CIFSSMBPosixLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2455 const __u16 smb_file_id
, const __u32 netpid
,
2456 const loff_t start_offset
, const __u64 len
,
2457 struct file_lock
*pLockData
, const __u16 lock_type
,
2458 const bool waitFlag
)
2460 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2461 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2462 struct cifs_posix_lock
*parm_data
;
2465 int bytes_returned
= 0;
2466 int resp_buf_type
= 0;
2467 __u16 params
, param_offset
, offset
, byte_count
, count
;
2469 struct kvec rsp_iov
;
2471 cifs_dbg(FYI
, "Posix Lock\n");
2473 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
2478 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)pSMB
;
2481 pSMB
->MaxSetupCount
= 0;
2484 pSMB
->Reserved2
= 0;
2485 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2486 offset
= param_offset
+ params
;
2488 count
= sizeof(struct cifs_posix_lock
);
2489 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2490 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2491 pSMB
->SetupCount
= 1;
2492 pSMB
->Reserved3
= 0;
2494 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
2496 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2497 byte_count
= 3 /* pad */ + params
+ count
;
2498 pSMB
->DataCount
= cpu_to_le16(count
);
2499 pSMB
->ParameterCount
= cpu_to_le16(params
);
2500 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2501 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2502 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2503 parm_data
= (struct cifs_posix_lock
*)
2504 (((char *) &pSMB
->hdr
.Protocol
) + offset
);
2506 parm_data
->lock_type
= cpu_to_le16(lock_type
);
2508 timeout
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2509 parm_data
->lock_flags
= cpu_to_le16(1);
2510 pSMB
->Timeout
= cpu_to_le32(-1);
2514 parm_data
->pid
= cpu_to_le32(netpid
);
2515 parm_data
->start
= cpu_to_le64(start_offset
);
2516 parm_data
->length
= cpu_to_le64(len
); /* normalize negative numbers */
2518 pSMB
->DataOffset
= cpu_to_le16(offset
);
2519 pSMB
->Fid
= smb_file_id
;
2520 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_LOCK
);
2521 pSMB
->Reserved4
= 0;
2522 inc_rfc1001_len(pSMB
, byte_count
);
2523 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2525 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2526 (struct smb_hdr
*) pSMBr
, &bytes_returned
);
2528 iov
[0].iov_base
= (char *)pSMB
;
2529 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
2530 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
2531 &resp_buf_type
, timeout
, &rsp_iov
);
2532 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)rsp_iov
.iov_base
;
2534 cifs_small_buf_release(pSMB
);
2537 cifs_dbg(FYI
, "Send error in Posix Lock = %d\n", rc
);
2538 } else if (pLockData
) {
2539 /* lock structure can be returned on get */
2542 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2544 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(*parm_data
)) {
2545 rc
= -EIO
; /* bad smb */
2548 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
2549 data_count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2550 if (data_count
< sizeof(struct cifs_posix_lock
)) {
2554 parm_data
= (struct cifs_posix_lock
*)
2555 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2556 if (parm_data
->lock_type
== cpu_to_le16(CIFS_UNLCK
))
2557 pLockData
->fl_type
= F_UNLCK
;
2559 if (parm_data
->lock_type
==
2560 cpu_to_le16(CIFS_RDLCK
))
2561 pLockData
->fl_type
= F_RDLCK
;
2562 else if (parm_data
->lock_type
==
2563 cpu_to_le16(CIFS_WRLCK
))
2564 pLockData
->fl_type
= F_WRLCK
;
2566 pLockData
->fl_start
= le64_to_cpu(parm_data
->start
);
2567 pLockData
->fl_end
= pLockData
->fl_start
+
2568 le64_to_cpu(parm_data
->length
) - 1;
2569 pLockData
->fl_pid
= -le32_to_cpu(parm_data
->pid
);
2574 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2576 /* Note: On -EAGAIN error only caller can retry on handle based calls
2577 since file handle passed in no longer valid */
2584 CIFSSMBClose(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2587 CLOSE_REQ
*pSMB
= NULL
;
2588 cifs_dbg(FYI
, "In CIFSSMBClose\n");
2590 /* do not retry on dead session on close */
2591 rc
= small_smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
);
2597 pSMB
->FileID
= (__u16
) smb_file_id
;
2598 pSMB
->LastWriteTime
= 0xFFFFFFFF;
2599 pSMB
->ByteCount
= 0;
2600 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2601 cifs_small_buf_release(pSMB
);
2602 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_closes
);
2605 /* EINTR is expected when user ctl-c to kill app */
2606 cifs_dbg(VFS
, "Send error in Close = %d\n", rc
);
2610 /* Since session is dead, file will be closed on server already */
2618 CIFSSMBFlush(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2621 FLUSH_REQ
*pSMB
= NULL
;
2622 cifs_dbg(FYI
, "In CIFSSMBFlush\n");
2624 rc
= small_smb_init(SMB_COM_FLUSH
, 1, tcon
, (void **) &pSMB
);
2628 pSMB
->FileID
= (__u16
) smb_file_id
;
2629 pSMB
->ByteCount
= 0;
2630 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2631 cifs_small_buf_release(pSMB
);
2632 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_flushes
);
2634 cifs_dbg(VFS
, "Send error in Flush = %d\n", rc
);
2640 CIFSSMBRename(const unsigned int xid
, struct cifs_tcon
*tcon
,
2641 const char *from_name
, const char *to_name
,
2642 struct cifs_sb_info
*cifs_sb
)
2645 RENAME_REQ
*pSMB
= NULL
;
2646 RENAME_RSP
*pSMBr
= NULL
;
2648 int name_len
, name_len2
;
2650 int remap
= cifs_remap(cifs_sb
);
2652 cifs_dbg(FYI
, "In CIFSSMBRename\n");
2654 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
2659 pSMB
->BufferFormat
= 0x04;
2660 pSMB
->SearchAttributes
=
2661 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2664 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2665 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2666 from_name
, PATH_MAX
,
2667 cifs_sb
->local_nls
, remap
);
2668 name_len
++; /* trailing null */
2670 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2671 /* protocol requires ASCII signature byte on Unicode string */
2672 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2674 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2675 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2677 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2678 name_len2
*= 2; /* convert to bytes */
2679 } else { /* BB improve the check for buffer overruns BB */
2680 name_len
= strnlen(from_name
, PATH_MAX
);
2681 name_len
++; /* trailing null */
2682 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
2683 name_len2
= strnlen(to_name
, PATH_MAX
);
2684 name_len2
++; /* trailing null */
2685 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2686 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
2687 name_len2
++; /* trailing null */
2688 name_len2
++; /* signature byte */
2691 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2692 inc_rfc1001_len(pSMB
, count
);
2693 pSMB
->ByteCount
= cpu_to_le16(count
);
2695 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2696 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2697 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_renames
);
2699 cifs_dbg(FYI
, "Send error in rename = %d\n", rc
);
2701 cifs_buf_release(pSMB
);
2709 int CIFSSMBRenameOpenFile(const unsigned int xid
, struct cifs_tcon
*pTcon
,
2710 int netfid
, const char *target_name
,
2711 const struct nls_table
*nls_codepage
, int remap
)
2713 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2714 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2715 struct set_file_rename
*rename_info
;
2717 char dummy_string
[30];
2719 int bytes_returned
= 0;
2721 __u16 params
, param_offset
, offset
, count
, byte_count
;
2723 cifs_dbg(FYI
, "Rename to File by handle\n");
2724 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
2730 pSMB
->MaxSetupCount
= 0;
2734 pSMB
->Reserved2
= 0;
2735 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2736 offset
= param_offset
+ params
;
2738 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2739 rename_info
= (struct set_file_rename
*) data_offset
;
2740 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2741 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2742 pSMB
->SetupCount
= 1;
2743 pSMB
->Reserved3
= 0;
2744 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2745 byte_count
= 3 /* pad */ + params
;
2746 pSMB
->ParameterCount
= cpu_to_le16(params
);
2747 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2748 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2749 pSMB
->DataOffset
= cpu_to_le16(offset
);
2750 /* construct random name ".cifs_tmp<inodenum><mid>" */
2751 rename_info
->overwrite
= cpu_to_le32(1);
2752 rename_info
->root_fid
= 0;
2753 /* unicode only call */
2754 if (target_name
== NULL
) {
2755 sprintf(dummy_string
, "cifs%x", pSMB
->hdr
.Mid
);
2757 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2758 dummy_string
, 24, nls_codepage
, remap
);
2761 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2762 target_name
, PATH_MAX
, nls_codepage
,
2765 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
2766 count
= 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str
);
2767 byte_count
+= count
;
2768 pSMB
->DataCount
= cpu_to_le16(count
);
2769 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2771 pSMB
->InformationLevel
=
2772 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
2773 pSMB
->Reserved4
= 0;
2774 inc_rfc1001_len(pSMB
, byte_count
);
2775 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2776 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
2777 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2778 cifs_stats_inc(&pTcon
->stats
.cifs_stats
.num_t2renames
);
2780 cifs_dbg(FYI
, "Send error in Rename (by file handle) = %d\n",
2783 cifs_buf_release(pSMB
);
2785 /* Note: On -EAGAIN error only caller can retry on handle based calls
2786 since file handle passed in no longer valid */
2792 CIFSSMBCopy(const unsigned int xid
, struct cifs_tcon
*tcon
,
2793 const char *fromName
, const __u16 target_tid
, const char *toName
,
2794 const int flags
, const struct nls_table
*nls_codepage
, int remap
)
2797 COPY_REQ
*pSMB
= NULL
;
2798 COPY_RSP
*pSMBr
= NULL
;
2800 int name_len
, name_len2
;
2803 cifs_dbg(FYI
, "In CIFSSMBCopy\n");
2805 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
2810 pSMB
->BufferFormat
= 0x04;
2811 pSMB
->Tid2
= target_tid
;
2813 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
2815 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2816 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2817 fromName
, PATH_MAX
, nls_codepage
,
2819 name_len
++; /* trailing null */
2821 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2822 /* protocol requires ASCII signature byte on Unicode string */
2823 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2825 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2826 toName
, PATH_MAX
, nls_codepage
, remap
);
2827 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2828 name_len2
*= 2; /* convert to bytes */
2829 } else { /* BB improve the check for buffer overruns BB */
2830 name_len
= strnlen(fromName
, PATH_MAX
);
2831 name_len
++; /* trailing null */
2832 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
2833 name_len2
= strnlen(toName
, PATH_MAX
);
2834 name_len2
++; /* trailing null */
2835 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2836 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
2837 name_len2
++; /* trailing null */
2838 name_len2
++; /* signature byte */
2841 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2842 inc_rfc1001_len(pSMB
, count
);
2843 pSMB
->ByteCount
= cpu_to_le16(count
);
2845 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2846 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2848 cifs_dbg(FYI
, "Send error in copy = %d with %d files copied\n",
2849 rc
, le16_to_cpu(pSMBr
->CopyCount
));
2851 cifs_buf_release(pSMB
);
2860 CIFSUnixCreateSymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2861 const char *fromName
, const char *toName
,
2862 const struct nls_table
*nls_codepage
, int remap
)
2864 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2865 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2868 int name_len_target
;
2870 int bytes_returned
= 0;
2871 __u16 params
, param_offset
, offset
, byte_count
;
2873 cifs_dbg(FYI
, "In Symlink Unix style\n");
2875 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2880 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2882 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fromName
,
2883 /* find define for this maxpathcomponent */
2884 PATH_MAX
, nls_codepage
, remap
);
2885 name_len
++; /* trailing null */
2888 } else { /* BB improve the check for buffer overruns BB */
2889 name_len
= strnlen(fromName
, PATH_MAX
);
2890 name_len
++; /* trailing null */
2891 strncpy(pSMB
->FileName
, fromName
, name_len
);
2893 params
= 6 + name_len
;
2894 pSMB
->MaxSetupCount
= 0;
2898 pSMB
->Reserved2
= 0;
2899 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2900 InformationLevel
) - 4;
2901 offset
= param_offset
+ params
;
2903 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2904 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2906 cifsConvertToUTF16((__le16
*) data_offset
, toName
,
2907 /* find define for this maxpathcomponent */
2908 PATH_MAX
, nls_codepage
, remap
);
2909 name_len_target
++; /* trailing null */
2910 name_len_target
*= 2;
2911 } else { /* BB improve the check for buffer overruns BB */
2912 name_len_target
= strnlen(toName
, PATH_MAX
);
2913 name_len_target
++; /* trailing null */
2914 strncpy(data_offset
, toName
, name_len_target
);
2917 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2918 /* BB find exact max on data count below from sess */
2919 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2920 pSMB
->SetupCount
= 1;
2921 pSMB
->Reserved3
= 0;
2922 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2923 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2924 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2925 pSMB
->ParameterCount
= cpu_to_le16(params
);
2926 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2927 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2928 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2929 pSMB
->DataOffset
= cpu_to_le16(offset
);
2930 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
2931 pSMB
->Reserved4
= 0;
2932 inc_rfc1001_len(pSMB
, byte_count
);
2933 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2934 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2935 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2936 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_symlinks
);
2938 cifs_dbg(FYI
, "Send error in SetPathInfo create symlink = %d\n",
2941 cifs_buf_release(pSMB
);
2944 goto createSymLinkRetry
;
2950 CIFSUnixCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2951 const char *fromName
, const char *toName
,
2952 const struct nls_table
*nls_codepage
, int remap
)
2954 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2955 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2958 int name_len_target
;
2960 int bytes_returned
= 0;
2961 __u16 params
, param_offset
, offset
, byte_count
;
2963 cifs_dbg(FYI
, "In Create Hard link Unix style\n");
2964 createHardLinkRetry
:
2965 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2970 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2971 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->FileName
, toName
,
2972 PATH_MAX
, nls_codepage
, remap
);
2973 name_len
++; /* trailing null */
2976 } else { /* BB improve the check for buffer overruns BB */
2977 name_len
= strnlen(toName
, PATH_MAX
);
2978 name_len
++; /* trailing null */
2979 strncpy(pSMB
->FileName
, toName
, name_len
);
2981 params
= 6 + name_len
;
2982 pSMB
->MaxSetupCount
= 0;
2986 pSMB
->Reserved2
= 0;
2987 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2988 InformationLevel
) - 4;
2989 offset
= param_offset
+ params
;
2991 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2992 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2994 cifsConvertToUTF16((__le16
*) data_offset
, fromName
,
2995 PATH_MAX
, nls_codepage
, remap
);
2996 name_len_target
++; /* trailing null */
2997 name_len_target
*= 2;
2998 } else { /* BB improve the check for buffer overruns BB */
2999 name_len_target
= strnlen(fromName
, PATH_MAX
);
3000 name_len_target
++; /* trailing null */
3001 strncpy(data_offset
, fromName
, name_len_target
);
3004 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3005 /* BB find exact max on data count below from sess*/
3006 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3007 pSMB
->SetupCount
= 1;
3008 pSMB
->Reserved3
= 0;
3009 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3010 byte_count
= 3 /* pad */ + params
+ name_len_target
;
3011 pSMB
->ParameterCount
= cpu_to_le16(params
);
3012 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3013 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
3014 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3015 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3016 pSMB
->DataOffset
= cpu_to_le16(offset
);
3017 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
3018 pSMB
->Reserved4
= 0;
3019 inc_rfc1001_len(pSMB
, byte_count
);
3020 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3021 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3022 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3023 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3025 cifs_dbg(FYI
, "Send error in SetPathInfo (hard link) = %d\n",
3028 cifs_buf_release(pSMB
);
3030 goto createHardLinkRetry
;
3036 CIFSCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3037 const char *from_name
, const char *to_name
,
3038 struct cifs_sb_info
*cifs_sb
)
3041 NT_RENAME_REQ
*pSMB
= NULL
;
3042 RENAME_RSP
*pSMBr
= NULL
;
3044 int name_len
, name_len2
;
3046 int remap
= cifs_remap(cifs_sb
);
3048 cifs_dbg(FYI
, "In CIFSCreateHardLink\n");
3049 winCreateHardLinkRetry
:
3051 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
3056 pSMB
->SearchAttributes
=
3057 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
3059 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
3060 pSMB
->ClusterCount
= 0;
3062 pSMB
->BufferFormat
= 0x04;
3064 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3066 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, from_name
,
3067 PATH_MAX
, cifs_sb
->local_nls
, remap
);
3068 name_len
++; /* trailing null */
3071 /* protocol specifies ASCII buffer format (0x04) for unicode */
3072 pSMB
->OldFileName
[name_len
] = 0x04;
3073 pSMB
->OldFileName
[name_len
+ 1] = 0x00; /* pad */
3075 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
3076 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
3078 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
3079 name_len2
*= 2; /* convert to bytes */
3080 } else { /* BB improve the check for buffer overruns BB */
3081 name_len
= strnlen(from_name
, PATH_MAX
);
3082 name_len
++; /* trailing null */
3083 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
3084 name_len2
= strnlen(to_name
, PATH_MAX
);
3085 name_len2
++; /* trailing null */
3086 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
3087 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
3088 name_len2
++; /* trailing null */
3089 name_len2
++; /* signature byte */
3092 count
= 1 /* string type byte */ + name_len
+ name_len2
;
3093 inc_rfc1001_len(pSMB
, count
);
3094 pSMB
->ByteCount
= cpu_to_le16(count
);
3096 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3097 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3098 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3100 cifs_dbg(FYI
, "Send error in hard link (NT rename) = %d\n", rc
);
3102 cifs_buf_release(pSMB
);
3104 goto winCreateHardLinkRetry
;
3110 CIFSSMBUnixQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3111 const unsigned char *searchName
, char **symlinkinfo
,
3112 const struct nls_table
*nls_codepage
, int remap
)
3114 /* SMB_QUERY_FILE_UNIX_LINK */
3115 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3116 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3120 __u16 params
, byte_count
;
3123 cifs_dbg(FYI
, "In QPathSymLinkInfo (Unix) for path %s\n", searchName
);
3126 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3131 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3133 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3134 searchName
, PATH_MAX
, nls_codepage
,
3136 name_len
++; /* trailing null */
3138 } else { /* BB improve the check for buffer overruns BB */
3139 name_len
= strnlen(searchName
, PATH_MAX
);
3140 name_len
++; /* trailing null */
3141 strncpy(pSMB
->FileName
, searchName
, name_len
);
3144 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3145 pSMB
->TotalDataCount
= 0;
3146 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3147 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3148 pSMB
->MaxSetupCount
= 0;
3152 pSMB
->Reserved2
= 0;
3153 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3154 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3155 pSMB
->DataCount
= 0;
3156 pSMB
->DataOffset
= 0;
3157 pSMB
->SetupCount
= 1;
3158 pSMB
->Reserved3
= 0;
3159 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3160 byte_count
= params
+ 1 /* pad */ ;
3161 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3162 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3163 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
3164 pSMB
->Reserved4
= 0;
3165 inc_rfc1001_len(pSMB
, byte_count
);
3166 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3168 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3169 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3171 cifs_dbg(FYI
, "Send error in QuerySymLinkInfo = %d\n", rc
);
3173 /* decode response */
3175 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3176 /* BB also check enough total bytes returned */
3177 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3181 u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3183 data_start
= ((char *) &pSMBr
->hdr
.Protocol
) +
3184 le16_to_cpu(pSMBr
->t2
.DataOffset
);
3186 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3191 /* BB FIXME investigate remapping reserved chars here */
3192 *symlinkinfo
= cifs_strndup_from_utf16(data_start
,
3193 count
, is_unicode
, nls_codepage
);
3198 cifs_buf_release(pSMB
);
3200 goto querySymLinkRetry
;
3205 * Recent Windows versions now create symlinks more frequently
3206 * and they use the "reparse point" mechanism below. We can of course
3207 * do symlinks nicely to Samba and other servers which support the
3208 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3209 * "MF" symlinks optionally, but for recent Windows we really need to
3210 * reenable the code below and fix the cifs_symlink callers to handle this.
3211 * In the interim this code has been moved to its own config option so
3212 * it is not compiled in by default until callers fixed up and more tested.
3215 CIFSSMBQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3216 __u16 fid
, char **symlinkinfo
,
3217 const struct nls_table
*nls_codepage
)
3221 struct smb_com_transaction_ioctl_req
*pSMB
;
3222 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3224 unsigned int sub_len
;
3226 struct reparse_symlink_data
*reparse_buf
;
3227 struct reparse_posix_data
*posix_buf
;
3228 __u32 data_offset
, data_count
;
3231 cifs_dbg(FYI
, "In Windows reparse style QueryLink for fid %u\n", fid
);
3232 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3237 pSMB
->TotalParameterCount
= 0 ;
3238 pSMB
->TotalDataCount
= 0;
3239 pSMB
->MaxParameterCount
= cpu_to_le32(2);
3240 /* BB find exact data count max from sess structure BB */
3241 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3242 pSMB
->MaxSetupCount
= 4;
3244 pSMB
->ParameterOffset
= 0;
3245 pSMB
->DataCount
= 0;
3246 pSMB
->DataOffset
= 0;
3247 pSMB
->SetupCount
= 4;
3248 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3249 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3250 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
3251 pSMB
->IsFsctl
= 1; /* FSCTL */
3252 pSMB
->IsRootFlag
= 0;
3253 pSMB
->Fid
= fid
; /* file handle always le */
3254 pSMB
->ByteCount
= 0;
3256 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3257 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3259 cifs_dbg(FYI
, "Send error in QueryReparseLinkInfo = %d\n", rc
);
3263 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3264 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3265 if (get_bcc(&pSMBr
->hdr
) < 2 || data_offset
> 512) {
3266 /* BB also check enough total bytes returned */
3267 rc
= -EIO
; /* bad smb */
3270 if (!data_count
|| (data_count
> 2048)) {
3272 cifs_dbg(FYI
, "Invalid return data count on get reparse info ioctl\n");
3275 end_of_smb
= 2 + get_bcc(&pSMBr
->hdr
) + (char *)&pSMBr
->ByteCount
;
3276 reparse_buf
= (struct reparse_symlink_data
*)
3277 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
3278 if ((char *)reparse_buf
>= end_of_smb
) {
3282 if (reparse_buf
->ReparseTag
== cpu_to_le32(IO_REPARSE_TAG_NFS
)) {
3283 cifs_dbg(FYI
, "NFS style reparse tag\n");
3284 posix_buf
= (struct reparse_posix_data
*)reparse_buf
;
3286 if (posix_buf
->InodeType
!= cpu_to_le64(NFS_SPECFILE_LNK
)) {
3287 cifs_dbg(FYI
, "unsupported file type 0x%llx\n",
3288 le64_to_cpu(posix_buf
->InodeType
));
3293 sub_len
= le16_to_cpu(reparse_buf
->ReparseDataLength
);
3294 if (posix_buf
->PathBuffer
+ sub_len
> end_of_smb
) {
3295 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3299 *symlinkinfo
= cifs_strndup_from_utf16(posix_buf
->PathBuffer
,
3300 sub_len
, is_unicode
, nls_codepage
);
3302 } else if (reparse_buf
->ReparseTag
!=
3303 cpu_to_le32(IO_REPARSE_TAG_SYMLINK
)) {
3308 /* Reparse tag is NTFS symlink */
3309 sub_start
= le16_to_cpu(reparse_buf
->SubstituteNameOffset
) +
3310 reparse_buf
->PathBuffer
;
3311 sub_len
= le16_to_cpu(reparse_buf
->SubstituteNameLength
);
3312 if (sub_start
+ sub_len
> end_of_smb
) {
3313 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3317 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3322 /* BB FIXME investigate remapping reserved chars here */
3323 *symlinkinfo
= cifs_strndup_from_utf16(sub_start
, sub_len
, is_unicode
,
3328 cifs_buf_release(pSMB
);
3331 * Note: On -EAGAIN error only caller can retry on handle based calls
3332 * since file handle passed in no longer valid.
3338 CIFSSMB_set_compression(const unsigned int xid
, struct cifs_tcon
*tcon
,
3343 struct smb_com_transaction_compr_ioctl_req
*pSMB
;
3344 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3346 cifs_dbg(FYI
, "Set compression for %u\n", fid
);
3347 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3352 pSMB
->compression_state
= cpu_to_le16(COMPRESSION_FORMAT_DEFAULT
);
3354 pSMB
->TotalParameterCount
= 0;
3355 pSMB
->TotalDataCount
= cpu_to_le32(2);
3356 pSMB
->MaxParameterCount
= 0;
3357 pSMB
->MaxDataCount
= 0;
3358 pSMB
->MaxSetupCount
= 4;
3360 pSMB
->ParameterOffset
= 0;
3361 pSMB
->DataCount
= cpu_to_le32(2);
3363 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req
,
3364 compression_state
) - 4); /* 84 */
3365 pSMB
->SetupCount
= 4;
3366 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3367 pSMB
->ParameterCount
= 0;
3368 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_SET_COMPRESSION
);
3369 pSMB
->IsFsctl
= 1; /* FSCTL */
3370 pSMB
->IsRootFlag
= 0;
3371 pSMB
->Fid
= fid
; /* file handle always le */
3372 /* 3 byte pad, followed by 2 byte compress state */
3373 pSMB
->ByteCount
= cpu_to_le16(5);
3374 inc_rfc1001_len(pSMB
, 5);
3376 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3377 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3379 cifs_dbg(FYI
, "Send error in SetCompression = %d\n", rc
);
3381 cifs_buf_release(pSMB
);
3384 * Note: On -EAGAIN error only caller can retry on handle based calls
3385 * since file handle passed in no longer valid.
3391 #ifdef CONFIG_CIFS_POSIX
3393 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3394 static void cifs_convert_ace(struct posix_acl_xattr_entry
*ace
,
3395 struct cifs_posix_ace
*cifs_ace
)
3397 /* u8 cifs fields do not need le conversion */
3398 ace
->e_perm
= cpu_to_le16(cifs_ace
->cifs_e_perm
);
3399 ace
->e_tag
= cpu_to_le16(cifs_ace
->cifs_e_tag
);
3400 ace
->e_id
= cpu_to_le32(le64_to_cpu(cifs_ace
->cifs_uid
));
3402 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3403 ace->e_perm, ace->e_tag, ace->e_id);
3409 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3410 static int cifs_copy_posix_acl(char *trgt
, char *src
, const int buflen
,
3411 const int acl_type
, const int size_of_data_area
)
3416 struct cifs_posix_ace
*pACE
;
3417 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)src
;
3418 struct posix_acl_xattr_header
*local_acl
= (void *)trgt
;
3420 if (le16_to_cpu(cifs_acl
->version
) != CIFS_ACL_VERSION
)
3423 if (acl_type
== ACL_TYPE_ACCESS
) {
3424 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3425 pACE
= &cifs_acl
->ace_array
[0];
3426 size
= sizeof(struct cifs_posix_acl
);
3427 size
+= sizeof(struct cifs_posix_ace
) * count
;
3428 /* check if we would go beyond end of SMB */
3429 if (size_of_data_area
< size
) {
3430 cifs_dbg(FYI
, "bad CIFS POSIX ACL size %d vs. %d\n",
3431 size_of_data_area
, size
);
3434 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3435 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3436 size
= sizeof(struct cifs_posix_acl
);
3437 size
+= sizeof(struct cifs_posix_ace
) * count
;
3438 /* skip past access ACEs to get to default ACEs */
3439 pACE
= &cifs_acl
->ace_array
[count
];
3440 count
= le16_to_cpu(cifs_acl
->default_entry_count
);
3441 size
+= sizeof(struct cifs_posix_ace
) * count
;
3442 /* check if we would go beyond end of SMB */
3443 if (size_of_data_area
< size
)
3450 size
= posix_acl_xattr_size(count
);
3451 if ((buflen
== 0) || (local_acl
== NULL
)) {
3452 /* used to query ACL EA size */
3453 } else if (size
> buflen
) {
3455 } else /* buffer big enough */ {
3456 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3458 local_acl
->a_version
= cpu_to_le32(POSIX_ACL_XATTR_VERSION
);
3459 for (i
= 0; i
< count
; i
++) {
3460 cifs_convert_ace(&ace
[i
], pACE
);
3467 static __u16
convert_ace_to_cifs_ace(struct cifs_posix_ace
*cifs_ace
,
3468 const struct posix_acl_xattr_entry
*local_ace
)
3470 __u16 rc
= 0; /* 0 = ACL converted ok */
3472 cifs_ace
->cifs_e_perm
= le16_to_cpu(local_ace
->e_perm
);
3473 cifs_ace
->cifs_e_tag
= le16_to_cpu(local_ace
->e_tag
);
3474 /* BB is there a better way to handle the large uid? */
3475 if (local_ace
->e_id
== cpu_to_le32(-1)) {
3476 /* Probably no need to le convert -1 on any arch but can not hurt */
3477 cifs_ace
->cifs_uid
= cpu_to_le64(-1);
3479 cifs_ace
->cifs_uid
= cpu_to_le64(le32_to_cpu(local_ace
->e_id
));
3481 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3482 ace->e_perm, ace->e_tag, ace->e_id);
3487 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3488 static __u16
ACL_to_cifs_posix(char *parm_data
, const char *pACL
,
3489 const int buflen
, const int acl_type
)
3492 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)parm_data
;
3493 struct posix_acl_xattr_header
*local_acl
= (void *)pACL
;
3494 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3498 if ((buflen
== 0) || (pACL
== NULL
) || (cifs_acl
== NULL
))
3501 count
= posix_acl_xattr_count((size_t)buflen
);
3502 cifs_dbg(FYI
, "setting acl with %d entries from buf of length %d and version of %d\n",
3503 count
, buflen
, le32_to_cpu(local_acl
->a_version
));
3504 if (le32_to_cpu(local_acl
->a_version
) != 2) {
3505 cifs_dbg(FYI
, "unknown POSIX ACL version %d\n",
3506 le32_to_cpu(local_acl
->a_version
));
3509 cifs_acl
->version
= cpu_to_le16(1);
3510 if (acl_type
== ACL_TYPE_ACCESS
) {
3511 cifs_acl
->access_entry_count
= cpu_to_le16(count
);
3512 cifs_acl
->default_entry_count
= cpu_to_le16(0xFFFF);
3513 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3514 cifs_acl
->default_entry_count
= cpu_to_le16(count
);
3515 cifs_acl
->access_entry_count
= cpu_to_le16(0xFFFF);
3517 cifs_dbg(FYI
, "unknown ACL type %d\n", acl_type
);
3520 for (i
= 0; i
< count
; i
++) {
3521 rc
= convert_ace_to_cifs_ace(&cifs_acl
->ace_array
[i
], &ace
[i
]);
3523 /* ACE not converted */
3528 rc
= (__u16
)(count
* sizeof(struct cifs_posix_ace
));
3529 rc
+= sizeof(struct cifs_posix_acl
);
3530 /* BB add check to make sure ACL does not overflow SMB */
3536 CIFSSMBGetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3537 const unsigned char *searchName
,
3538 char *acl_inf
, const int buflen
, const int acl_type
,
3539 const struct nls_table
*nls_codepage
, int remap
)
3541 /* SMB_QUERY_POSIX_ACL */
3542 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3543 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3547 __u16 params
, byte_count
;
3549 cifs_dbg(FYI
, "In GetPosixACL (Unix) for path %s\n", searchName
);
3552 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3557 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3559 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3560 searchName
, PATH_MAX
, nls_codepage
,
3562 name_len
++; /* trailing null */
3564 pSMB
->FileName
[name_len
] = 0;
3565 pSMB
->FileName
[name_len
+1] = 0;
3566 } else { /* BB improve the check for buffer overruns BB */
3567 name_len
= strnlen(searchName
, PATH_MAX
);
3568 name_len
++; /* trailing null */
3569 strncpy(pSMB
->FileName
, searchName
, name_len
);
3572 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3573 pSMB
->TotalDataCount
= 0;
3574 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3575 /* BB find exact max data count below from sess structure BB */
3576 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3577 pSMB
->MaxSetupCount
= 0;
3581 pSMB
->Reserved2
= 0;
3582 pSMB
->ParameterOffset
= cpu_to_le16(
3583 offsetof(struct smb_com_transaction2_qpi_req
,
3584 InformationLevel
) - 4);
3585 pSMB
->DataCount
= 0;
3586 pSMB
->DataOffset
= 0;
3587 pSMB
->SetupCount
= 1;
3588 pSMB
->Reserved3
= 0;
3589 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3590 byte_count
= params
+ 1 /* pad */ ;
3591 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3592 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3593 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_ACL
);
3594 pSMB
->Reserved4
= 0;
3595 inc_rfc1001_len(pSMB
, byte_count
);
3596 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3598 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3599 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3600 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3602 cifs_dbg(FYI
, "Send error in Query POSIX ACL = %d\n", rc
);
3604 /* decode response */
3606 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3607 /* BB also check enough total bytes returned */
3608 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3609 rc
= -EIO
; /* bad smb */
3611 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3612 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3613 rc
= cifs_copy_posix_acl(acl_inf
,
3614 (char *)&pSMBr
->hdr
.Protocol
+data_offset
,
3615 buflen
, acl_type
, count
);
3618 cifs_buf_release(pSMB
);
3625 CIFSSMBSetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3626 const unsigned char *fileName
,
3627 const char *local_acl
, const int buflen
,
3629 const struct nls_table
*nls_codepage
, int remap
)
3631 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3632 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3636 int bytes_returned
= 0;
3637 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
3639 cifs_dbg(FYI
, "In SetPosixACL (Unix) for path %s\n", fileName
);
3641 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3645 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3647 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
3648 PATH_MAX
, nls_codepage
, remap
);
3649 name_len
++; /* trailing null */
3651 } else { /* BB improve the check for buffer overruns BB */
3652 name_len
= strnlen(fileName
, PATH_MAX
);
3653 name_len
++; /* trailing null */
3654 strncpy(pSMB
->FileName
, fileName
, name_len
);
3656 params
= 6 + name_len
;
3657 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3658 /* BB find max SMB size from sess */
3659 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3660 pSMB
->MaxSetupCount
= 0;
3664 pSMB
->Reserved2
= 0;
3665 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3666 InformationLevel
) - 4;
3667 offset
= param_offset
+ params
;
3668 parm_data
= ((char *) &pSMB
->hdr
.Protocol
) + offset
;
3669 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3671 /* convert to on the wire format for POSIX ACL */
3672 data_count
= ACL_to_cifs_posix(parm_data
, local_acl
, buflen
, acl_type
);
3674 if (data_count
== 0) {
3676 goto setACLerrorExit
;
3678 pSMB
->DataOffset
= cpu_to_le16(offset
);
3679 pSMB
->SetupCount
= 1;
3680 pSMB
->Reserved3
= 0;
3681 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3682 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_ACL
);
3683 byte_count
= 3 /* pad */ + params
+ data_count
;
3684 pSMB
->DataCount
= cpu_to_le16(data_count
);
3685 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3686 pSMB
->ParameterCount
= cpu_to_le16(params
);
3687 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3688 pSMB
->Reserved4
= 0;
3689 inc_rfc1001_len(pSMB
, byte_count
);
3690 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3691 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3692 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3694 cifs_dbg(FYI
, "Set POSIX ACL returned %d\n", rc
);
3697 cifs_buf_release(pSMB
);
3703 /* BB fix tabs in this function FIXME BB */
3705 CIFSGetExtAttr(const unsigned int xid
, struct cifs_tcon
*tcon
,
3706 const int netfid
, __u64
*pExtAttrBits
, __u64
*pMask
)
3709 struct smb_t2_qfi_req
*pSMB
= NULL
;
3710 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3712 __u16 params
, byte_count
;
3714 cifs_dbg(FYI
, "In GetExtAttr\n");
3719 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3724 params
= 2 /* level */ + 2 /* fid */;
3725 pSMB
->t2
.TotalDataCount
= 0;
3726 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3727 /* BB find exact max data count below from sess structure BB */
3728 pSMB
->t2
.MaxDataCount
= cpu_to_le16(4000);
3729 pSMB
->t2
.MaxSetupCount
= 0;
3730 pSMB
->t2
.Reserved
= 0;
3732 pSMB
->t2
.Timeout
= 0;
3733 pSMB
->t2
.Reserved2
= 0;
3734 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3736 pSMB
->t2
.DataCount
= 0;
3737 pSMB
->t2
.DataOffset
= 0;
3738 pSMB
->t2
.SetupCount
= 1;
3739 pSMB
->t2
.Reserved3
= 0;
3740 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3741 byte_count
= params
+ 1 /* pad */ ;
3742 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3743 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3744 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_ATTR_FLAGS
);
3747 inc_rfc1001_len(pSMB
, byte_count
);
3748 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3750 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3751 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3753 cifs_dbg(FYI
, "error %d in GetExtAttr\n", rc
);
3755 /* decode response */
3756 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3757 /* BB also check enough total bytes returned */
3758 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3759 /* If rc should we check for EOPNOSUPP and
3760 disable the srvino flag? or in caller? */
3761 rc
= -EIO
; /* bad smb */
3763 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3764 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3765 struct file_chattr_info
*pfinfo
;
3766 /* BB Do we need a cast or hash here ? */
3768 cifs_dbg(FYI
, "Illegal size ret in GetExtAttr\n");
3772 pfinfo
= (struct file_chattr_info
*)
3773 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
3774 *pExtAttrBits
= le64_to_cpu(pfinfo
->mode
);
3775 *pMask
= le64_to_cpu(pfinfo
->mask
);
3779 cifs_buf_release(pSMB
);
3781 goto GetExtAttrRetry
;
3785 #endif /* CONFIG_POSIX */
3787 #ifdef CONFIG_CIFS_ACL
3789 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3790 * all NT TRANSACTS that we init here have total parm and data under about 400
3791 * bytes (to fit in small cifs buffer size), which is the case so far, it
3792 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3793 * returned setup area) and MaxParameterCount (returned parms size) must be set
3797 smb_init_nttransact(const __u16 sub_command
, const int setup_count
,
3798 const int parm_len
, struct cifs_tcon
*tcon
,
3803 struct smb_com_ntransact_req
*pSMB
;
3805 rc
= small_smb_init(SMB_COM_NT_TRANSACT
, 19 + setup_count
, tcon
,
3809 *ret_buf
= (void *)pSMB
;
3811 pSMB
->TotalParameterCount
= cpu_to_le32(parm_len
);
3812 pSMB
->TotalDataCount
= 0;
3813 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3814 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3815 pSMB
->DataCount
= pSMB
->TotalDataCount
;
3816 temp_offset
= offsetof(struct smb_com_ntransact_req
, Parms
) +
3817 (setup_count
* 2) - 4 /* for rfc1001 length itself */;
3818 pSMB
->ParameterOffset
= cpu_to_le32(temp_offset
);
3819 pSMB
->DataOffset
= cpu_to_le32(temp_offset
+ parm_len
);
3820 pSMB
->SetupCount
= setup_count
; /* no need to le convert byte fields */
3821 pSMB
->SubCommand
= cpu_to_le16(sub_command
);
3826 validate_ntransact(char *buf
, char **ppparm
, char **ppdata
,
3827 __u32
*pparmlen
, __u32
*pdatalen
)
3830 __u32 data_count
, data_offset
, parm_count
, parm_offset
;
3831 struct smb_com_ntransact_rsp
*pSMBr
;
3840 pSMBr
= (struct smb_com_ntransact_rsp
*)buf
;
3842 bcc
= get_bcc(&pSMBr
->hdr
);
3843 end_of_smb
= 2 /* sizeof byte count */ + bcc
+
3844 (char *)&pSMBr
->ByteCount
;
3846 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3847 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3848 parm_offset
= le32_to_cpu(pSMBr
->ParameterOffset
);
3849 parm_count
= le32_to_cpu(pSMBr
->ParameterCount
);
3851 *ppparm
= (char *)&pSMBr
->hdr
.Protocol
+ parm_offset
;
3852 *ppdata
= (char *)&pSMBr
->hdr
.Protocol
+ data_offset
;
3854 /* should we also check that parm and data areas do not overlap? */
3855 if (*ppparm
> end_of_smb
) {
3856 cifs_dbg(FYI
, "parms start after end of smb\n");
3858 } else if (parm_count
+ *ppparm
> end_of_smb
) {
3859 cifs_dbg(FYI
, "parm end after end of smb\n");
3861 } else if (*ppdata
> end_of_smb
) {
3862 cifs_dbg(FYI
, "data starts after end of smb\n");
3864 } else if (data_count
+ *ppdata
> end_of_smb
) {
3865 cifs_dbg(FYI
, "data %p + count %d (%p) past smb end %p start %p\n",
3866 *ppdata
, data_count
, (data_count
+ *ppdata
),
3869 } else if (parm_count
+ data_count
> bcc
) {
3870 cifs_dbg(FYI
, "parm count and data count larger than SMB\n");
3873 *pdatalen
= data_count
;
3874 *pparmlen
= parm_count
;
3878 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3880 CIFSSMBGetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3881 struct cifs_ntsd
**acl_inf
, __u32
*pbuflen
)
3885 QUERY_SEC_DESC_REQ
*pSMB
;
3887 struct kvec rsp_iov
;
3889 cifs_dbg(FYI
, "GetCifsACL\n");
3894 rc
= smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC
, 0,
3895 8 /* parm len */, tcon
, (void **) &pSMB
);
3899 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3900 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3901 pSMB
->MaxSetupCount
= 0;
3902 pSMB
->Fid
= fid
; /* file handle always le */
3903 pSMB
->AclFlags
= cpu_to_le32(CIFS_ACL_OWNER
| CIFS_ACL_GROUP
|
3905 pSMB
->ByteCount
= cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3906 inc_rfc1001_len(pSMB
, 11);
3907 iov
[0].iov_base
= (char *)pSMB
;
3908 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
3910 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovec */, &buf_type
,
3912 cifs_small_buf_release(pSMB
);
3913 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3915 cifs_dbg(FYI
, "Send error in QuerySecDesc = %d\n", rc
);
3916 } else { /* decode response */
3920 struct smb_com_ntransact_rsp
*pSMBr
;
3923 /* validate_nttransact */
3924 rc
= validate_ntransact(rsp_iov
.iov_base
, (char **)&parm
,
3925 &pdata
, &parm_len
, pbuflen
);
3928 pSMBr
= (struct smb_com_ntransact_rsp
*)rsp_iov
.iov_base
;
3930 cifs_dbg(FYI
, "smb %p parm %p data %p\n",
3931 pSMBr
, parm
, *acl_inf
);
3933 if (le32_to_cpu(pSMBr
->ParameterCount
) != 4) {
3934 rc
= -EIO
; /* bad smb */
3939 /* BB check that data area is minimum length and as big as acl_len */
3941 acl_len
= le32_to_cpu(*parm
);
3942 if (acl_len
!= *pbuflen
) {
3943 cifs_dbg(VFS
, "acl length %d does not match %d\n",
3945 if (*pbuflen
> acl_len
)
3949 /* check if buffer is big enough for the acl
3950 header followed by the smallest SID */
3951 if ((*pbuflen
< sizeof(struct cifs_ntsd
) + 8) ||
3952 (*pbuflen
>= 64 * 1024)) {
3953 cifs_dbg(VFS
, "bad acl length %d\n", *pbuflen
);
3957 *acl_inf
= kmemdup(pdata
, *pbuflen
, GFP_KERNEL
);
3958 if (*acl_inf
== NULL
) {
3965 free_rsp_buf(buf_type
, rsp_iov
.iov_base
);
3970 CIFSSMBSetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3971 struct cifs_ntsd
*pntsd
, __u32 acllen
, int aclflag
)
3973 __u16 byte_count
, param_count
, data_count
, param_offset
, data_offset
;
3975 int bytes_returned
= 0;
3976 SET_SEC_DESC_REQ
*pSMB
= NULL
;
3980 rc
= smb_init(SMB_COM_NT_TRANSACT
, 19, tcon
, (void **) &pSMB
, &pSMBr
);
3984 pSMB
->MaxSetupCount
= 0;
3988 param_offset
= offsetof(struct smb_com_transaction_ssec_req
, Fid
) - 4;
3989 data_count
= acllen
;
3990 data_offset
= param_offset
+ param_count
;
3991 byte_count
= 3 /* pad */ + param_count
;
3993 pSMB
->DataCount
= cpu_to_le32(data_count
);
3994 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3995 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3996 pSMB
->MaxDataCount
= cpu_to_le32(16384);
3997 pSMB
->ParameterCount
= cpu_to_le32(param_count
);
3998 pSMB
->ParameterOffset
= cpu_to_le32(param_offset
);
3999 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4000 pSMB
->DataOffset
= cpu_to_le32(data_offset
);
4001 pSMB
->SetupCount
= 0;
4002 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC
);
4003 pSMB
->ByteCount
= cpu_to_le16(byte_count
+data_count
);
4005 pSMB
->Fid
= fid
; /* file handle always le */
4006 pSMB
->Reserved2
= 0;
4007 pSMB
->AclFlags
= cpu_to_le32(aclflag
);
4009 if (pntsd
&& acllen
) {
4010 memcpy((char *)pSMBr
+ offsetof(struct smb_hdr
, Protocol
) +
4011 data_offset
, pntsd
, acllen
);
4012 inc_rfc1001_len(pSMB
, byte_count
+ data_count
);
4014 inc_rfc1001_len(pSMB
, byte_count
);
4016 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4017 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4019 cifs_dbg(FYI
, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4020 bytes_returned
, rc
);
4022 cifs_dbg(FYI
, "Set CIFS ACL returned %d\n", rc
);
4023 cifs_buf_release(pSMB
);
4026 goto setCifsAclRetry
;
4031 #endif /* CONFIG_CIFS_ACL */
4033 /* Legacy Query Path Information call for lookup to old servers such
4036 SMBQueryInformation(const unsigned int xid
, struct cifs_tcon
*tcon
,
4037 const char *search_name
, FILE_ALL_INFO
*data
,
4038 const struct nls_table
*nls_codepage
, int remap
)
4040 QUERY_INFORMATION_REQ
*pSMB
;
4041 QUERY_INFORMATION_RSP
*pSMBr
;
4046 cifs_dbg(FYI
, "In SMBQPath path %s\n", search_name
);
4048 rc
= smb_init(SMB_COM_QUERY_INFORMATION
, 0, tcon
, (void **) &pSMB
,
4053 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4055 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4056 search_name
, PATH_MAX
, nls_codepage
,
4058 name_len
++; /* trailing null */
4061 name_len
= strnlen(search_name
, PATH_MAX
);
4062 name_len
++; /* trailing null */
4063 strncpy(pSMB
->FileName
, search_name
, name_len
);
4065 pSMB
->BufferFormat
= 0x04;
4066 name_len
++; /* account for buffer type byte */
4067 inc_rfc1001_len(pSMB
, (__u16
)name_len
);
4068 pSMB
->ByteCount
= cpu_to_le16(name_len
);
4070 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4071 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4073 cifs_dbg(FYI
, "Send error in QueryInfo = %d\n", rc
);
4076 __u32 time
= le32_to_cpu(pSMBr
->last_write_time
);
4078 /* decode response */
4079 /* BB FIXME - add time zone adjustment BB */
4080 memset(data
, 0, sizeof(FILE_ALL_INFO
));
4083 /* decode time fields */
4084 data
->ChangeTime
= cpu_to_le64(cifs_UnixTimeToNT(ts
));
4085 data
->LastWriteTime
= data
->ChangeTime
;
4086 data
->LastAccessTime
= 0;
4087 data
->AllocationSize
=
4088 cpu_to_le64(le32_to_cpu(pSMBr
->size
));
4089 data
->EndOfFile
= data
->AllocationSize
;
4091 cpu_to_le32(le16_to_cpu(pSMBr
->attr
));
4093 rc
= -EIO
; /* bad buffer passed in */
4095 cifs_buf_release(pSMB
);
4104 CIFSSMBQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4105 u16 netfid
, FILE_ALL_INFO
*pFindData
)
4107 struct smb_t2_qfi_req
*pSMB
= NULL
;
4108 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4111 __u16 params
, byte_count
;
4114 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4119 params
= 2 /* level */ + 2 /* fid */;
4120 pSMB
->t2
.TotalDataCount
= 0;
4121 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4122 /* BB find exact max data count below from sess structure BB */
4123 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4124 pSMB
->t2
.MaxSetupCount
= 0;
4125 pSMB
->t2
.Reserved
= 0;
4127 pSMB
->t2
.Timeout
= 0;
4128 pSMB
->t2
.Reserved2
= 0;
4129 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4131 pSMB
->t2
.DataCount
= 0;
4132 pSMB
->t2
.DataOffset
= 0;
4133 pSMB
->t2
.SetupCount
= 1;
4134 pSMB
->t2
.Reserved3
= 0;
4135 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4136 byte_count
= params
+ 1 /* pad */ ;
4137 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4138 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4139 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4142 inc_rfc1001_len(pSMB
, byte_count
);
4143 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4145 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4146 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4148 cifs_dbg(FYI
, "Send error in QFileInfo = %d", rc
);
4149 } else { /* decode response */
4150 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4152 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4154 else if (get_bcc(&pSMBr
->hdr
) < 40)
4155 rc
= -EIO
; /* bad smb */
4156 else if (pFindData
) {
4157 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4158 memcpy((char *) pFindData
,
4159 (char *) &pSMBr
->hdr
.Protocol
+
4160 data_offset
, sizeof(FILE_ALL_INFO
));
4164 cifs_buf_release(pSMB
);
4166 goto QFileInfoRetry
;
4172 CIFSSMBQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4173 const char *search_name
, FILE_ALL_INFO
*data
,
4174 int legacy
/* old style infolevel */,
4175 const struct nls_table
*nls_codepage
, int remap
)
4177 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4178 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4179 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4183 __u16 params
, byte_count
;
4185 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4187 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4192 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4194 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, search_name
,
4195 PATH_MAX
, nls_codepage
, remap
);
4196 name_len
++; /* trailing null */
4198 } else { /* BB improve the check for buffer overruns BB */
4199 name_len
= strnlen(search_name
, PATH_MAX
);
4200 name_len
++; /* trailing null */
4201 strncpy(pSMB
->FileName
, search_name
, name_len
);
4204 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4205 pSMB
->TotalDataCount
= 0;
4206 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4207 /* BB find exact max SMB PDU from sess structure BB */
4208 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4209 pSMB
->MaxSetupCount
= 0;
4213 pSMB
->Reserved2
= 0;
4214 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4215 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4216 pSMB
->DataCount
= 0;
4217 pSMB
->DataOffset
= 0;
4218 pSMB
->SetupCount
= 1;
4219 pSMB
->Reserved3
= 0;
4220 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4221 byte_count
= params
+ 1 /* pad */ ;
4222 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4223 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4225 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
4227 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4228 pSMB
->Reserved4
= 0;
4229 inc_rfc1001_len(pSMB
, byte_count
);
4230 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4232 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4233 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4235 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4236 } else { /* decode response */
4237 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4239 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4241 else if (!legacy
&& get_bcc(&pSMBr
->hdr
) < 40)
4242 rc
= -EIO
; /* bad smb */
4243 else if (legacy
&& get_bcc(&pSMBr
->hdr
) < 24)
4244 rc
= -EIO
; /* 24 or 26 expected but we do not read
4248 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4251 * On legacy responses we do not read the last field,
4252 * EAsize, fortunately since it varies by subdialect and
4253 * also note it differs on Set vs Get, ie two bytes or 4
4254 * bytes depending but we don't care here.
4257 size
= sizeof(FILE_INFO_STANDARD
);
4259 size
= sizeof(FILE_ALL_INFO
);
4260 memcpy((char *) data
, (char *) &pSMBr
->hdr
.Protocol
+
4265 cifs_buf_release(pSMB
);
4267 goto QPathInfoRetry
;
4273 CIFSSMBUnixQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4274 u16 netfid
, FILE_UNIX_BASIC_INFO
*pFindData
)
4276 struct smb_t2_qfi_req
*pSMB
= NULL
;
4277 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4280 __u16 params
, byte_count
;
4283 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4288 params
= 2 /* level */ + 2 /* fid */;
4289 pSMB
->t2
.TotalDataCount
= 0;
4290 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4291 /* BB find exact max data count below from sess structure BB */
4292 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4293 pSMB
->t2
.MaxSetupCount
= 0;
4294 pSMB
->t2
.Reserved
= 0;
4296 pSMB
->t2
.Timeout
= 0;
4297 pSMB
->t2
.Reserved2
= 0;
4298 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4300 pSMB
->t2
.DataCount
= 0;
4301 pSMB
->t2
.DataOffset
= 0;
4302 pSMB
->t2
.SetupCount
= 1;
4303 pSMB
->t2
.Reserved3
= 0;
4304 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4305 byte_count
= params
+ 1 /* pad */ ;
4306 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4307 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4308 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4311 inc_rfc1001_len(pSMB
, byte_count
);
4312 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4314 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4315 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4317 cifs_dbg(FYI
, "Send error in UnixQFileInfo = %d", rc
);
4318 } else { /* decode response */
4319 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4321 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4322 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4323 rc
= -EIO
; /* bad smb */
4325 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4326 memcpy((char *) pFindData
,
4327 (char *) &pSMBr
->hdr
.Protocol
+
4329 sizeof(FILE_UNIX_BASIC_INFO
));
4333 cifs_buf_release(pSMB
);
4335 goto UnixQFileInfoRetry
;
4341 CIFSSMBUnixQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4342 const unsigned char *searchName
,
4343 FILE_UNIX_BASIC_INFO
*pFindData
,
4344 const struct nls_table
*nls_codepage
, int remap
)
4346 /* SMB_QUERY_FILE_UNIX_BASIC */
4347 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4348 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4350 int bytes_returned
= 0;
4352 __u16 params
, byte_count
;
4354 cifs_dbg(FYI
, "In QPathInfo (Unix) the path %s\n", searchName
);
4356 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4361 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4363 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4364 PATH_MAX
, nls_codepage
, remap
);
4365 name_len
++; /* trailing null */
4367 } else { /* BB improve the check for buffer overruns BB */
4368 name_len
= strnlen(searchName
, PATH_MAX
);
4369 name_len
++; /* trailing null */
4370 strncpy(pSMB
->FileName
, searchName
, name_len
);
4373 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4374 pSMB
->TotalDataCount
= 0;
4375 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4376 /* BB find exact max SMB PDU from sess structure BB */
4377 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4378 pSMB
->MaxSetupCount
= 0;
4382 pSMB
->Reserved2
= 0;
4383 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4384 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4385 pSMB
->DataCount
= 0;
4386 pSMB
->DataOffset
= 0;
4387 pSMB
->SetupCount
= 1;
4388 pSMB
->Reserved3
= 0;
4389 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4390 byte_count
= params
+ 1 /* pad */ ;
4391 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4392 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4393 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4394 pSMB
->Reserved4
= 0;
4395 inc_rfc1001_len(pSMB
, byte_count
);
4396 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4398 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4399 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4401 cifs_dbg(FYI
, "Send error in UnixQPathInfo = %d", rc
);
4402 } else { /* decode response */
4403 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4405 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4406 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4407 rc
= -EIO
; /* bad smb */
4409 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4410 memcpy((char *) pFindData
,
4411 (char *) &pSMBr
->hdr
.Protocol
+
4413 sizeof(FILE_UNIX_BASIC_INFO
));
4416 cifs_buf_release(pSMB
);
4418 goto UnixQPathInfoRetry
;
4423 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4425 CIFSFindFirst(const unsigned int xid
, struct cifs_tcon
*tcon
,
4426 const char *searchName
, struct cifs_sb_info
*cifs_sb
,
4427 __u16
*pnetfid
, __u16 search_flags
,
4428 struct cifs_search_info
*psrch_inf
, bool msearch
)
4430 /* level 257 SMB_ */
4431 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
4432 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
4433 T2_FFIRST_RSP_PARMS
*parms
;
4435 int bytes_returned
= 0;
4436 int name_len
, remap
;
4437 __u16 params
, byte_count
;
4438 struct nls_table
*nls_codepage
;
4440 cifs_dbg(FYI
, "In FindFirst for %s\n", searchName
);
4443 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4448 nls_codepage
= cifs_sb
->local_nls
;
4449 remap
= cifs_remap(cifs_sb
);
4451 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4453 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4454 PATH_MAX
, nls_codepage
, remap
);
4455 /* We can not add the asterik earlier in case
4456 it got remapped to 0xF03A as if it were part of the
4457 directory name instead of a wildcard */
4460 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4461 pSMB
->FileName
[name_len
+1] = 0;
4462 pSMB
->FileName
[name_len
+2] = '*';
4463 pSMB
->FileName
[name_len
+3] = 0;
4464 name_len
+= 4; /* now the trailing null */
4465 /* null terminate just in case */
4466 pSMB
->FileName
[name_len
] = 0;
4467 pSMB
->FileName
[name_len
+1] = 0;
4470 } else { /* BB add check for overrun of SMB buf BB */
4471 name_len
= strnlen(searchName
, PATH_MAX
);
4472 /* BB fix here and in unicode clause above ie
4473 if (name_len > buffersize-header)
4474 free buffer exit; BB */
4475 strncpy(pSMB
->FileName
, searchName
, name_len
);
4477 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4478 pSMB
->FileName
[name_len
+1] = '*';
4479 pSMB
->FileName
[name_len
+2] = 0;
4484 params
= 12 + name_len
/* includes null */ ;
4485 pSMB
->TotalDataCount
= 0; /* no EAs */
4486 pSMB
->MaxParameterCount
= cpu_to_le16(10);
4487 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4488 pSMB
->MaxSetupCount
= 0;
4492 pSMB
->Reserved2
= 0;
4493 byte_count
= params
+ 1 /* pad */ ;
4494 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4495 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4496 pSMB
->ParameterOffset
= cpu_to_le16(
4497 offsetof(struct smb_com_transaction2_ffirst_req
, SearchAttributes
)
4499 pSMB
->DataCount
= 0;
4500 pSMB
->DataOffset
= 0;
4501 pSMB
->SetupCount
= 1; /* one byte, no need to make endian neutral */
4502 pSMB
->Reserved3
= 0;
4503 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
4504 pSMB
->SearchAttributes
=
4505 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
4507 pSMB
->SearchCount
= cpu_to_le16(CIFSMaxBufSize
/sizeof(FILE_UNIX_INFO
));
4508 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4509 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4511 /* BB what should we set StorageType to? Does it matter? BB */
4512 pSMB
->SearchStorageType
= 0;
4513 inc_rfc1001_len(pSMB
, byte_count
);
4514 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4516 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4517 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4518 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_ffirst
);
4520 if (rc
) {/* BB add logic to retry regular search if Unix search
4521 rejected unexpectedly by server */
4522 /* BB Add code to handle unsupported level rc */
4523 cifs_dbg(FYI
, "Error in FindFirst = %d\n", rc
);
4525 cifs_buf_release(pSMB
);
4527 /* BB eventually could optimize out free and realloc of buf */
4530 goto findFirstRetry
;
4531 } else { /* decode response */
4532 /* BB remember to free buffer if error BB */
4533 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4537 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4538 psrch_inf
->unicode
= true;
4540 psrch_inf
->unicode
= false;
4542 psrch_inf
->ntwrk_buf_start
= (char *)pSMBr
;
4543 psrch_inf
->smallBuf
= 0;
4544 psrch_inf
->srch_entries_start
=
4545 (char *) &pSMBr
->hdr
.Protocol
+
4546 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4547 parms
= (T2_FFIRST_RSP_PARMS
*)((char *) &pSMBr
->hdr
.Protocol
+
4548 le16_to_cpu(pSMBr
->t2
.ParameterOffset
));
4550 if (parms
->EndofSearch
)
4551 psrch_inf
->endOfSearch
= true;
4553 psrch_inf
->endOfSearch
= false;
4555 psrch_inf
->entries_in_buffer
=
4556 le16_to_cpu(parms
->SearchCount
);
4557 psrch_inf
->index_of_last_entry
= 2 /* skip . and .. */ +
4558 psrch_inf
->entries_in_buffer
;
4559 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4560 if (CIFSMaxBufSize
< lnoff
) {
4561 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4562 psrch_inf
->last_entry
= NULL
;
4566 psrch_inf
->last_entry
= psrch_inf
->srch_entries_start
+
4570 *pnetfid
= parms
->SearchHandle
;
4572 cifs_buf_release(pSMB
);
4579 int CIFSFindNext(const unsigned int xid
, struct cifs_tcon
*tcon
,
4580 __u16 searchHandle
, __u16 search_flags
,
4581 struct cifs_search_info
*psrch_inf
)
4583 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
4584 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
4585 T2_FNEXT_RSP_PARMS
*parms
;
4586 char *response_data
;
4589 unsigned int name_len
;
4590 __u16 params
, byte_count
;
4592 cifs_dbg(FYI
, "In FindNext\n");
4594 if (psrch_inf
->endOfSearch
)
4597 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4602 params
= 14; /* includes 2 bytes of null string, converted to LE below*/
4604 pSMB
->TotalDataCount
= 0; /* no EAs */
4605 pSMB
->MaxParameterCount
= cpu_to_le16(8);
4606 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4607 pSMB
->MaxSetupCount
= 0;
4611 pSMB
->Reserved2
= 0;
4612 pSMB
->ParameterOffset
= cpu_to_le16(
4613 offsetof(struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
4614 pSMB
->DataCount
= 0;
4615 pSMB
->DataOffset
= 0;
4616 pSMB
->SetupCount
= 1;
4617 pSMB
->Reserved3
= 0;
4618 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
4619 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
4621 cpu_to_le16(CIFSMaxBufSize
/ sizeof(FILE_UNIX_INFO
));
4622 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4623 pSMB
->ResumeKey
= psrch_inf
->resume_key
;
4624 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4626 name_len
= psrch_inf
->resume_name_len
;
4628 if (name_len
< PATH_MAX
) {
4629 memcpy(pSMB
->ResumeFileName
, psrch_inf
->presume_name
, name_len
);
4630 byte_count
+= name_len
;
4631 /* 14 byte parm len above enough for 2 byte null terminator */
4632 pSMB
->ResumeFileName
[name_len
] = 0;
4633 pSMB
->ResumeFileName
[name_len
+1] = 0;
4636 goto FNext2_err_exit
;
4638 byte_count
= params
+ 1 /* pad */ ;
4639 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4640 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4641 inc_rfc1001_len(pSMB
, byte_count
);
4642 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4644 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4645 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4646 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fnext
);
4649 psrch_inf
->endOfSearch
= true;
4650 cifs_buf_release(pSMB
);
4651 rc
= 0; /* search probably was closed at end of search*/
4653 cifs_dbg(FYI
, "FindNext returned = %d\n", rc
);
4654 } else { /* decode response */
4655 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4660 /* BB fixme add lock for file (srch_info) struct here */
4661 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4662 psrch_inf
->unicode
= true;
4664 psrch_inf
->unicode
= false;
4665 response_data
= (char *) &pSMBr
->hdr
.Protocol
+
4666 le16_to_cpu(pSMBr
->t2
.ParameterOffset
);
4667 parms
= (T2_FNEXT_RSP_PARMS
*)response_data
;
4668 response_data
= (char *)&pSMBr
->hdr
.Protocol
+
4669 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4670 if (psrch_inf
->smallBuf
)
4671 cifs_small_buf_release(
4672 psrch_inf
->ntwrk_buf_start
);
4674 cifs_buf_release(psrch_inf
->ntwrk_buf_start
);
4675 psrch_inf
->srch_entries_start
= response_data
;
4676 psrch_inf
->ntwrk_buf_start
= (char *)pSMB
;
4677 psrch_inf
->smallBuf
= 0;
4678 if (parms
->EndofSearch
)
4679 psrch_inf
->endOfSearch
= true;
4681 psrch_inf
->endOfSearch
= false;
4682 psrch_inf
->entries_in_buffer
=
4683 le16_to_cpu(parms
->SearchCount
);
4684 psrch_inf
->index_of_last_entry
+=
4685 psrch_inf
->entries_in_buffer
;
4686 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4687 if (CIFSMaxBufSize
< lnoff
) {
4688 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4689 psrch_inf
->last_entry
= NULL
;
4692 psrch_inf
->last_entry
=
4693 psrch_inf
->srch_entries_start
+ lnoff
;
4695 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4696 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4698 /* BB fixme add unlock here */
4703 /* BB On error, should we leave previous search buf (and count and
4704 last entry fields) intact or free the previous one? */
4706 /* Note: On -EAGAIN error only caller can retry on handle based calls
4707 since file handle passed in no longer valid */
4710 cifs_buf_release(pSMB
);
4715 CIFSFindClose(const unsigned int xid
, struct cifs_tcon
*tcon
,
4716 const __u16 searchHandle
)
4719 FINDCLOSE_REQ
*pSMB
= NULL
;
4721 cifs_dbg(FYI
, "In CIFSSMBFindClose\n");
4722 rc
= small_smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **)&pSMB
);
4724 /* no sense returning error if session restarted
4725 as file handle has been closed */
4731 pSMB
->FileID
= searchHandle
;
4732 pSMB
->ByteCount
= 0;
4733 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
4734 cifs_small_buf_release(pSMB
);
4736 cifs_dbg(VFS
, "Send error in FindClose = %d\n", rc
);
4738 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fclose
);
4740 /* Since session is dead, search handle closed on server already */
4748 CIFSGetSrvInodeNumber(const unsigned int xid
, struct cifs_tcon
*tcon
,
4749 const char *search_name
, __u64
*inode_number
,
4750 const struct nls_table
*nls_codepage
, int remap
)
4753 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4754 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4755 int name_len
, bytes_returned
;
4756 __u16 params
, byte_count
;
4758 cifs_dbg(FYI
, "In GetSrvInodeNum for %s\n", search_name
);
4762 GetInodeNumberRetry
:
4763 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4768 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4770 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4771 search_name
, PATH_MAX
, nls_codepage
,
4773 name_len
++; /* trailing null */
4775 } else { /* BB improve the check for buffer overruns BB */
4776 name_len
= strnlen(search_name
, PATH_MAX
);
4777 name_len
++; /* trailing null */
4778 strncpy(pSMB
->FileName
, search_name
, name_len
);
4781 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
4782 pSMB
->TotalDataCount
= 0;
4783 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4784 /* BB find exact max data count below from sess structure BB */
4785 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4786 pSMB
->MaxSetupCount
= 0;
4790 pSMB
->Reserved2
= 0;
4791 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4792 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4793 pSMB
->DataCount
= 0;
4794 pSMB
->DataOffset
= 0;
4795 pSMB
->SetupCount
= 1;
4796 pSMB
->Reserved3
= 0;
4797 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4798 byte_count
= params
+ 1 /* pad */ ;
4799 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4800 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4801 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO
);
4802 pSMB
->Reserved4
= 0;
4803 inc_rfc1001_len(pSMB
, byte_count
);
4804 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4806 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4807 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4809 cifs_dbg(FYI
, "error %d in QueryInternalInfo\n", rc
);
4811 /* decode response */
4812 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4813 /* BB also check enough total bytes returned */
4814 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
4815 /* If rc should we check for EOPNOSUPP and
4816 disable the srvino flag? or in caller? */
4817 rc
= -EIO
; /* bad smb */
4819 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4820 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
4821 struct file_internal_info
*pfinfo
;
4822 /* BB Do we need a cast or hash here ? */
4824 cifs_dbg(FYI
, "Illegal size ret in QryIntrnlInf\n");
4826 goto GetInodeNumOut
;
4828 pfinfo
= (struct file_internal_info
*)
4829 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
4830 *inode_number
= le64_to_cpu(pfinfo
->UniqueId
);
4834 cifs_buf_release(pSMB
);
4836 goto GetInodeNumberRetry
;
4841 CIFSGetDFSRefer(const unsigned int xid
, struct cifs_ses
*ses
,
4842 const char *search_name
, struct dfs_info3_param
**target_nodes
,
4843 unsigned int *num_of_nodes
,
4844 const struct nls_table
*nls_codepage
, int remap
)
4846 /* TRANS2_GET_DFS_REFERRAL */
4847 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
4848 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
4852 __u16 params
, byte_count
;
4854 *target_nodes
= NULL
;
4856 cifs_dbg(FYI
, "In GetDFSRefer the path %s\n", search_name
);
4857 if (ses
== NULL
|| ses
->tcon_ipc
== NULL
)
4861 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, ses
->tcon_ipc
, (void **) &pSMB
,
4866 /* server pointer checked in called function,
4867 but should never be null here anyway */
4868 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
4869 pSMB
->hdr
.Tid
= ses
->tcon_ipc
->tid
;
4870 pSMB
->hdr
.Uid
= ses
->Suid
;
4871 if (ses
->capabilities
& CAP_STATUS32
)
4872 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
4873 if (ses
->capabilities
& CAP_DFS
)
4874 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
4876 if (ses
->capabilities
& CAP_UNICODE
) {
4877 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
4879 cifsConvertToUTF16((__le16
*) pSMB
->RequestFileName
,
4880 search_name
, PATH_MAX
, nls_codepage
,
4882 name_len
++; /* trailing null */
4884 } else { /* BB improve the check for buffer overruns BB */
4885 name_len
= strnlen(search_name
, PATH_MAX
);
4886 name_len
++; /* trailing null */
4887 strncpy(pSMB
->RequestFileName
, search_name
, name_len
);
4890 if (ses
->server
->sign
)
4891 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
4893 pSMB
->hdr
.Uid
= ses
->Suid
;
4895 params
= 2 /* level */ + name_len
/*includes null */ ;
4896 pSMB
->TotalDataCount
= 0;
4897 pSMB
->DataCount
= 0;
4898 pSMB
->DataOffset
= 0;
4899 pSMB
->MaxParameterCount
= 0;
4900 /* BB find exact max SMB PDU from sess structure BB */
4901 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4902 pSMB
->MaxSetupCount
= 0;
4906 pSMB
->Reserved2
= 0;
4907 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4908 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
4909 pSMB
->SetupCount
= 1;
4910 pSMB
->Reserved3
= 0;
4911 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
4912 byte_count
= params
+ 3 /* pad */ ;
4913 pSMB
->ParameterCount
= cpu_to_le16(params
);
4914 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4915 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
4916 inc_rfc1001_len(pSMB
, byte_count
);
4917 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4919 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
4920 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4922 cifs_dbg(FYI
, "Send error in GetDFSRefer = %d\n", rc
);
4925 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4927 /* BB Also check if enough total bytes returned? */
4928 if (rc
|| get_bcc(&pSMBr
->hdr
) < 17) {
4929 rc
= -EIO
; /* bad smb */
4933 cifs_dbg(FYI
, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4934 get_bcc(&pSMBr
->hdr
), le16_to_cpu(pSMBr
->t2
.DataOffset
));
4936 /* parse returned result into more usable form */
4937 rc
= parse_dfs_referrals(&pSMBr
->dfs_data
,
4938 le16_to_cpu(pSMBr
->t2
.DataCount
),
4939 num_of_nodes
, target_nodes
, nls_codepage
,
4941 (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) != 0);
4944 cifs_buf_release(pSMB
);
4952 /* Query File System Info such as free space to old servers such as Win 9x */
4954 SMBOldQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4955 struct kstatfs
*FSData
)
4957 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4958 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4959 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4960 FILE_SYSTEM_ALLOC_INFO
*response_data
;
4962 int bytes_returned
= 0;
4963 __u16 params
, byte_count
;
4965 cifs_dbg(FYI
, "OldQFSInfo\n");
4967 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4972 params
= 2; /* level */
4973 pSMB
->TotalDataCount
= 0;
4974 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4975 pSMB
->MaxDataCount
= cpu_to_le16(1000);
4976 pSMB
->MaxSetupCount
= 0;
4980 pSMB
->Reserved2
= 0;
4981 byte_count
= params
+ 1 /* pad */ ;
4982 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4983 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4984 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4985 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
4986 pSMB
->DataCount
= 0;
4987 pSMB
->DataOffset
= 0;
4988 pSMB
->SetupCount
= 1;
4989 pSMB
->Reserved3
= 0;
4990 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
4991 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_ALLOCATION
);
4992 inc_rfc1001_len(pSMB
, byte_count
);
4993 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4995 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4996 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4998 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
4999 } else { /* decode response */
5000 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5002 if (rc
|| get_bcc(&pSMBr
->hdr
) < 18)
5003 rc
= -EIO
; /* bad smb */
5005 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5006 cifs_dbg(FYI
, "qfsinf resp BCC: %d Offset %d\n",
5007 get_bcc(&pSMBr
->hdr
), data_offset
);
5009 response_data
= (FILE_SYSTEM_ALLOC_INFO
*)
5010 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
5012 le16_to_cpu(response_data
->BytesPerSector
) *
5013 le32_to_cpu(response_data
->
5014 SectorsPerAllocationUnit
);
5016 le32_to_cpu(response_data
->TotalAllocationUnits
);
5017 FSData
->f_bfree
= FSData
->f_bavail
=
5018 le32_to_cpu(response_data
->FreeAllocationUnits
);
5019 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5020 (unsigned long long)FSData
->f_blocks
,
5021 (unsigned long long)FSData
->f_bfree
,
5025 cifs_buf_release(pSMB
);
5028 goto oldQFSInfoRetry
;
5034 CIFSSMBQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5035 struct kstatfs
*FSData
)
5037 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5038 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5039 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5040 FILE_SYSTEM_INFO
*response_data
;
5042 int bytes_returned
= 0;
5043 __u16 params
, byte_count
;
5045 cifs_dbg(FYI
, "In QFSInfo\n");
5047 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5052 params
= 2; /* level */
5053 pSMB
->TotalDataCount
= 0;
5054 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5055 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5056 pSMB
->MaxSetupCount
= 0;
5060 pSMB
->Reserved2
= 0;
5061 byte_count
= params
+ 1 /* pad */ ;
5062 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5063 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5064 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5065 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5066 pSMB
->DataCount
= 0;
5067 pSMB
->DataOffset
= 0;
5068 pSMB
->SetupCount
= 1;
5069 pSMB
->Reserved3
= 0;
5070 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5071 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
5072 inc_rfc1001_len(pSMB
, byte_count
);
5073 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5075 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5076 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5078 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5079 } else { /* decode response */
5080 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5082 if (rc
|| get_bcc(&pSMBr
->hdr
) < 24)
5083 rc
= -EIO
; /* bad smb */
5085 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5089 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5092 le32_to_cpu(response_data
->BytesPerSector
) *
5093 le32_to_cpu(response_data
->
5094 SectorsPerAllocationUnit
);
5096 le64_to_cpu(response_data
->TotalAllocationUnits
);
5097 FSData
->f_bfree
= FSData
->f_bavail
=
5098 le64_to_cpu(response_data
->FreeAllocationUnits
);
5099 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5100 (unsigned long long)FSData
->f_blocks
,
5101 (unsigned long long)FSData
->f_bfree
,
5105 cifs_buf_release(pSMB
);
5114 CIFSSMBQFSAttributeInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5116 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5117 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5118 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5119 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
5121 int bytes_returned
= 0;
5122 __u16 params
, byte_count
;
5124 cifs_dbg(FYI
, "In QFSAttributeInfo\n");
5126 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5131 params
= 2; /* level */
5132 pSMB
->TotalDataCount
= 0;
5133 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5134 /* BB find exact max SMB PDU from sess structure BB */
5135 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5136 pSMB
->MaxSetupCount
= 0;
5140 pSMB
->Reserved2
= 0;
5141 byte_count
= params
+ 1 /* pad */ ;
5142 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5143 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5144 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5145 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5146 pSMB
->DataCount
= 0;
5147 pSMB
->DataOffset
= 0;
5148 pSMB
->SetupCount
= 1;
5149 pSMB
->Reserved3
= 0;
5150 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5151 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
5152 inc_rfc1001_len(pSMB
, byte_count
);
5153 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5155 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5156 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5158 cifs_dbg(VFS
, "Send error in QFSAttributeInfo = %d\n", rc
);
5159 } else { /* decode response */
5160 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5162 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5163 /* BB also check if enough bytes returned */
5164 rc
= -EIO
; /* bad smb */
5166 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5168 (FILE_SYSTEM_ATTRIBUTE_INFO
5169 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5171 memcpy(&tcon
->fsAttrInfo
, response_data
,
5172 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO
));
5175 cifs_buf_release(pSMB
);
5178 goto QFSAttributeRetry
;
5184 CIFSSMBQFSDeviceInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5186 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5187 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5188 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5189 FILE_SYSTEM_DEVICE_INFO
*response_data
;
5191 int bytes_returned
= 0;
5192 __u16 params
, byte_count
;
5194 cifs_dbg(FYI
, "In QFSDeviceInfo\n");
5196 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5201 params
= 2; /* level */
5202 pSMB
->TotalDataCount
= 0;
5203 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5204 /* BB find exact max SMB PDU from sess structure BB */
5205 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5206 pSMB
->MaxSetupCount
= 0;
5210 pSMB
->Reserved2
= 0;
5211 byte_count
= params
+ 1 /* pad */ ;
5212 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5213 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5214 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5215 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5217 pSMB
->DataCount
= 0;
5218 pSMB
->DataOffset
= 0;
5219 pSMB
->SetupCount
= 1;
5220 pSMB
->Reserved3
= 0;
5221 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5222 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
5223 inc_rfc1001_len(pSMB
, byte_count
);
5224 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5226 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5227 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5229 cifs_dbg(FYI
, "Send error in QFSDeviceInfo = %d\n", rc
);
5230 } else { /* decode response */
5231 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5233 if (rc
|| get_bcc(&pSMBr
->hdr
) <
5234 sizeof(FILE_SYSTEM_DEVICE_INFO
))
5235 rc
= -EIO
; /* bad smb */
5237 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5239 (FILE_SYSTEM_DEVICE_INFO
*)
5240 (((char *) &pSMBr
->hdr
.Protocol
) +
5242 memcpy(&tcon
->fsDevInfo
, response_data
,
5243 sizeof(FILE_SYSTEM_DEVICE_INFO
));
5246 cifs_buf_release(pSMB
);
5249 goto QFSDeviceRetry
;
5255 CIFSSMBQFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5257 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5258 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5259 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5260 FILE_SYSTEM_UNIX_INFO
*response_data
;
5262 int bytes_returned
= 0;
5263 __u16 params
, byte_count
;
5265 cifs_dbg(FYI
, "In QFSUnixInfo\n");
5267 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5268 (void **) &pSMB
, (void **) &pSMBr
);
5272 params
= 2; /* level */
5273 pSMB
->TotalDataCount
= 0;
5274 pSMB
->DataCount
= 0;
5275 pSMB
->DataOffset
= 0;
5276 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5277 /* BB find exact max SMB PDU from sess structure BB */
5278 pSMB
->MaxDataCount
= cpu_to_le16(100);
5279 pSMB
->MaxSetupCount
= 0;
5283 pSMB
->Reserved2
= 0;
5284 byte_count
= params
+ 1 /* pad */ ;
5285 pSMB
->ParameterCount
= cpu_to_le16(params
);
5286 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5287 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5288 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5289 pSMB
->SetupCount
= 1;
5290 pSMB
->Reserved3
= 0;
5291 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5292 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
5293 inc_rfc1001_len(pSMB
, byte_count
);
5294 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5296 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5297 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5299 cifs_dbg(VFS
, "Send error in QFSUnixInfo = %d\n", rc
);
5300 } else { /* decode response */
5301 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5303 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5304 rc
= -EIO
; /* bad smb */
5306 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5308 (FILE_SYSTEM_UNIX_INFO
5309 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5311 memcpy(&tcon
->fsUnixInfo
, response_data
,
5312 sizeof(FILE_SYSTEM_UNIX_INFO
));
5315 cifs_buf_release(pSMB
);
5325 CIFSSMBSetFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
, __u64 cap
)
5327 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5328 TRANSACTION2_SETFSI_REQ
*pSMB
= NULL
;
5329 TRANSACTION2_SETFSI_RSP
*pSMBr
= NULL
;
5331 int bytes_returned
= 0;
5332 __u16 params
, param_offset
, offset
, byte_count
;
5334 cifs_dbg(FYI
, "In SETFSUnixInfo\n");
5336 /* BB switch to small buf init to save memory */
5337 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5338 (void **) &pSMB
, (void **) &pSMBr
);
5342 params
= 4; /* 2 bytes zero followed by info level. */
5343 pSMB
->MaxSetupCount
= 0;
5347 pSMB
->Reserved2
= 0;
5348 param_offset
= offsetof(struct smb_com_transaction2_setfsi_req
, FileNum
)
5350 offset
= param_offset
+ params
;
5352 pSMB
->MaxParameterCount
= cpu_to_le16(4);
5353 /* BB find exact max SMB PDU from sess structure BB */
5354 pSMB
->MaxDataCount
= cpu_to_le16(100);
5355 pSMB
->SetupCount
= 1;
5356 pSMB
->Reserved3
= 0;
5357 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FS_INFORMATION
);
5358 byte_count
= 1 /* pad */ + params
+ 12;
5360 pSMB
->DataCount
= cpu_to_le16(12);
5361 pSMB
->ParameterCount
= cpu_to_le16(params
);
5362 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5363 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5364 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5365 pSMB
->DataOffset
= cpu_to_le16(offset
);
5369 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_CIFS_UNIX_INFO
);
5372 pSMB
->ClientUnixMajor
= cpu_to_le16(CIFS_UNIX_MAJOR_VERSION
);
5373 pSMB
->ClientUnixMinor
= cpu_to_le16(CIFS_UNIX_MINOR_VERSION
);
5374 pSMB
->ClientUnixCap
= cpu_to_le64(cap
);
5376 inc_rfc1001_len(pSMB
, byte_count
);
5377 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5379 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5380 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5382 cifs_dbg(VFS
, "Send error in SETFSUnixInfo = %d\n", rc
);
5383 } else { /* decode response */
5384 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5386 rc
= -EIO
; /* bad smb */
5388 cifs_buf_release(pSMB
);
5391 goto SETFSUnixRetry
;
5399 CIFSSMBQFSPosixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5400 struct kstatfs
*FSData
)
5402 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5403 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5404 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5405 FILE_SYSTEM_POSIX_INFO
*response_data
;
5407 int bytes_returned
= 0;
5408 __u16 params
, byte_count
;
5410 cifs_dbg(FYI
, "In QFSPosixInfo\n");
5412 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5417 params
= 2; /* level */
5418 pSMB
->TotalDataCount
= 0;
5419 pSMB
->DataCount
= 0;
5420 pSMB
->DataOffset
= 0;
5421 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5422 /* BB find exact max SMB PDU from sess structure BB */
5423 pSMB
->MaxDataCount
= cpu_to_le16(100);
5424 pSMB
->MaxSetupCount
= 0;
5428 pSMB
->Reserved2
= 0;
5429 byte_count
= params
+ 1 /* pad */ ;
5430 pSMB
->ParameterCount
= cpu_to_le16(params
);
5431 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5432 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5433 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5434 pSMB
->SetupCount
= 1;
5435 pSMB
->Reserved3
= 0;
5436 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5437 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_FS_INFO
);
5438 inc_rfc1001_len(pSMB
, byte_count
);
5439 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5441 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5442 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5444 cifs_dbg(FYI
, "Send error in QFSUnixInfo = %d\n", rc
);
5445 } else { /* decode response */
5446 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5448 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5449 rc
= -EIO
; /* bad smb */
5451 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5453 (FILE_SYSTEM_POSIX_INFO
5454 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5457 le32_to_cpu(response_data
->BlockSize
);
5459 le64_to_cpu(response_data
->TotalBlocks
);
5461 le64_to_cpu(response_data
->BlocksAvail
);
5462 if (response_data
->UserBlocksAvail
== cpu_to_le64(-1)) {
5463 FSData
->f_bavail
= FSData
->f_bfree
;
5466 le64_to_cpu(response_data
->UserBlocksAvail
);
5468 if (response_data
->TotalFileNodes
!= cpu_to_le64(-1))
5470 le64_to_cpu(response_data
->TotalFileNodes
);
5471 if (response_data
->FreeFileNodes
!= cpu_to_le64(-1))
5473 le64_to_cpu(response_data
->FreeFileNodes
);
5476 cifs_buf_release(pSMB
);
5486 * We can not use write of zero bytes trick to set file size due to need for
5487 * large file support. Also note that this SetPathInfo is preferred to
5488 * SetFileInfo based method in next routine which is only needed to work around
5489 * a sharing violation bugin Samba which this routine can run into.
5492 CIFSSMBSetEOF(const unsigned int xid
, struct cifs_tcon
*tcon
,
5493 const char *file_name
, __u64 size
, struct cifs_sb_info
*cifs_sb
,
5494 bool set_allocation
)
5496 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5497 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5498 struct file_end_of_file_info
*parm_data
;
5501 int bytes_returned
= 0;
5502 int remap
= cifs_remap(cifs_sb
);
5504 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
5506 cifs_dbg(FYI
, "In SetEOF\n");
5508 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5513 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5515 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5516 PATH_MAX
, cifs_sb
->local_nls
, remap
);
5517 name_len
++; /* trailing null */
5519 } else { /* BB improve the check for buffer overruns BB */
5520 name_len
= strnlen(file_name
, PATH_MAX
);
5521 name_len
++; /* trailing null */
5522 strncpy(pSMB
->FileName
, file_name
, name_len
);
5524 params
= 6 + name_len
;
5525 data_count
= sizeof(struct file_end_of_file_info
);
5526 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5527 pSMB
->MaxDataCount
= cpu_to_le16(4100);
5528 pSMB
->MaxSetupCount
= 0;
5532 pSMB
->Reserved2
= 0;
5533 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5534 InformationLevel
) - 4;
5535 offset
= param_offset
+ params
;
5536 if (set_allocation
) {
5537 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5538 pSMB
->InformationLevel
=
5539 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5541 pSMB
->InformationLevel
=
5542 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5543 } else /* Set File Size */ {
5544 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5545 pSMB
->InformationLevel
=
5546 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5548 pSMB
->InformationLevel
=
5549 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5553 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
5555 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5556 pSMB
->DataOffset
= cpu_to_le16(offset
);
5557 pSMB
->SetupCount
= 1;
5558 pSMB
->Reserved3
= 0;
5559 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5560 byte_count
= 3 /* pad */ + params
+ data_count
;
5561 pSMB
->DataCount
= cpu_to_le16(data_count
);
5562 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5563 pSMB
->ParameterCount
= cpu_to_le16(params
);
5564 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5565 pSMB
->Reserved4
= 0;
5566 inc_rfc1001_len(pSMB
, byte_count
);
5567 parm_data
->FileSize
= cpu_to_le64(size
);
5568 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5569 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5570 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5572 cifs_dbg(FYI
, "SetPathInfo (file size) returned %d\n", rc
);
5574 cifs_buf_release(pSMB
);
5583 CIFSSMBSetFileSize(const unsigned int xid
, struct cifs_tcon
*tcon
,
5584 struct cifsFileInfo
*cfile
, __u64 size
, bool set_allocation
)
5586 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5587 struct file_end_of_file_info
*parm_data
;
5589 __u16 params
, param_offset
, offset
, byte_count
, count
;
5591 cifs_dbg(FYI
, "SetFileSize (via SetFileInfo) %lld\n",
5593 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5598 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)cfile
->pid
);
5599 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(cfile
->pid
>> 16));
5602 pSMB
->MaxSetupCount
= 0;
5606 pSMB
->Reserved2
= 0;
5607 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5608 offset
= param_offset
+ params
;
5610 count
= sizeof(struct file_end_of_file_info
);
5611 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5612 /* BB find exact max SMB PDU from sess structure BB */
5613 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5614 pSMB
->SetupCount
= 1;
5615 pSMB
->Reserved3
= 0;
5616 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5617 byte_count
= 3 /* pad */ + params
+ count
;
5618 pSMB
->DataCount
= cpu_to_le16(count
);
5619 pSMB
->ParameterCount
= cpu_to_le16(params
);
5620 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5621 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5622 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5624 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
)
5626 pSMB
->DataOffset
= cpu_to_le16(offset
);
5627 parm_data
->FileSize
= cpu_to_le64(size
);
5628 pSMB
->Fid
= cfile
->fid
.netfid
;
5629 if (set_allocation
) {
5630 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5631 pSMB
->InformationLevel
=
5632 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5634 pSMB
->InformationLevel
=
5635 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5636 } else /* Set File Size */ {
5637 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5638 pSMB
->InformationLevel
=
5639 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5641 pSMB
->InformationLevel
=
5642 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5644 pSMB
->Reserved4
= 0;
5645 inc_rfc1001_len(pSMB
, byte_count
);
5646 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5647 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5648 cifs_small_buf_release(pSMB
);
5650 cifs_dbg(FYI
, "Send error in SetFileInfo (SetFileSize) = %d\n",
5654 /* Note: On -EAGAIN error only caller can retry on handle based calls
5655 since file handle passed in no longer valid */
5660 /* Some legacy servers such as NT4 require that the file times be set on
5661 an open handle, rather than by pathname - this is awkward due to
5662 potential access conflicts on the open, but it is unavoidable for these
5663 old servers since the only other choice is to go from 100 nanosecond DCE
5664 time and resort to the original setpathinfo level which takes the ancient
5665 DOS time format with 2 second granularity */
5667 CIFSSMBSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5668 const FILE_BASIC_INFO
*data
, __u16 fid
, __u32 pid_of_opener
)
5670 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5673 __u16 params
, param_offset
, offset
, byte_count
, count
;
5675 cifs_dbg(FYI
, "Set Times (via SetFileInfo)\n");
5676 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5681 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5682 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5685 pSMB
->MaxSetupCount
= 0;
5689 pSMB
->Reserved2
= 0;
5690 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5691 offset
= param_offset
+ params
;
5693 data_offset
= (char *)pSMB
+
5694 offsetof(struct smb_hdr
, Protocol
) + offset
;
5696 count
= sizeof(FILE_BASIC_INFO
);
5697 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5698 /* BB find max SMB PDU from sess */
5699 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5700 pSMB
->SetupCount
= 1;
5701 pSMB
->Reserved3
= 0;
5702 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5703 byte_count
= 3 /* pad */ + params
+ count
;
5704 pSMB
->DataCount
= cpu_to_le16(count
);
5705 pSMB
->ParameterCount
= cpu_to_le16(params
);
5706 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5707 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5708 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5709 pSMB
->DataOffset
= cpu_to_le16(offset
);
5711 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5712 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5714 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5715 pSMB
->Reserved4
= 0;
5716 inc_rfc1001_len(pSMB
, byte_count
);
5717 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5718 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5719 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5720 cifs_small_buf_release(pSMB
);
5722 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5725 /* Note: On -EAGAIN error only caller can retry on handle based calls
5726 since file handle passed in no longer valid */
5732 CIFSSMBSetFileDisposition(const unsigned int xid
, struct cifs_tcon
*tcon
,
5733 bool delete_file
, __u16 fid
, __u32 pid_of_opener
)
5735 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5738 __u16 params
, param_offset
, offset
, byte_count
, count
;
5740 cifs_dbg(FYI
, "Set File Disposition (via SetFileInfo)\n");
5741 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5746 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5747 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5750 pSMB
->MaxSetupCount
= 0;
5754 pSMB
->Reserved2
= 0;
5755 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5756 offset
= param_offset
+ params
;
5758 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5761 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5762 /* BB find max SMB PDU from sess */
5763 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5764 pSMB
->SetupCount
= 1;
5765 pSMB
->Reserved3
= 0;
5766 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5767 byte_count
= 3 /* pad */ + params
+ count
;
5768 pSMB
->DataCount
= cpu_to_le16(count
);
5769 pSMB
->ParameterCount
= cpu_to_le16(params
);
5770 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5771 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5772 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5773 pSMB
->DataOffset
= cpu_to_le16(offset
);
5775 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO
);
5776 pSMB
->Reserved4
= 0;
5777 inc_rfc1001_len(pSMB
, byte_count
);
5778 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5779 *data_offset
= delete_file
? 1 : 0;
5780 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5781 cifs_small_buf_release(pSMB
);
5783 cifs_dbg(FYI
, "Send error in SetFileDisposition = %d\n", rc
);
5789 CIFSSMBSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5790 const char *fileName
, const FILE_BASIC_INFO
*data
,
5791 const struct nls_table
*nls_codepage
, int remap
)
5793 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5794 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5797 int bytes_returned
= 0;
5799 __u16 params
, param_offset
, offset
, byte_count
, count
;
5801 cifs_dbg(FYI
, "In SetTimes\n");
5804 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5809 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5811 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5812 PATH_MAX
, nls_codepage
, remap
);
5813 name_len
++; /* trailing null */
5815 } else { /* BB improve the check for buffer overruns BB */
5816 name_len
= strnlen(fileName
, PATH_MAX
);
5817 name_len
++; /* trailing null */
5818 strncpy(pSMB
->FileName
, fileName
, name_len
);
5821 params
= 6 + name_len
;
5822 count
= sizeof(FILE_BASIC_INFO
);
5823 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5824 /* BB find max SMB PDU from sess structure BB */
5825 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5826 pSMB
->MaxSetupCount
= 0;
5830 pSMB
->Reserved2
= 0;
5831 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5832 InformationLevel
) - 4;
5833 offset
= param_offset
+ params
;
5834 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5835 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5836 pSMB
->DataOffset
= cpu_to_le16(offset
);
5837 pSMB
->SetupCount
= 1;
5838 pSMB
->Reserved3
= 0;
5839 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5840 byte_count
= 3 /* pad */ + params
+ count
;
5842 pSMB
->DataCount
= cpu_to_le16(count
);
5843 pSMB
->ParameterCount
= cpu_to_le16(params
);
5844 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5845 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5846 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5847 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5849 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5850 pSMB
->Reserved4
= 0;
5851 inc_rfc1001_len(pSMB
, byte_count
);
5852 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5853 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5854 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5855 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5857 cifs_dbg(FYI
, "SetPathInfo (times) returned %d\n", rc
);
5859 cifs_buf_release(pSMB
);
5867 /* Can not be used to set time stamps yet (due to old DOS time format) */
5868 /* Can be used to set attributes */
5869 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5870 handling it anyway and NT4 was what we thought it would be needed for
5871 Do not delete it until we prove whether needed for Win9x though */
5873 CIFSSMBSetAttrLegacy(unsigned int xid
, struct cifs_tcon
*tcon
, char *fileName
,
5874 __u16 dos_attrs
, const struct nls_table
*nls_codepage
)
5876 SETATTR_REQ
*pSMB
= NULL
;
5877 SETATTR_RSP
*pSMBr
= NULL
;
5882 cifs_dbg(FYI
, "In SetAttrLegacy\n");
5885 rc
= smb_init(SMB_COM_SETATTR
, 8, tcon
, (void **) &pSMB
,
5890 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5892 ConvertToUTF16((__le16
*) pSMB
->fileName
, fileName
,
5893 PATH_MAX
, nls_codepage
);
5894 name_len
++; /* trailing null */
5896 } else { /* BB improve the check for buffer overruns BB */
5897 name_len
= strnlen(fileName
, PATH_MAX
);
5898 name_len
++; /* trailing null */
5899 strncpy(pSMB
->fileName
, fileName
, name_len
);
5901 pSMB
->attr
= cpu_to_le16(dos_attrs
);
5902 pSMB
->BufferFormat
= 0x04;
5903 inc_rfc1001_len(pSMB
, name_len
+ 1);
5904 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
5905 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5906 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5908 cifs_dbg(FYI
, "Error in LegacySetAttr = %d\n", rc
);
5910 cifs_buf_release(pSMB
);
5913 goto SetAttrLgcyRetry
;
5917 #endif /* temporarily unneeded SetAttr legacy function */
5920 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO
*data_offset
,
5921 const struct cifs_unix_set_info_args
*args
)
5923 u64 uid
= NO_CHANGE_64
, gid
= NO_CHANGE_64
;
5924 u64 mode
= args
->mode
;
5926 if (uid_valid(args
->uid
))
5927 uid
= from_kuid(&init_user_ns
, args
->uid
);
5928 if (gid_valid(args
->gid
))
5929 gid
= from_kgid(&init_user_ns
, args
->gid
);
5932 * Samba server ignores set of file size to zero due to bugs in some
5933 * older clients, but we should be precise - we use SetFileSize to
5934 * set file size and do not want to truncate file size to zero
5935 * accidentally as happened on one Samba server beta by putting
5936 * zero instead of -1 here
5938 data_offset
->EndOfFile
= cpu_to_le64(NO_CHANGE_64
);
5939 data_offset
->NumOfBytes
= cpu_to_le64(NO_CHANGE_64
);
5940 data_offset
->LastStatusChange
= cpu_to_le64(args
->ctime
);
5941 data_offset
->LastAccessTime
= cpu_to_le64(args
->atime
);
5942 data_offset
->LastModificationTime
= cpu_to_le64(args
->mtime
);
5943 data_offset
->Uid
= cpu_to_le64(uid
);
5944 data_offset
->Gid
= cpu_to_le64(gid
);
5945 /* better to leave device as zero when it is */
5946 data_offset
->DevMajor
= cpu_to_le64(MAJOR(args
->device
));
5947 data_offset
->DevMinor
= cpu_to_le64(MINOR(args
->device
));
5948 data_offset
->Permissions
= cpu_to_le64(mode
);
5951 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
5952 else if (S_ISDIR(mode
))
5953 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
5954 else if (S_ISLNK(mode
))
5955 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
5956 else if (S_ISCHR(mode
))
5957 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
5958 else if (S_ISBLK(mode
))
5959 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
5960 else if (S_ISFIFO(mode
))
5961 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
5962 else if (S_ISSOCK(mode
))
5963 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
5967 CIFSSMBUnixSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5968 const struct cifs_unix_set_info_args
*args
,
5969 u16 fid
, u32 pid_of_opener
)
5971 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5974 u16 params
, param_offset
, offset
, byte_count
, count
;
5976 cifs_dbg(FYI
, "Set Unix Info (via SetFileInfo)\n");
5977 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5982 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5983 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5986 pSMB
->MaxSetupCount
= 0;
5990 pSMB
->Reserved2
= 0;
5991 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5992 offset
= param_offset
+ params
;
5994 data_offset
= (char *)pSMB
+
5995 offsetof(struct smb_hdr
, Protocol
) + offset
;
5997 count
= sizeof(FILE_UNIX_BASIC_INFO
);
5999 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6000 /* BB find max SMB PDU from sess */
6001 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6002 pSMB
->SetupCount
= 1;
6003 pSMB
->Reserved3
= 0;
6004 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
6005 byte_count
= 3 /* pad */ + params
+ count
;
6006 pSMB
->DataCount
= cpu_to_le16(count
);
6007 pSMB
->ParameterCount
= cpu_to_le16(params
);
6008 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6009 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6010 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6011 pSMB
->DataOffset
= cpu_to_le16(offset
);
6013 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6014 pSMB
->Reserved4
= 0;
6015 inc_rfc1001_len(pSMB
, byte_count
);
6016 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6018 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO
*)data_offset
, args
);
6020 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
6021 cifs_small_buf_release(pSMB
);
6023 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
6026 /* Note: On -EAGAIN error only caller can retry on handle based calls
6027 since file handle passed in no longer valid */
6033 CIFSSMBUnixSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6034 const char *file_name
,
6035 const struct cifs_unix_set_info_args
*args
,
6036 const struct nls_table
*nls_codepage
, int remap
)
6038 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
6039 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
6042 int bytes_returned
= 0;
6043 FILE_UNIX_BASIC_INFO
*data_offset
;
6044 __u16 params
, param_offset
, offset
, count
, byte_count
;
6046 cifs_dbg(FYI
, "In SetUID/GID/Mode\n");
6048 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6053 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6055 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
6056 PATH_MAX
, nls_codepage
, remap
);
6057 name_len
++; /* trailing null */
6059 } else { /* BB improve the check for buffer overruns BB */
6060 name_len
= strnlen(file_name
, PATH_MAX
);
6061 name_len
++; /* trailing null */
6062 strncpy(pSMB
->FileName
, file_name
, name_len
);
6065 params
= 6 + name_len
;
6066 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6067 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6068 /* BB find max SMB PDU from sess structure BB */
6069 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6070 pSMB
->MaxSetupCount
= 0;
6074 pSMB
->Reserved2
= 0;
6075 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6076 InformationLevel
) - 4;
6077 offset
= param_offset
+ params
;
6079 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
6081 memset(data_offset
, 0, count
);
6082 pSMB
->DataOffset
= cpu_to_le16(offset
);
6083 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6084 pSMB
->SetupCount
= 1;
6085 pSMB
->Reserved3
= 0;
6086 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6087 byte_count
= 3 /* pad */ + params
+ count
;
6088 pSMB
->ParameterCount
= cpu_to_le16(params
);
6089 pSMB
->DataCount
= cpu_to_le16(count
);
6090 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6091 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6092 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6093 pSMB
->Reserved4
= 0;
6094 inc_rfc1001_len(pSMB
, byte_count
);
6096 cifs_fill_unix_set_info(data_offset
, args
);
6098 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6099 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6100 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6102 cifs_dbg(FYI
, "SetPathInfo (perms) returned %d\n", rc
);
6104 cifs_buf_release(pSMB
);
6110 #ifdef CONFIG_CIFS_XATTR
6112 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6113 * function used by listxattr and getxattr type calls. When ea_name is set,
6114 * it looks for that attribute name and stuffs that value into the EAData
6115 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6116 * buffer. In both cases, the return value is either the length of the
6117 * resulting data or a negative error code. If EAData is a NULL pointer then
6118 * the data isn't copied to it, but the length is returned.
6121 CIFSSMBQAllEAs(const unsigned int xid
, struct cifs_tcon
*tcon
,
6122 const unsigned char *searchName
, const unsigned char *ea_name
,
6123 char *EAData
, size_t buf_size
,
6124 struct cifs_sb_info
*cifs_sb
)
6126 /* BB assumes one setup word */
6127 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
6128 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
6129 int remap
= cifs_remap(cifs_sb
);
6130 struct nls_table
*nls_codepage
= cifs_sb
->local_nls
;
6134 struct fealist
*ea_response_data
;
6135 struct fea
*temp_fea
;
6138 __u16 params
, byte_count
, data_offset
;
6139 unsigned int ea_name_len
= ea_name
? strlen(ea_name
) : 0;
6141 cifs_dbg(FYI
, "In Query All EAs path %s\n", searchName
);
6143 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6148 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6150 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
6151 PATH_MAX
, nls_codepage
, remap
);
6152 list_len
++; /* trailing null */
6154 } else { /* BB improve the check for buffer overruns BB */
6155 list_len
= strnlen(searchName
, PATH_MAX
);
6156 list_len
++; /* trailing null */
6157 strncpy(pSMB
->FileName
, searchName
, list_len
);
6160 params
= 2 /* level */ + 4 /* reserved */ + list_len
/* includes NUL */;
6161 pSMB
->TotalDataCount
= 0;
6162 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6163 /* BB find exact max SMB PDU from sess structure BB */
6164 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
6165 pSMB
->MaxSetupCount
= 0;
6169 pSMB
->Reserved2
= 0;
6170 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
6171 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
6172 pSMB
->DataCount
= 0;
6173 pSMB
->DataOffset
= 0;
6174 pSMB
->SetupCount
= 1;
6175 pSMB
->Reserved3
= 0;
6176 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
6177 byte_count
= params
+ 1 /* pad */ ;
6178 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
6179 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6180 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
6181 pSMB
->Reserved4
= 0;
6182 inc_rfc1001_len(pSMB
, byte_count
);
6183 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6185 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6186 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6188 cifs_dbg(FYI
, "Send error in QueryAllEAs = %d\n", rc
);
6193 /* BB also check enough total bytes returned */
6194 /* BB we need to improve the validity checking
6195 of these trans2 responses */
6197 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
6198 if (rc
|| get_bcc(&pSMBr
->hdr
) < 4) {
6199 rc
= -EIO
; /* bad smb */
6203 /* check that length of list is not more than bcc */
6204 /* check that each entry does not go beyond length
6206 /* check that each element of each entry does not
6207 go beyond end of list */
6208 /* validate_trans2_offsets() */
6209 /* BB check if start of smb + data_offset > &bcc+ bcc */
6211 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
6212 ea_response_data
= (struct fealist
*)
6213 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
6215 list_len
= le32_to_cpu(ea_response_data
->list_len
);
6216 cifs_dbg(FYI
, "ea length %d\n", list_len
);
6217 if (list_len
<= 8) {
6218 cifs_dbg(FYI
, "empty EA list returned from server\n");
6219 /* didn't find the named attribute */
6225 /* make sure list_len doesn't go past end of SMB */
6226 end_of_smb
= (char *)pByteArea(&pSMBr
->hdr
) + get_bcc(&pSMBr
->hdr
);
6227 if ((char *)ea_response_data
+ list_len
> end_of_smb
) {
6228 cifs_dbg(FYI
, "EA list appears to go beyond SMB\n");
6233 /* account for ea list len */
6235 temp_fea
= ea_response_data
->list
;
6236 temp_ptr
= (char *)temp_fea
;
6237 while (list_len
> 0) {
6238 unsigned int name_len
;
6243 /* make sure we can read name_len and value_len */
6245 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6250 name_len
= temp_fea
->name_len
;
6251 value_len
= le16_to_cpu(temp_fea
->value_len
);
6252 list_len
-= name_len
+ 1 + value_len
;
6254 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6260 if (ea_name_len
== name_len
&&
6261 memcmp(ea_name
, temp_ptr
, name_len
) == 0) {
6262 temp_ptr
+= name_len
+ 1;
6266 if ((size_t)value_len
> buf_size
) {
6270 memcpy(EAData
, temp_ptr
, value_len
);
6274 /* account for prefix user. and trailing null */
6275 rc
+= (5 + 1 + name_len
);
6276 if (rc
< (int) buf_size
) {
6277 memcpy(EAData
, "user.", 5);
6279 memcpy(EAData
, temp_ptr
, name_len
);
6281 /* null terminate name */
6284 } else if (buf_size
== 0) {
6285 /* skip copy - calc size only */
6287 /* stop before overrun buffer */
6292 temp_ptr
+= name_len
+ 1 + value_len
;
6293 temp_fea
= (struct fea
*)temp_ptr
;
6296 /* didn't find the named attribute */
6301 cifs_buf_release(pSMB
);
6309 CIFSSMBSetEA(const unsigned int xid
, struct cifs_tcon
*tcon
,
6310 const char *fileName
, const char *ea_name
, const void *ea_value
,
6311 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
,
6312 struct cifs_sb_info
*cifs_sb
)
6314 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
6315 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
6316 struct fealist
*parm_data
;
6319 int bytes_returned
= 0;
6320 __u16 params
, param_offset
, byte_count
, offset
, count
;
6321 int remap
= cifs_remap(cifs_sb
);
6323 cifs_dbg(FYI
, "In SetEA\n");
6325 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6330 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6332 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
6333 PATH_MAX
, nls_codepage
, remap
);
6334 name_len
++; /* trailing null */
6336 } else { /* BB improve the check for buffer overruns BB */
6337 name_len
= strnlen(fileName
, PATH_MAX
);
6338 name_len
++; /* trailing null */
6339 strncpy(pSMB
->FileName
, fileName
, name_len
);
6342 params
= 6 + name_len
;
6344 /* done calculating parms using name_len of file name,
6345 now use name_len to calculate length of ea name
6346 we are going to create in the inode xattrs */
6347 if (ea_name
== NULL
)
6350 name_len
= strnlen(ea_name
, 255);
6352 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
;
6353 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6354 /* BB find max SMB PDU from sess */
6355 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6356 pSMB
->MaxSetupCount
= 0;
6360 pSMB
->Reserved2
= 0;
6361 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6362 InformationLevel
) - 4;
6363 offset
= param_offset
+ params
;
6364 pSMB
->InformationLevel
=
6365 cpu_to_le16(SMB_SET_FILE_EA
);
6367 parm_data
= (void *)pSMB
+ offsetof(struct smb_hdr
, Protocol
) + offset
;
6368 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6369 pSMB
->DataOffset
= cpu_to_le16(offset
);
6370 pSMB
->SetupCount
= 1;
6371 pSMB
->Reserved3
= 0;
6372 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6373 byte_count
= 3 /* pad */ + params
+ count
;
6374 pSMB
->DataCount
= cpu_to_le16(count
);
6375 parm_data
->list_len
= cpu_to_le32(count
);
6376 parm_data
->list
[0].EA_flags
= 0;
6377 /* we checked above that name len is less than 255 */
6378 parm_data
->list
[0].name_len
= (__u8
)name_len
;
6379 /* EA names are always ASCII */
6381 strncpy(parm_data
->list
[0].name
, ea_name
, name_len
);
6382 parm_data
->list
[0].name
[name_len
] = 0;
6383 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
6384 /* caller ensures that ea_value_len is less than 64K but
6385 we need to ensure that it fits within the smb */
6387 /*BB add length check to see if it would fit in
6388 negotiated SMB buffer size BB */
6389 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6391 memcpy(parm_data
->list
[0].name
+name_len
+1,
6392 ea_value
, ea_value_len
);
6394 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6395 pSMB
->ParameterCount
= cpu_to_le16(params
);
6396 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6397 pSMB
->Reserved4
= 0;
6398 inc_rfc1001_len(pSMB
, byte_count
);
6399 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6400 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6401 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6403 cifs_dbg(FYI
, "SetPathInfo (EA) returned %d\n", rc
);
6405 cifs_buf_release(pSMB
);
6414 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6416 * Years ago the kernel added a "dnotify" function for Samba server,
6417 * to allow network clients (such as Windows) to display updated
6418 * lists of files in directory listings automatically when
6419 * files are added by one user when another user has the
6420 * same directory open on their desktop. The Linux cifs kernel
6421 * client hooked into the kernel side of this interface for
6422 * the same reason, but ironically when the VFS moved from
6423 * "dnotify" to "inotify" it became harder to plug in Linux
6424 * network file system clients (the most obvious use case
6425 * for notify interfaces is when multiple users can update
6426 * the contents of the same directory - exactly what network
6427 * file systems can do) although the server (Samba) could
6428 * still use it. For the short term we leave the worker
6429 * function ifdeffed out (below) until inotify is fixed
6430 * in the VFS to make it easier to plug in network file
6431 * system clients. If inotify turns out to be permanently
6432 * incompatible for network fs clients, we could instead simply
6433 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6435 int CIFSSMBNotify(const unsigned int xid
, struct cifs_tcon
*tcon
,
6436 const int notify_subdirs
, const __u16 netfid
,
6437 __u32 filter
, struct file
*pfile
, int multishot
,
6438 const struct nls_table
*nls_codepage
)
6441 struct smb_com_transaction_change_notify_req
*pSMB
= NULL
;
6442 struct smb_com_ntransaction_change_notify_rsp
*pSMBr
= NULL
;
6443 struct dir_notify_req
*dnotify_req
;
6446 cifs_dbg(FYI
, "In CIFSSMBNotify for file handle %d\n", (int)netfid
);
6447 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
6452 pSMB
->TotalParameterCount
= 0 ;
6453 pSMB
->TotalDataCount
= 0;
6454 pSMB
->MaxParameterCount
= cpu_to_le32(2);
6455 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
6456 pSMB
->MaxSetupCount
= 4;
6458 pSMB
->ParameterOffset
= 0;
6459 pSMB
->DataCount
= 0;
6460 pSMB
->DataOffset
= 0;
6461 pSMB
->SetupCount
= 4; /* single byte does not need le conversion */
6462 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE
);
6463 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6465 pSMB
->WatchTree
= 1; /* one byte - no le conversion needed */
6466 pSMB
->Reserved2
= 0;
6467 pSMB
->CompletionFilter
= cpu_to_le32(filter
);
6468 pSMB
->Fid
= netfid
; /* file handle always le */
6469 pSMB
->ByteCount
= 0;
6471 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6472 (struct smb_hdr
*)pSMBr
, &bytes_returned
,
6475 cifs_dbg(FYI
, "Error in Notify = %d\n", rc
);
6477 /* Add file to outstanding requests */
6478 /* BB change to kmem cache alloc */
6479 dnotify_req
= kmalloc(
6480 sizeof(struct dir_notify_req
),
6483 dnotify_req
->Pid
= pSMB
->hdr
.Pid
;
6484 dnotify_req
->PidHigh
= pSMB
->hdr
.PidHigh
;
6485 dnotify_req
->Mid
= pSMB
->hdr
.Mid
;
6486 dnotify_req
->Tid
= pSMB
->hdr
.Tid
;
6487 dnotify_req
->Uid
= pSMB
->hdr
.Uid
;
6488 dnotify_req
->netfid
= netfid
;
6489 dnotify_req
->pfile
= pfile
;
6490 dnotify_req
->filter
= filter
;
6491 dnotify_req
->multishot
= multishot
;
6492 spin_lock(&GlobalMid_Lock
);
6493 list_add_tail(&dnotify_req
->lhead
,
6494 &GlobalDnotifyReqList
);
6495 spin_unlock(&GlobalMid_Lock
);
6499 cifs_buf_release(pSMB
);
6502 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */