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"
46 #include "smbdirect.h"
48 #ifdef CONFIG_CIFS_POSIX
53 #ifdef CONFIG_CIFS_WEAK_PW_HASH
54 {LANMAN_PROT
, "\2LM1.2X002"},
55 {LANMAN2_PROT
, "\2LANMAN2.1"},
56 #endif /* weak password hashing for legacy clients */
57 {CIFS_PROT
, "\2NT LM 0.12"},
58 {POSIX_PROT
, "\2POSIX 2"},
66 #ifdef CONFIG_CIFS_WEAK_PW_HASH
67 {LANMAN_PROT
, "\2LM1.2X002"},
68 {LANMAN2_PROT
, "\2LANMAN2.1"},
69 #endif /* weak password hashing for legacy clients */
70 {CIFS_PROT
, "\2NT LM 0.12"},
75 /* define the number of elements in the cifs dialect array */
76 #ifdef CONFIG_CIFS_POSIX
77 #ifdef CONFIG_CIFS_WEAK_PW_HASH
78 #define CIFS_NUM_PROT 4
80 #define CIFS_NUM_PROT 2
81 #endif /* CIFS_WEAK_PW_HASH */
83 #ifdef CONFIG_CIFS_WEAK_PW_HASH
84 #define CIFS_NUM_PROT 3
86 #define CIFS_NUM_PROT 1
87 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
88 #endif /* CIFS_POSIX */
91 * Mark as invalid, all open files on tree connections since they
92 * were closed when session to server was lost.
95 cifs_mark_open_files_invalid(struct cifs_tcon
*tcon
)
97 struct cifsFileInfo
*open_file
= NULL
;
98 struct list_head
*tmp
;
99 struct list_head
*tmp1
;
101 /* list all files open on tree connection and mark them invalid */
102 spin_lock(&tcon
->open_file_lock
);
103 list_for_each_safe(tmp
, tmp1
, &tcon
->openFileList
) {
104 open_file
= list_entry(tmp
, struct cifsFileInfo
, tlist
);
105 open_file
->invalidHandle
= true;
106 open_file
->oplock_break_cancelled
= true;
108 spin_unlock(&tcon
->open_file_lock
);
110 mutex_lock(&tcon
->prfid_mutex
);
111 tcon
->valid_root_fid
= false;
112 memset(tcon
->prfid
, 0, sizeof(struct cifs_fid
));
113 mutex_unlock(&tcon
->prfid_mutex
);
116 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
121 /* reconnect the socket, tcon, and smb session if needed */
123 cifs_reconnect_tcon(struct cifs_tcon
*tcon
, int smb_command
)
126 struct cifs_ses
*ses
;
127 struct TCP_Server_Info
*server
;
128 struct nls_table
*nls_codepage
;
131 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
132 * tcp and smb session status done differently for those three - in the
139 server
= ses
->server
;
142 * only tree disconnect, open, and write, (and ulogoff which does not
143 * have tcon) are allowed as we start force umount
145 if (tcon
->tidStatus
== CifsExiting
) {
146 if (smb_command
!= SMB_COM_WRITE_ANDX
&&
147 smb_command
!= SMB_COM_OPEN_ANDX
&&
148 smb_command
!= SMB_COM_TREE_DISCONNECT
) {
149 cifs_dbg(FYI
, "can not send cmd %d while umounting\n",
156 * Give demultiplex thread up to 10 seconds to reconnect, should be
157 * greater than cifs socket timeout which is 7 seconds
159 while (server
->tcpStatus
== CifsNeedReconnect
) {
160 wait_event_interruptible_timeout(server
->response_q
,
161 (server
->tcpStatus
!= CifsNeedReconnect
), 10 * HZ
);
163 /* are we still trying to reconnect? */
164 if (server
->tcpStatus
!= CifsNeedReconnect
)
168 * on "soft" mounts we wait once. Hard mounts keep
169 * retrying until process is killed or server comes
173 cifs_dbg(FYI
, "gave up waiting on reconnect in smb_init\n");
178 if (!ses
->need_reconnect
&& !tcon
->need_reconnect
)
181 nls_codepage
= load_nls_default();
184 * need to prevent multiple threads trying to simultaneously
185 * reconnect the same SMB session
187 mutex_lock(&ses
->session_mutex
);
190 * Recheck after acquire mutex. If another thread is negotiating
191 * and the server never sends an answer the socket will be closed
192 * and tcpStatus set to reconnect.
194 if (server
->tcpStatus
== CifsNeedReconnect
) {
196 mutex_unlock(&ses
->session_mutex
);
200 rc
= cifs_negotiate_protocol(0, ses
);
201 if (rc
== 0 && ses
->need_reconnect
)
202 rc
= cifs_setup_session(0, ses
, nls_codepage
);
204 /* do we need to reconnect tcon? */
205 if (rc
|| !tcon
->need_reconnect
) {
206 mutex_unlock(&ses
->session_mutex
);
210 cifs_mark_open_files_invalid(tcon
);
211 rc
= CIFSTCon(0, ses
, tcon
->treeName
, tcon
, nls_codepage
);
212 mutex_unlock(&ses
->session_mutex
);
213 cifs_dbg(FYI
, "reconnect tcon rc = %d\n", rc
);
216 printk_once(KERN_WARNING
"reconnect tcon failed rc = %d\n", rc
);
220 atomic_inc(&tconInfoReconnectCount
);
222 /* tell server Unix caps we support */
223 if (ses
->capabilities
& CAP_UNIX
)
224 reset_cifs_unix_caps(0, tcon
, NULL
, NULL
);
227 * Removed call to reopen open files here. It is safer (and faster) to
228 * reopen files one at a time as needed in read and write.
230 * FIXME: what about file locks? don't we need to reclaim them ASAP?
235 * Check if handle based operation so we know whether we can continue
236 * or not without returning to caller to reset file handle
238 switch (smb_command
) {
239 case SMB_COM_READ_ANDX
:
240 case SMB_COM_WRITE_ANDX
:
242 case SMB_COM_FIND_CLOSE2
:
243 case SMB_COM_LOCKING_ANDX
:
247 unload_nls(nls_codepage
);
251 /* Allocate and return pointer to an SMB request buffer, and set basic
252 SMB information in the SMB header. If the return code is zero, this
253 function must have filled in request_buf pointer */
255 small_smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
260 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
264 *request_buf
= cifs_small_buf_get();
265 if (*request_buf
== NULL
) {
266 /* BB should we add a retry in here if not a writepage? */
270 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
,
274 cifs_stats_inc(&tcon
->num_smbs_sent
);
280 small_smb_init_no_tc(const int smb_command
, const int wct
,
281 struct cifs_ses
*ses
, void **request_buf
)
284 struct smb_hdr
*buffer
;
286 rc
= small_smb_init(smb_command
, wct
, NULL
, request_buf
);
290 buffer
= (struct smb_hdr
*)*request_buf
;
291 buffer
->Mid
= get_next_mid(ses
->server
);
292 if (ses
->capabilities
& CAP_UNICODE
)
293 buffer
->Flags2
|= SMBFLG2_UNICODE
;
294 if (ses
->capabilities
& CAP_STATUS32
)
295 buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
297 /* uid, tid can stay at zero as set in header assemble */
299 /* BB add support for turning on the signing when
300 this function is used after 1st of session setup requests */
305 /* If the return code is zero, this function must fill in request_buf pointer */
307 __smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
308 void **request_buf
, void **response_buf
)
310 *request_buf
= cifs_buf_get();
311 if (*request_buf
== NULL
) {
312 /* BB should we add a retry in here if not a writepage? */
315 /* Although the original thought was we needed the response buf for */
316 /* potential retries of smb operations it turns out we can determine */
317 /* from the mid flags when the request buffer can be resent without */
318 /* having to use a second distinct buffer for the response */
320 *response_buf
= *request_buf
;
322 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
, tcon
,
326 cifs_stats_inc(&tcon
->num_smbs_sent
);
331 /* If the return code is zero, this function must fill in request_buf pointer */
333 smb_init(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
334 void **request_buf
, void **response_buf
)
338 rc
= cifs_reconnect_tcon(tcon
, smb_command
);
342 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
346 smb_init_no_reconnect(int smb_command
, int wct
, struct cifs_tcon
*tcon
,
347 void **request_buf
, void **response_buf
)
349 if (tcon
->ses
->need_reconnect
|| tcon
->need_reconnect
)
352 return __smb_init(smb_command
, wct
, tcon
, request_buf
, response_buf
);
355 static int validate_t2(struct smb_t2_rsp
*pSMB
)
357 unsigned int total_size
;
359 /* check for plausible wct */
360 if (pSMB
->hdr
.WordCount
< 10)
363 /* check for parm and data offset going beyond end of smb */
364 if (get_unaligned_le16(&pSMB
->t2_rsp
.ParameterOffset
) > 1024 ||
365 get_unaligned_le16(&pSMB
->t2_rsp
.DataOffset
) > 1024)
368 total_size
= get_unaligned_le16(&pSMB
->t2_rsp
.ParameterCount
);
369 if (total_size
>= 512)
372 /* check that bcc is at least as big as parms + data, and that it is
373 * less than negotiated smb buffer
375 total_size
+= get_unaligned_le16(&pSMB
->t2_rsp
.DataCount
);
376 if (total_size
> get_bcc(&pSMB
->hdr
) ||
377 total_size
>= CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
)
382 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB
,
383 sizeof(struct smb_t2_rsp
) + 16);
388 decode_ext_sec_blob(struct cifs_ses
*ses
, NEGOTIATE_RSP
*pSMBr
)
392 char *guid
= pSMBr
->u
.extended_response
.GUID
;
393 struct TCP_Server_Info
*server
= ses
->server
;
395 count
= get_bcc(&pSMBr
->hdr
);
396 if (count
< SMB1_CLIENT_GUID_SIZE
)
399 spin_lock(&cifs_tcp_ses_lock
);
400 if (server
->srv_count
> 1) {
401 spin_unlock(&cifs_tcp_ses_lock
);
402 if (memcmp(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
) != 0) {
403 cifs_dbg(FYI
, "server UID changed\n");
404 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
407 spin_unlock(&cifs_tcp_ses_lock
);
408 memcpy(server
->server_GUID
, guid
, SMB1_CLIENT_GUID_SIZE
);
411 if (count
== SMB1_CLIENT_GUID_SIZE
) {
412 server
->sec_ntlmssp
= true;
414 count
-= SMB1_CLIENT_GUID_SIZE
;
415 rc
= decode_negTokenInit(
416 pSMBr
->u
.extended_response
.SecurityBlob
, count
, server
);
425 cifs_enable_signing(struct TCP_Server_Info
*server
, bool mnt_sign_required
)
427 bool srv_sign_required
= server
->sec_mode
& server
->vals
->signing_required
;
428 bool srv_sign_enabled
= server
->sec_mode
& server
->vals
->signing_enabled
;
429 bool mnt_sign_enabled
= global_secflags
& CIFSSEC_MAY_SIGN
;
432 * Is signing required by mnt options? If not then check
433 * global_secflags to see if it is there.
435 if (!mnt_sign_required
)
436 mnt_sign_required
= ((global_secflags
& CIFSSEC_MUST_SIGN
) ==
440 * If signing is required then it's automatically enabled too,
441 * otherwise, check to see if the secflags allow it.
443 mnt_sign_enabled
= mnt_sign_required
? mnt_sign_required
:
444 (global_secflags
& CIFSSEC_MAY_SIGN
);
446 /* If server requires signing, does client allow it? */
447 if (srv_sign_required
) {
448 if (!mnt_sign_enabled
) {
449 cifs_dbg(VFS
, "Server requires signing, but it's disabled in SecurityFlags!");
455 /* If client requires signing, does server allow it? */
456 if (mnt_sign_required
) {
457 if (!srv_sign_enabled
) {
458 cifs_dbg(VFS
, "Server does not support signing!");
464 if (cifs_rdma_enabled(server
) && server
->sign
)
465 cifs_dbg(VFS
, "Signing is enabled, and RDMA read/write will be disabled");
470 #ifdef CONFIG_CIFS_WEAK_PW_HASH
472 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
475 struct lanman_neg_rsp
*rsp
= (struct lanman_neg_rsp
*)pSMBr
;
477 if (server
->dialect
!= LANMAN_PROT
&& server
->dialect
!= LANMAN2_PROT
)
480 server
->sec_mode
= le16_to_cpu(rsp
->SecurityMode
);
481 server
->maxReq
= min_t(unsigned int,
482 le16_to_cpu(rsp
->MaxMpxCount
),
484 set_credits(server
, server
->maxReq
);
485 server
->maxBuf
= le16_to_cpu(rsp
->MaxBufSize
);
486 /* even though we do not use raw we might as well set this
487 accurately, in case we ever find a need for it */
488 if ((le16_to_cpu(rsp
->RawMode
) & RAW_ENABLE
) == RAW_ENABLE
) {
489 server
->max_rw
= 0xFF00;
490 server
->capabilities
= CAP_MPX_MODE
| CAP_RAW_MODE
;
492 server
->max_rw
= 0;/* do not need to use raw anyway */
493 server
->capabilities
= CAP_MPX_MODE
;
495 tmp
= (__s16
)le16_to_cpu(rsp
->ServerTimeZone
);
497 /* OS/2 often does not set timezone therefore
498 * we must use server time to calc time zone.
499 * Could deviate slightly from the right zone.
500 * Smallest defined timezone difference is 15 minutes
501 * (i.e. Nepal). Rounding up/down is done to match
504 int val
, seconds
, remain
, result
;
506 unsigned long utc
= ktime_get_real_seconds();
507 ts
= cnvrtDosUnixTm(rsp
->SrvTime
.Date
,
508 rsp
->SrvTime
.Time
, 0);
509 cifs_dbg(FYI
, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
510 (int)ts
.tv_sec
, (int)utc
,
511 (int)(utc
- ts
.tv_sec
));
512 val
= (int)(utc
- ts
.tv_sec
);
514 result
= (seconds
/ MIN_TZ_ADJ
) * MIN_TZ_ADJ
;
515 remain
= seconds
% MIN_TZ_ADJ
;
516 if (remain
>= (MIN_TZ_ADJ
/ 2))
517 result
+= MIN_TZ_ADJ
;
520 server
->timeAdj
= result
;
522 server
->timeAdj
= (int)tmp
;
523 server
->timeAdj
*= 60; /* also in seconds */
525 cifs_dbg(FYI
, "server->timeAdj: %d seconds\n", server
->timeAdj
);
528 /* BB get server time for time conversions and add
529 code to use it and timezone since this is not UTC */
531 if (rsp
->EncryptionKeyLength
==
532 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE
)) {
533 memcpy(server
->cryptkey
, rsp
->EncryptionKey
,
534 CIFS_CRYPTO_KEY_SIZE
);
535 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
536 return -EIO
; /* need cryptkey unless plain text */
539 cifs_dbg(FYI
, "LANMAN negotiated\n");
544 decode_lanman_negprot_rsp(struct TCP_Server_Info
*server
, NEGOTIATE_RSP
*pSMBr
)
546 cifs_dbg(VFS
, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
552 should_set_ext_sec_flag(enum securityEnum sectype
)
559 if (global_secflags
&
560 (CIFSSEC_MAY_KRB5
| CIFSSEC_MAY_NTLMSSP
))
569 CIFSSMBNegotiate(const unsigned int xid
, struct cifs_ses
*ses
)
572 NEGOTIATE_RSP
*pSMBr
;
576 struct TCP_Server_Info
*server
= ses
->server
;
580 WARN(1, "%s: server is NULL!\n", __func__
);
584 rc
= smb_init(SMB_COM_NEGOTIATE
, 0, NULL
/* no tcon yet */ ,
585 (void **) &pSMB
, (void **) &pSMBr
);
589 pSMB
->hdr
.Mid
= get_next_mid(server
);
590 pSMB
->hdr
.Flags2
|= (SMBFLG2_UNICODE
| SMBFLG2_ERR_STATUS
);
592 if (should_set_ext_sec_flag(ses
->sectype
)) {
593 cifs_dbg(FYI
, "Requesting extended security.");
594 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
598 for (i
= 0; i
< CIFS_NUM_PROT
; i
++) {
599 strncpy(pSMB
->DialectsArray
+count
, protocols
[i
].name
, 16);
600 count
+= strlen(protocols
[i
].name
) + 1;
601 /* null at end of source and target buffers anyway */
603 inc_rfc1001_len(pSMB
, count
);
604 pSMB
->ByteCount
= cpu_to_le16(count
);
606 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
607 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
611 server
->dialect
= le16_to_cpu(pSMBr
->DialectIndex
);
612 cifs_dbg(FYI
, "Dialect: %d\n", server
->dialect
);
613 /* Check wct = 1 error case */
614 if ((pSMBr
->hdr
.WordCount
< 13) || (server
->dialect
== BAD_PROT
)) {
615 /* core returns wct = 1, but we do not ask for core - otherwise
616 small wct just comes when dialect index is -1 indicating we
617 could not negotiate a common dialect */
620 } else if (pSMBr
->hdr
.WordCount
== 13) {
621 server
->negflavor
= CIFS_NEGFLAVOR_LANMAN
;
622 rc
= decode_lanman_negprot_rsp(server
, pSMBr
);
624 } else if (pSMBr
->hdr
.WordCount
!= 17) {
629 /* else wct == 17, NTLM or better */
631 server
->sec_mode
= pSMBr
->SecurityMode
;
632 if ((server
->sec_mode
& SECMODE_USER
) == 0)
633 cifs_dbg(FYI
, "share mode security\n");
635 /* one byte, so no need to convert this or EncryptionKeyLen from
637 server
->maxReq
= min_t(unsigned int, le16_to_cpu(pSMBr
->MaxMpxCount
),
639 set_credits(server
, server
->maxReq
);
640 /* probably no need to store and check maxvcs */
641 server
->maxBuf
= le32_to_cpu(pSMBr
->MaxBufferSize
);
642 server
->max_rw
= le32_to_cpu(pSMBr
->MaxRawSize
);
643 cifs_dbg(NOISY
, "Max buf = %d\n", ses
->server
->maxBuf
);
644 server
->capabilities
= le32_to_cpu(pSMBr
->Capabilities
);
645 server
->timeAdj
= (int)(__s16
)le16_to_cpu(pSMBr
->ServerTimeZone
);
646 server
->timeAdj
*= 60;
648 if (pSMBr
->EncryptionKeyLength
== CIFS_CRYPTO_KEY_SIZE
) {
649 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
650 memcpy(ses
->server
->cryptkey
, pSMBr
->u
.EncryptionKey
,
651 CIFS_CRYPTO_KEY_SIZE
);
652 } else if (pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
||
653 server
->capabilities
& CAP_EXTENDED_SECURITY
) {
654 server
->negflavor
= CIFS_NEGFLAVOR_EXTENDED
;
655 rc
= decode_ext_sec_blob(ses
, pSMBr
);
656 } else if (server
->sec_mode
& SECMODE_PW_ENCRYPT
) {
657 rc
= -EIO
; /* no crypt key only if plain text pwd */
659 server
->negflavor
= CIFS_NEGFLAVOR_UNENCAP
;
660 server
->capabilities
&= ~CAP_EXTENDED_SECURITY
;
665 rc
= cifs_enable_signing(server
, ses
->sign
);
667 cifs_buf_release(pSMB
);
669 cifs_dbg(FYI
, "negprot rc %d\n", rc
);
674 CIFSSMBTDis(const unsigned int xid
, struct cifs_tcon
*tcon
)
676 struct smb_hdr
*smb_buffer
;
679 cifs_dbg(FYI
, "In tree disconnect\n");
681 /* BB: do we need to check this? These should never be NULL. */
682 if ((tcon
->ses
== NULL
) || (tcon
->ses
->server
== NULL
))
686 * No need to return error on this operation if tid invalidated and
687 * closed on server already e.g. due to tcp session crashing. Also,
688 * the tcon is no longer on the list, so no need to take lock before
691 if ((tcon
->need_reconnect
) || (tcon
->ses
->need_reconnect
))
694 rc
= small_smb_init(SMB_COM_TREE_DISCONNECT
, 0, tcon
,
695 (void **)&smb_buffer
);
699 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)smb_buffer
, 0);
700 cifs_small_buf_release(smb_buffer
);
702 cifs_dbg(FYI
, "Tree disconnect failed %d\n", rc
);
704 /* No need to return error on this operation if tid invalidated and
705 closed on server already e.g. due to tcp session crashing */
713 * This is a no-op for now. We're not really interested in the reply, but
714 * rather in the fact that the server sent one and that server->lstrp
717 * FIXME: maybe we should consider checking that the reply matches request?
720 cifs_echo_callback(struct mid_q_entry
*mid
)
722 struct TCP_Server_Info
*server
= mid
->callback_data
;
724 DeleteMidQEntry(mid
);
725 add_credits(server
, 1, CIFS_ECHO_OP
);
729 CIFSSMBEcho(struct TCP_Server_Info
*server
)
734 struct smb_rqst rqst
= { .rq_iov
= iov
,
737 cifs_dbg(FYI
, "In echo request\n");
739 rc
= small_smb_init(SMB_COM_ECHO
, 0, NULL
, (void **)&smb
);
743 if (server
->capabilities
& CAP_UNICODE
)
744 smb
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
746 /* set up echo request */
747 smb
->hdr
.Tid
= 0xffff;
748 smb
->hdr
.WordCount
= 1;
749 put_unaligned_le16(1, &smb
->EchoCount
);
750 put_bcc(1, &smb
->hdr
);
752 inc_rfc1001_len(smb
, 3);
755 iov
[0].iov_base
= smb
;
756 iov
[1].iov_len
= get_rfc1002_length(smb
);
757 iov
[1].iov_base
= (char *)smb
+ 4;
759 rc
= cifs_call_async(server
, &rqst
, NULL
, cifs_echo_callback
, NULL
,
760 server
, CIFS_ASYNC_OP
| CIFS_ECHO_OP
);
762 cifs_dbg(FYI
, "Echo request failed: %d\n", rc
);
764 cifs_small_buf_release(smb
);
770 CIFSSMBLogoff(const unsigned int xid
, struct cifs_ses
*ses
)
772 LOGOFF_ANDX_REQ
*pSMB
;
775 cifs_dbg(FYI
, "In SMBLogoff for session disconnect\n");
778 * BB: do we need to check validity of ses and server? They should
779 * always be valid since we have an active reference. If not, that
780 * should probably be a BUG()
782 if (!ses
|| !ses
->server
)
785 mutex_lock(&ses
->session_mutex
);
786 if (ses
->need_reconnect
)
787 goto session_already_dead
; /* no need to send SMBlogoff if uid
788 already closed due to reconnect */
789 rc
= small_smb_init(SMB_COM_LOGOFF_ANDX
, 2, NULL
, (void **)&pSMB
);
791 mutex_unlock(&ses
->session_mutex
);
795 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
797 if (ses
->server
->sign
)
798 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
800 pSMB
->hdr
.Uid
= ses
->Suid
;
802 pSMB
->AndXCommand
= 0xFF;
803 rc
= SendReceiveNoRsp(xid
, ses
, (char *) pSMB
, 0);
804 cifs_small_buf_release(pSMB
);
805 session_already_dead
:
806 mutex_unlock(&ses
->session_mutex
);
808 /* if session dead then we do not need to do ulogoff,
809 since server closed smb session, no sense reporting
817 CIFSPOSIXDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
,
818 const char *fileName
, __u16 type
,
819 const struct nls_table
*nls_codepage
, int remap
)
821 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
822 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
823 struct unlink_psx_rq
*pRqD
;
826 int bytes_returned
= 0;
827 __u16 params
, param_offset
, offset
, byte_count
;
829 cifs_dbg(FYI
, "In POSIX delete\n");
831 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
836 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
838 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
839 PATH_MAX
, nls_codepage
, remap
);
840 name_len
++; /* trailing null */
842 } else { /* BB add path length overrun check */
843 name_len
= strnlen(fileName
, PATH_MAX
);
844 name_len
++; /* trailing null */
845 strncpy(pSMB
->FileName
, fileName
, name_len
);
848 params
= 6 + name_len
;
849 pSMB
->MaxParameterCount
= cpu_to_le16(2);
850 pSMB
->MaxDataCount
= 0; /* BB double check this with jra */
851 pSMB
->MaxSetupCount
= 0;
856 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
857 InformationLevel
) - 4;
858 offset
= param_offset
+ params
;
860 /* Setup pointer to Request Data (inode type) */
861 pRqD
= (struct unlink_psx_rq
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
862 pRqD
->type
= cpu_to_le16(type
);
863 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
864 pSMB
->DataOffset
= cpu_to_le16(offset
);
865 pSMB
->SetupCount
= 1;
867 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
868 byte_count
= 3 /* pad */ + params
+ sizeof(struct unlink_psx_rq
);
870 pSMB
->DataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
871 pSMB
->TotalDataCount
= cpu_to_le16(sizeof(struct unlink_psx_rq
));
872 pSMB
->ParameterCount
= cpu_to_le16(params
);
873 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
874 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_UNLINK
);
876 inc_rfc1001_len(pSMB
, byte_count
);
877 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
878 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
879 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
881 cifs_dbg(FYI
, "Posix delete returned %d\n", rc
);
882 cifs_buf_release(pSMB
);
884 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
893 CIFSSMBDelFile(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
894 struct cifs_sb_info
*cifs_sb
)
896 DELETE_FILE_REQ
*pSMB
= NULL
;
897 DELETE_FILE_RSP
*pSMBr
= NULL
;
901 int remap
= cifs_remap(cifs_sb
);
904 rc
= smb_init(SMB_COM_DELETE
, 1, tcon
, (void **) &pSMB
,
909 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
910 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->fileName
, name
,
911 PATH_MAX
, cifs_sb
->local_nls
,
913 name_len
++; /* trailing null */
915 } else { /* BB improve check for buffer overruns BB */
916 name_len
= strnlen(name
, PATH_MAX
);
917 name_len
++; /* trailing null */
918 strncpy(pSMB
->fileName
, name
, name_len
);
920 pSMB
->SearchAttributes
=
921 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
);
922 pSMB
->BufferFormat
= 0x04;
923 inc_rfc1001_len(pSMB
, name_len
+ 1);
924 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
925 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
926 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
927 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_deletes
);
929 cifs_dbg(FYI
, "Error in RMFile = %d\n", rc
);
931 cifs_buf_release(pSMB
);
939 CIFSSMBRmDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
940 struct cifs_sb_info
*cifs_sb
)
942 DELETE_DIRECTORY_REQ
*pSMB
= NULL
;
943 DELETE_DIRECTORY_RSP
*pSMBr
= NULL
;
947 int remap
= cifs_remap(cifs_sb
);
949 cifs_dbg(FYI
, "In CIFSSMBRmDir\n");
951 rc
= smb_init(SMB_COM_DELETE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
956 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
957 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
958 PATH_MAX
, cifs_sb
->local_nls
,
960 name_len
++; /* trailing null */
962 } else { /* BB improve check for buffer overruns BB */
963 name_len
= strnlen(name
, PATH_MAX
);
964 name_len
++; /* trailing null */
965 strncpy(pSMB
->DirName
, name
, name_len
);
968 pSMB
->BufferFormat
= 0x04;
969 inc_rfc1001_len(pSMB
, name_len
+ 1);
970 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
971 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
972 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
973 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_rmdirs
);
975 cifs_dbg(FYI
, "Error in RMDir = %d\n", rc
);
977 cifs_buf_release(pSMB
);
984 CIFSSMBMkDir(const unsigned int xid
, struct cifs_tcon
*tcon
, const char *name
,
985 struct cifs_sb_info
*cifs_sb
)
988 CREATE_DIRECTORY_REQ
*pSMB
= NULL
;
989 CREATE_DIRECTORY_RSP
*pSMBr
= NULL
;
992 int remap
= cifs_remap(cifs_sb
);
994 cifs_dbg(FYI
, "In CIFSSMBMkDir\n");
996 rc
= smb_init(SMB_COM_CREATE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
1001 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1002 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->DirName
, name
,
1003 PATH_MAX
, cifs_sb
->local_nls
,
1005 name_len
++; /* trailing null */
1007 } else { /* BB improve check for buffer overruns BB */
1008 name_len
= strnlen(name
, PATH_MAX
);
1009 name_len
++; /* trailing null */
1010 strncpy(pSMB
->DirName
, name
, name_len
);
1013 pSMB
->BufferFormat
= 0x04;
1014 inc_rfc1001_len(pSMB
, name_len
+ 1);
1015 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
1016 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1017 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1018 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_mkdirs
);
1020 cifs_dbg(FYI
, "Error in Mkdir = %d\n", rc
);
1022 cifs_buf_release(pSMB
);
1029 CIFSPOSIXCreate(const unsigned int xid
, struct cifs_tcon
*tcon
,
1030 __u32 posix_flags
, __u64 mode
, __u16
*netfid
,
1031 FILE_UNIX_BASIC_INFO
*pRetData
, __u32
*pOplock
,
1032 const char *name
, const struct nls_table
*nls_codepage
,
1035 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
1036 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
1039 int bytes_returned
= 0;
1040 __u16 params
, param_offset
, offset
, byte_count
, count
;
1041 OPEN_PSX_REQ
*pdata
;
1042 OPEN_PSX_RSP
*psx_rsp
;
1044 cifs_dbg(FYI
, "In POSIX Create\n");
1046 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1051 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1053 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, name
,
1054 PATH_MAX
, nls_codepage
, remap
);
1055 name_len
++; /* trailing null */
1057 } else { /* BB improve the check for buffer overruns BB */
1058 name_len
= strnlen(name
, PATH_MAX
);
1059 name_len
++; /* trailing null */
1060 strncpy(pSMB
->FileName
, name
, name_len
);
1063 params
= 6 + name_len
;
1064 count
= sizeof(OPEN_PSX_REQ
);
1065 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1066 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* large enough */
1067 pSMB
->MaxSetupCount
= 0;
1071 pSMB
->Reserved2
= 0;
1072 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
1073 InformationLevel
) - 4;
1074 offset
= param_offset
+ params
;
1075 pdata
= (OPEN_PSX_REQ
*)(((char *)&pSMB
->hdr
.Protocol
) + offset
);
1076 pdata
->Level
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
1077 pdata
->Permissions
= cpu_to_le64(mode
);
1078 pdata
->PosixOpenFlags
= cpu_to_le32(posix_flags
);
1079 pdata
->OpenFlags
= cpu_to_le32(*pOplock
);
1080 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
1081 pSMB
->DataOffset
= cpu_to_le16(offset
);
1082 pSMB
->SetupCount
= 1;
1083 pSMB
->Reserved3
= 0;
1084 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
1085 byte_count
= 3 /* pad */ + params
+ count
;
1087 pSMB
->DataCount
= cpu_to_le16(count
);
1088 pSMB
->ParameterCount
= cpu_to_le16(params
);
1089 pSMB
->TotalDataCount
= pSMB
->DataCount
;
1090 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1091 pSMB
->InformationLevel
= cpu_to_le16(SMB_POSIX_OPEN
);
1092 pSMB
->Reserved4
= 0;
1093 inc_rfc1001_len(pSMB
, byte_count
);
1094 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1095 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1096 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1098 cifs_dbg(FYI
, "Posix create returned %d\n", rc
);
1099 goto psx_create_err
;
1102 cifs_dbg(FYI
, "copying inode info\n");
1103 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
1105 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)) {
1106 rc
= -EIO
; /* bad smb */
1107 goto psx_create_err
;
1110 /* copy return information to pRetData */
1111 psx_rsp
= (OPEN_PSX_RSP
*)((char *) &pSMBr
->hdr
.Protocol
1112 + le16_to_cpu(pSMBr
->t2
.DataOffset
));
1114 *pOplock
= le16_to_cpu(psx_rsp
->OplockFlags
);
1116 *netfid
= psx_rsp
->Fid
; /* cifs fid stays in le */
1117 /* Let caller know file was created so we can set the mode. */
1118 /* Do we care about the CreateAction in any other cases? */
1119 if (cpu_to_le32(FILE_CREATE
) == psx_rsp
->CreateAction
)
1120 *pOplock
|= CIFS_CREATE_ACTION
;
1121 /* check to make sure response data is there */
1122 if (psx_rsp
->ReturnedLevel
!= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
)) {
1123 pRetData
->Type
= cpu_to_le32(-1); /* unknown */
1124 cifs_dbg(NOISY
, "unknown type\n");
1126 if (get_bcc(&pSMBr
->hdr
) < sizeof(OPEN_PSX_RSP
)
1127 + sizeof(FILE_UNIX_BASIC_INFO
)) {
1128 cifs_dbg(VFS
, "Open response data too small\n");
1129 pRetData
->Type
= cpu_to_le32(-1);
1130 goto psx_create_err
;
1132 memcpy((char *) pRetData
,
1133 (char *)psx_rsp
+ sizeof(OPEN_PSX_RSP
),
1134 sizeof(FILE_UNIX_BASIC_INFO
));
1138 cifs_buf_release(pSMB
);
1140 if (posix_flags
& SMB_O_DIRECTORY
)
1141 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixmkdirs
);
1143 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_posixopens
);
1151 static __u16
convert_disposition(int disposition
)
1155 switch (disposition
) {
1156 case FILE_SUPERSEDE
:
1157 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1160 ofun
= SMBOPEN_OAPPEND
;
1163 ofun
= SMBOPEN_OCREATE
;
1166 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OAPPEND
;
1168 case FILE_OVERWRITE
:
1169 ofun
= SMBOPEN_OTRUNC
;
1171 case FILE_OVERWRITE_IF
:
1172 ofun
= SMBOPEN_OCREATE
| SMBOPEN_OTRUNC
;
1175 cifs_dbg(FYI
, "unknown disposition %d\n", disposition
);
1176 ofun
= SMBOPEN_OAPPEND
; /* regular open */
1182 access_flags_to_smbopen_mode(const int access_flags
)
1184 int masked_flags
= access_flags
& (GENERIC_READ
| GENERIC_WRITE
);
1186 if (masked_flags
== GENERIC_READ
)
1187 return SMBOPEN_READ
;
1188 else if (masked_flags
== GENERIC_WRITE
)
1189 return SMBOPEN_WRITE
;
1191 /* just go for read/write */
1192 return SMBOPEN_READWRITE
;
1196 SMBLegacyOpen(const unsigned int xid
, struct cifs_tcon
*tcon
,
1197 const char *fileName
, const int openDisposition
,
1198 const int access_flags
, const int create_options
, __u16
*netfid
,
1199 int *pOplock
, FILE_ALL_INFO
*pfile_info
,
1200 const struct nls_table
*nls_codepage
, int remap
)
1203 OPENX_REQ
*pSMB
= NULL
;
1204 OPENX_RSP
*pSMBr
= NULL
;
1210 rc
= smb_init(SMB_COM_OPEN_ANDX
, 15, tcon
, (void **) &pSMB
,
1215 pSMB
->AndXCommand
= 0xFF; /* none */
1217 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1218 count
= 1; /* account for one byte pad to word boundary */
1220 cifsConvertToUTF16((__le16
*) (pSMB
->fileName
+ 1),
1221 fileName
, PATH_MAX
, nls_codepage
, remap
);
1222 name_len
++; /* trailing null */
1224 } else { /* BB improve check for buffer overruns BB */
1225 count
= 0; /* no pad */
1226 name_len
= strnlen(fileName
, PATH_MAX
);
1227 name_len
++; /* trailing null */
1228 strncpy(pSMB
->fileName
, fileName
, name_len
);
1230 if (*pOplock
& REQ_OPLOCK
)
1231 pSMB
->OpenFlags
= cpu_to_le16(REQ_OPLOCK
);
1232 else if (*pOplock
& REQ_BATCHOPLOCK
)
1233 pSMB
->OpenFlags
= cpu_to_le16(REQ_BATCHOPLOCK
);
1235 pSMB
->OpenFlags
|= cpu_to_le16(REQ_MORE_INFO
);
1236 pSMB
->Mode
= cpu_to_le16(access_flags_to_smbopen_mode(access_flags
));
1237 pSMB
->Mode
|= cpu_to_le16(0x40); /* deny none */
1238 /* set file as system file if special file such
1239 as fifo and server expecting SFU style and
1240 no Unix extensions */
1242 if (create_options
& CREATE_OPTION_SPECIAL
)
1243 pSMB
->FileAttributes
= cpu_to_le16(ATTR_SYSTEM
);
1244 else /* BB FIXME BB */
1245 pSMB
->FileAttributes
= cpu_to_le16(0/*ATTR_NORMAL*/);
1247 if (create_options
& CREATE_OPTION_READONLY
)
1248 pSMB
->FileAttributes
|= cpu_to_le16(ATTR_READONLY
);
1251 /* pSMB->CreateOptions = cpu_to_le32(create_options &
1252 CREATE_OPTIONS_MASK); */
1253 /* BB FIXME END BB */
1255 pSMB
->Sattr
= cpu_to_le16(ATTR_HIDDEN
| ATTR_SYSTEM
| ATTR_DIRECTORY
);
1256 pSMB
->OpenFunction
= cpu_to_le16(convert_disposition(openDisposition
));
1258 inc_rfc1001_len(pSMB
, count
);
1260 pSMB
->ByteCount
= cpu_to_le16(count
);
1261 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1262 (struct smb_hdr
*)pSMBr
, &bytes_returned
, 0);
1263 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1265 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1267 /* BB verify if wct == 15 */
1269 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1271 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
1272 /* Let caller know file was created so we can set the mode. */
1273 /* Do we care about the CreateAction in any other cases? */
1275 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1276 *pOplock |= CIFS_CREATE_ACTION; */
1280 pfile_info
->CreationTime
= 0; /* BB convert CreateTime*/
1281 pfile_info
->LastAccessTime
= 0; /* BB fixme */
1282 pfile_info
->LastWriteTime
= 0; /* BB fixme */
1283 pfile_info
->ChangeTime
= 0; /* BB fixme */
1284 pfile_info
->Attributes
=
1285 cpu_to_le32(le16_to_cpu(pSMBr
->FileAttributes
));
1286 /* the file_info buf is endian converted by caller */
1287 pfile_info
->AllocationSize
=
1288 cpu_to_le64(le32_to_cpu(pSMBr
->EndOfFile
));
1289 pfile_info
->EndOfFile
= pfile_info
->AllocationSize
;
1290 pfile_info
->NumberOfLinks
= cpu_to_le32(1);
1291 pfile_info
->DeletePending
= 0;
1295 cifs_buf_release(pSMB
);
1302 CIFS_open(const unsigned int xid
, struct cifs_open_parms
*oparms
, int *oplock
,
1306 OPEN_REQ
*req
= NULL
;
1307 OPEN_RSP
*rsp
= NULL
;
1311 struct cifs_sb_info
*cifs_sb
= oparms
->cifs_sb
;
1312 struct cifs_tcon
*tcon
= oparms
->tcon
;
1313 int remap
= cifs_remap(cifs_sb
);
1314 const struct nls_table
*nls
= cifs_sb
->local_nls
;
1315 int create_options
= oparms
->create_options
;
1316 int desired_access
= oparms
->desired_access
;
1317 int disposition
= oparms
->disposition
;
1318 const char *path
= oparms
->path
;
1321 rc
= smb_init(SMB_COM_NT_CREATE_ANDX
, 24, tcon
, (void **)&req
,
1326 /* no commands go after this */
1327 req
->AndXCommand
= 0xFF;
1329 if (req
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1330 /* account for one byte pad to word boundary */
1332 name_len
= cifsConvertToUTF16((__le16
*)(req
->fileName
+ 1),
1333 path
, PATH_MAX
, nls
, remap
);
1337 req
->NameLength
= cpu_to_le16(name_len
);
1339 /* BB improve check for buffer overruns BB */
1342 name_len
= strnlen(path
, PATH_MAX
);
1345 req
->NameLength
= cpu_to_le16(name_len
);
1346 strncpy(req
->fileName
, path
, name_len
);
1349 if (*oplock
& REQ_OPLOCK
)
1350 req
->OpenFlags
= cpu_to_le32(REQ_OPLOCK
);
1351 else if (*oplock
& REQ_BATCHOPLOCK
)
1352 req
->OpenFlags
= cpu_to_le32(REQ_BATCHOPLOCK
);
1354 req
->DesiredAccess
= cpu_to_le32(desired_access
);
1355 req
->AllocationSize
= 0;
1358 * Set file as system file if special file such as fifo and server
1359 * expecting SFU style and no Unix extensions.
1361 if (create_options
& CREATE_OPTION_SPECIAL
)
1362 req
->FileAttributes
= cpu_to_le32(ATTR_SYSTEM
);
1364 req
->FileAttributes
= cpu_to_le32(ATTR_NORMAL
);
1367 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1368 * sensitive checks for other servers such as Samba.
1370 if (tcon
->ses
->capabilities
& CAP_UNIX
)
1371 req
->FileAttributes
|= cpu_to_le32(ATTR_POSIX_SEMANTICS
);
1373 if (create_options
& CREATE_OPTION_READONLY
)
1374 req
->FileAttributes
|= cpu_to_le32(ATTR_READONLY
);
1376 req
->ShareAccess
= cpu_to_le32(FILE_SHARE_ALL
);
1377 req
->CreateDisposition
= cpu_to_le32(disposition
);
1378 req
->CreateOptions
= cpu_to_le32(create_options
& CREATE_OPTIONS_MASK
);
1380 /* BB Expirement with various impersonation levels and verify */
1381 req
->ImpersonationLevel
= cpu_to_le32(SECURITY_IMPERSONATION
);
1382 req
->SecurityFlags
= SECURITY_CONTEXT_TRACKING
|SECURITY_EFFECTIVE_ONLY
;
1385 inc_rfc1001_len(req
, count
);
1387 req
->ByteCount
= cpu_to_le16(count
);
1388 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*)req
,
1389 (struct smb_hdr
*)rsp
, &bytes_returned
, 0);
1390 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_opens
);
1392 cifs_dbg(FYI
, "Error in Open = %d\n", rc
);
1393 cifs_buf_release(req
);
1399 /* 1 byte no need to le_to_cpu */
1400 *oplock
= rsp
->OplockLevel
;
1401 /* cifs fid stays in le */
1402 oparms
->fid
->netfid
= rsp
->Fid
;
1404 /* Let caller know file was created so we can set the mode. */
1405 /* Do we care about the CreateAction in any other cases? */
1406 if (cpu_to_le32(FILE_CREATE
) == rsp
->CreateAction
)
1407 *oplock
|= CIFS_CREATE_ACTION
;
1410 /* copy from CreationTime to Attributes */
1411 memcpy((char *)buf
, (char *)&rsp
->CreationTime
, 36);
1412 /* the file_info buf is endian converted by caller */
1413 buf
->AllocationSize
= rsp
->AllocationSize
;
1414 buf
->EndOfFile
= rsp
->EndOfFile
;
1415 buf
->NumberOfLinks
= cpu_to_le32(1);
1416 buf
->DeletePending
= 0;
1419 cifs_buf_release(req
);
1424 * Discard any remaining data in the current SMB. To do this, we borrow the
1428 cifs_discard_remaining_data(struct TCP_Server_Info
*server
)
1430 unsigned int rfclen
= server
->pdu_size
;
1431 int remaining
= rfclen
+ server
->vals
->header_preamble_size
-
1434 while (remaining
> 0) {
1437 length
= cifs_read_from_socket(server
, server
->bigbuf
,
1438 min_t(unsigned int, remaining
,
1439 CIFSMaxBufSize
+ MAX_HEADER_SIZE(server
)));
1442 server
->total_read
+= length
;
1443 remaining
-= length
;
1450 cifs_readv_discard(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1453 struct cifs_readdata
*rdata
= mid
->callback_data
;
1455 length
= cifs_discard_remaining_data(server
);
1456 dequeue_mid(mid
, rdata
->result
);
1457 mid
->resp_buf
= server
->smallbuf
;
1458 server
->smallbuf
= NULL
;
1463 cifs_readv_receive(struct TCP_Server_Info
*server
, struct mid_q_entry
*mid
)
1466 unsigned int data_offset
, data_len
;
1467 struct cifs_readdata
*rdata
= mid
->callback_data
;
1468 char *buf
= server
->smallbuf
;
1469 unsigned int buflen
= server
->pdu_size
+
1470 server
->vals
->header_preamble_size
;
1471 bool use_rdma_mr
= false;
1473 cifs_dbg(FYI
, "%s: mid=%llu offset=%llu bytes=%u\n",
1474 __func__
, mid
->mid
, rdata
->offset
, rdata
->bytes
);
1477 * read the rest of READ_RSP header (sans Data array), or whatever we
1478 * can if there's not enough data. At this point, we've read down to
1481 len
= min_t(unsigned int, buflen
, server
->vals
->read_rsp_size
) -
1482 HEADER_SIZE(server
) + 1;
1484 length
= cifs_read_from_socket(server
,
1485 buf
+ HEADER_SIZE(server
) - 1, len
);
1488 server
->total_read
+= length
;
1490 if (server
->ops
->is_session_expired
&&
1491 server
->ops
->is_session_expired(buf
)) {
1492 cifs_reconnect(server
);
1493 wake_up(&server
->response_q
);
1497 if (server
->ops
->is_status_pending
&&
1498 server
->ops
->is_status_pending(buf
, server
, 0)) {
1499 cifs_discard_remaining_data(server
);
1503 /* Was the SMB read successful? */
1504 rdata
->result
= server
->ops
->map_error(buf
, false);
1505 if (rdata
->result
!= 0) {
1506 cifs_dbg(FYI
, "%s: server returned error %d\n",
1507 __func__
, rdata
->result
);
1508 return cifs_readv_discard(server
, mid
);
1511 /* Is there enough to get to the rest of the READ_RSP header? */
1512 if (server
->total_read
< server
->vals
->read_rsp_size
) {
1513 cifs_dbg(FYI
, "%s: server returned short header. got=%u expected=%zu\n",
1514 __func__
, server
->total_read
,
1515 server
->vals
->read_rsp_size
);
1516 rdata
->result
= -EIO
;
1517 return cifs_readv_discard(server
, mid
);
1520 data_offset
= server
->ops
->read_data_offset(buf
) +
1521 server
->vals
->header_preamble_size
;
1522 if (data_offset
< server
->total_read
) {
1524 * win2k8 sometimes sends an offset of 0 when the read
1525 * is beyond the EOF. Treat it as if the data starts just after
1528 cifs_dbg(FYI
, "%s: data offset (%u) inside read response header\n",
1529 __func__
, data_offset
);
1530 data_offset
= server
->total_read
;
1531 } else if (data_offset
> MAX_CIFS_SMALL_BUFFER_SIZE
) {
1532 /* data_offset is beyond the end of smallbuf */
1533 cifs_dbg(FYI
, "%s: data offset (%u) beyond end of smallbuf\n",
1534 __func__
, data_offset
);
1535 rdata
->result
= -EIO
;
1536 return cifs_readv_discard(server
, mid
);
1539 cifs_dbg(FYI
, "%s: total_read=%u data_offset=%u\n",
1540 __func__
, server
->total_read
, data_offset
);
1542 len
= data_offset
- server
->total_read
;
1544 /* read any junk before data into the rest of smallbuf */
1545 length
= cifs_read_from_socket(server
,
1546 buf
+ server
->total_read
, len
);
1549 server
->total_read
+= length
;
1552 /* set up first iov for signature check */
1553 rdata
->iov
[0].iov_base
= buf
;
1554 rdata
->iov
[0].iov_len
= 4;
1555 rdata
->iov
[1].iov_base
= buf
+ 4;
1556 rdata
->iov
[1].iov_len
= server
->total_read
- 4;
1557 cifs_dbg(FYI
, "0: iov_base=%p iov_len=%u\n",
1558 rdata
->iov
[0].iov_base
, server
->total_read
);
1560 /* how much data is in the response? */
1561 #ifdef CONFIG_CIFS_SMB_DIRECT
1562 use_rdma_mr
= rdata
->mr
;
1564 data_len
= server
->ops
->read_data_length(buf
, use_rdma_mr
);
1565 if (!use_rdma_mr
&& (data_offset
+ data_len
> buflen
)) {
1566 /* data_len is corrupt -- discard frame */
1567 rdata
->result
= -EIO
;
1568 return cifs_readv_discard(server
, mid
);
1571 length
= rdata
->read_into_pages(server
, rdata
, data_len
);
1575 server
->total_read
+= length
;
1577 cifs_dbg(FYI
, "total_read=%u buflen=%u remaining=%u\n",
1578 server
->total_read
, buflen
, data_len
);
1580 /* discard anything left over */
1581 if (server
->total_read
< buflen
)
1582 return cifs_readv_discard(server
, mid
);
1584 dequeue_mid(mid
, false);
1585 mid
->resp_buf
= server
->smallbuf
;
1586 server
->smallbuf
= NULL
;
1591 cifs_readv_callback(struct mid_q_entry
*mid
)
1593 struct cifs_readdata
*rdata
= mid
->callback_data
;
1594 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1595 struct TCP_Server_Info
*server
= tcon
->ses
->server
;
1596 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1598 .rq_pages
= rdata
->pages
,
1599 .rq_npages
= rdata
->nr_pages
,
1600 .rq_pagesz
= rdata
->pagesz
,
1601 .rq_tailsz
= rdata
->tailsz
};
1603 cifs_dbg(FYI
, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1604 __func__
, mid
->mid
, mid
->mid_state
, rdata
->result
,
1607 switch (mid
->mid_state
) {
1608 case MID_RESPONSE_RECEIVED
:
1609 /* result already set, check signature */
1613 rc
= cifs_verify_signature(&rqst
, server
,
1614 mid
->sequence_number
);
1616 cifs_dbg(VFS
, "SMB signature verification returned error = %d\n",
1619 /* FIXME: should this be counted toward the initiating task? */
1620 task_io_account_read(rdata
->got_bytes
);
1621 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1623 case MID_REQUEST_SUBMITTED
:
1624 case MID_RETRY_NEEDED
:
1625 rdata
->result
= -EAGAIN
;
1626 if (server
->sign
&& rdata
->got_bytes
)
1627 /* reset bytes number since we can not check a sign */
1628 rdata
->got_bytes
= 0;
1629 /* FIXME: should this be counted toward the initiating task? */
1630 task_io_account_read(rdata
->got_bytes
);
1631 cifs_stats_bytes_read(tcon
, rdata
->got_bytes
);
1634 rdata
->result
= -EIO
;
1637 queue_work(cifsiod_wq
, &rdata
->work
);
1638 DeleteMidQEntry(mid
);
1639 add_credits(server
, 1, 0);
1642 /* cifs_async_readv - send an async write, and set up mid to handle result */
1644 cifs_async_readv(struct cifs_readdata
*rdata
)
1647 READ_REQ
*smb
= NULL
;
1649 struct cifs_tcon
*tcon
= tlink_tcon(rdata
->cfile
->tlink
);
1650 struct smb_rqst rqst
= { .rq_iov
= rdata
->iov
,
1653 cifs_dbg(FYI
, "%s: offset=%llu bytes=%u\n",
1654 __func__
, rdata
->offset
, rdata
->bytes
);
1656 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1659 wct
= 10; /* old style read */
1660 if ((rdata
->offset
>> 32) > 0) {
1661 /* can not handle this big offset for old */
1666 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **)&smb
);
1670 smb
->hdr
.Pid
= cpu_to_le16((__u16
)rdata
->pid
);
1671 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(rdata
->pid
>> 16));
1673 smb
->AndXCommand
= 0xFF; /* none */
1674 smb
->Fid
= rdata
->cfile
->fid
.netfid
;
1675 smb
->OffsetLow
= cpu_to_le32(rdata
->offset
& 0xFFFFFFFF);
1677 smb
->OffsetHigh
= cpu_to_le32(rdata
->offset
>> 32);
1679 smb
->MaxCount
= cpu_to_le16(rdata
->bytes
& 0xFFFF);
1680 smb
->MaxCountHigh
= cpu_to_le32(rdata
->bytes
>> 16);
1684 /* old style read */
1685 struct smb_com_readx_req
*smbr
=
1686 (struct smb_com_readx_req
*)smb
;
1687 smbr
->ByteCount
= 0;
1690 /* 4 for RFC1001 length + 1 for BCC */
1691 rdata
->iov
[0].iov_base
= smb
;
1692 rdata
->iov
[0].iov_len
= 4;
1693 rdata
->iov
[1].iov_base
= (char *)smb
+ 4;
1694 rdata
->iov
[1].iov_len
= get_rfc1002_length(smb
);
1696 kref_get(&rdata
->refcount
);
1697 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, cifs_readv_receive
,
1698 cifs_readv_callback
, NULL
, rdata
, 0);
1701 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1703 kref_put(&rdata
->refcount
, cifs_readdata_release
);
1705 cifs_small_buf_release(smb
);
1710 CIFSSMBRead(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1711 unsigned int *nbytes
, char **buf
, int *pbuf_type
)
1714 READ_REQ
*pSMB
= NULL
;
1715 READ_RSP
*pSMBr
= NULL
;
1716 char *pReadData
= NULL
;
1718 int resp_buf_type
= 0;
1720 struct kvec rsp_iov
;
1721 __u32 pid
= io_parms
->pid
;
1722 __u16 netfid
= io_parms
->netfid
;
1723 __u64 offset
= io_parms
->offset
;
1724 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1725 unsigned int count
= io_parms
->length
;
1727 cifs_dbg(FYI
, "Reading %d bytes on fid %d\n", count
, netfid
);
1728 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1731 wct
= 10; /* old style read */
1732 if ((offset
>> 32) > 0) {
1733 /* can not handle this big offset for old */
1739 rc
= small_smb_init(SMB_COM_READ_ANDX
, wct
, tcon
, (void **) &pSMB
);
1743 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1744 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1746 /* tcon and ses pointer are checked in smb_init */
1747 if (tcon
->ses
->server
== NULL
)
1748 return -ECONNABORTED
;
1750 pSMB
->AndXCommand
= 0xFF; /* none */
1752 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1754 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1756 pSMB
->Remaining
= 0;
1757 pSMB
->MaxCount
= cpu_to_le16(count
& 0xFFFF);
1758 pSMB
->MaxCountHigh
= cpu_to_le32(count
>> 16);
1760 pSMB
->ByteCount
= 0; /* no need to do le conversion since 0 */
1762 /* old style read */
1763 struct smb_com_readx_req
*pSMBW
=
1764 (struct smb_com_readx_req
*)pSMB
;
1765 pSMBW
->ByteCount
= 0;
1768 iov
[0].iov_base
= (char *)pSMB
;
1769 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
1770 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1, &resp_buf_type
,
1771 CIFS_LOG_ERROR
, &rsp_iov
);
1772 cifs_small_buf_release(pSMB
);
1773 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_reads
);
1774 pSMBr
= (READ_RSP
*)rsp_iov
.iov_base
;
1776 cifs_dbg(VFS
, "Send error in read = %d\n", rc
);
1778 int data_length
= le16_to_cpu(pSMBr
->DataLengthHigh
);
1779 data_length
= data_length
<< 16;
1780 data_length
+= le16_to_cpu(pSMBr
->DataLength
);
1781 *nbytes
= data_length
;
1783 /*check that DataLength would not go beyond end of SMB */
1784 if ((data_length
> CIFSMaxBufSize
)
1785 || (data_length
> count
)) {
1786 cifs_dbg(FYI
, "bad length %d for count %d\n",
1787 data_length
, count
);
1791 pReadData
= (char *) (&pSMBr
->hdr
.Protocol
) +
1792 le16_to_cpu(pSMBr
->DataOffset
);
1793 /* if (rc = copy_to_user(buf, pReadData, data_length)) {
1794 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1796 }*/ /* can not use copy_to_user when using page cache*/
1798 memcpy(*buf
, pReadData
, data_length
);
1803 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
1804 } else if (resp_buf_type
!= CIFS_NO_BUFFER
) {
1805 /* return buffer to caller to free */
1806 *buf
= rsp_iov
.iov_base
;
1807 if (resp_buf_type
== CIFS_SMALL_BUFFER
)
1808 *pbuf_type
= CIFS_SMALL_BUFFER
;
1809 else if (resp_buf_type
== CIFS_LARGE_BUFFER
)
1810 *pbuf_type
= CIFS_LARGE_BUFFER
;
1811 } /* else no valid buffer on return - leave as null */
1813 /* Note: On -EAGAIN error only caller can retry on handle based calls
1814 since file handle passed in no longer valid */
1820 CIFSSMBWrite(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
1821 unsigned int *nbytes
, const char *buf
)
1824 WRITE_REQ
*pSMB
= NULL
;
1825 WRITE_RSP
*pSMBr
= NULL
;
1826 int bytes_returned
, wct
;
1829 __u32 pid
= io_parms
->pid
;
1830 __u16 netfid
= io_parms
->netfid
;
1831 __u64 offset
= io_parms
->offset
;
1832 struct cifs_tcon
*tcon
= io_parms
->tcon
;
1833 unsigned int count
= io_parms
->length
;
1837 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1838 if (tcon
->ses
== NULL
)
1839 return -ECONNABORTED
;
1841 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
)
1845 if ((offset
>> 32) > 0) {
1846 /* can not handle big offset for old srv */
1851 rc
= smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
,
1856 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
1857 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
1859 /* tcon and ses pointer are checked in smb_init */
1860 if (tcon
->ses
->server
== NULL
)
1861 return -ECONNABORTED
;
1863 pSMB
->AndXCommand
= 0xFF; /* none */
1865 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
1867 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
1869 pSMB
->Reserved
= 0xFFFFFFFF;
1870 pSMB
->WriteMode
= 0;
1871 pSMB
->Remaining
= 0;
1873 /* Can increase buffer size if buffer is big enough in some cases ie we
1874 can send more if LARGE_WRITE_X capability returned by the server and if
1875 our buffer is big enough or if we convert to iovecs on socket writes
1876 and eliminate the copy to the CIFS buffer */
1877 if (tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
) {
1878 bytes_sent
= min_t(const unsigned int, CIFSMaxBufSize
, count
);
1880 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
)
1884 if (bytes_sent
> count
)
1887 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
1889 memcpy(pSMB
->Data
, buf
, bytes_sent
);
1890 else if (count
!= 0) {
1892 cifs_buf_release(pSMB
);
1894 } /* else setting file size with write of zero bytes */
1896 byte_count
= bytes_sent
+ 1; /* pad */
1897 else /* wct == 12 */
1898 byte_count
= bytes_sent
+ 5; /* bigger pad, smaller smb hdr */
1900 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
& 0xFFFF);
1901 pSMB
->DataLengthHigh
= cpu_to_le16(bytes_sent
>> 16);
1902 inc_rfc1001_len(pSMB
, byte_count
);
1905 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1906 else { /* old style write has byte count 4 bytes earlier
1908 struct smb_com_writex_req
*pSMBW
=
1909 (struct smb_com_writex_req
*)pSMB
;
1910 pSMBW
->ByteCount
= cpu_to_le16(byte_count
);
1913 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1914 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1915 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
1917 cifs_dbg(FYI
, "Send error in write = %d\n", rc
);
1919 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
1920 *nbytes
= (*nbytes
) << 16;
1921 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
1924 * Mask off high 16 bits when bytes written as returned by the
1925 * server is greater than bytes requested by the client. Some
1926 * OS/2 servers are known to set incorrect CountHigh values.
1928 if (*nbytes
> count
)
1932 cifs_buf_release(pSMB
);
1934 /* Note: On -EAGAIN error only caller can retry on handle based calls
1935 since file handle passed in no longer valid */
1941 cifs_writedata_release(struct kref
*refcount
)
1943 struct cifs_writedata
*wdata
= container_of(refcount
,
1944 struct cifs_writedata
, refcount
);
1945 #ifdef CONFIG_CIFS_SMB_DIRECT
1947 smbd_deregister_mr(wdata
->mr
);
1953 cifsFileInfo_put(wdata
->cfile
);
1955 kvfree(wdata
->pages
);
1960 * Write failed with a retryable error. Resend the write request. It's also
1961 * possible that the page was redirtied so re-clean the page.
1964 cifs_writev_requeue(struct cifs_writedata
*wdata
)
1967 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
1968 struct TCP_Server_Info
*server
;
1969 unsigned int rest_len
;
1971 server
= tlink_tcon(wdata
->cfile
->tlink
)->ses
->server
;
1973 rest_len
= wdata
->bytes
;
1975 struct cifs_writedata
*wdata2
;
1976 unsigned int j
, nr_pages
, wsize
, tailsz
, cur_len
;
1978 wsize
= server
->ops
->wp_retry_size(inode
);
1979 if (wsize
< rest_len
) {
1980 nr_pages
= wsize
/ PAGE_SIZE
;
1985 cur_len
= nr_pages
* PAGE_SIZE
;
1988 nr_pages
= DIV_ROUND_UP(rest_len
, PAGE_SIZE
);
1990 tailsz
= rest_len
- (nr_pages
- 1) * PAGE_SIZE
;
1993 wdata2
= cifs_writedata_alloc(nr_pages
, cifs_writev_complete
);
1999 for (j
= 0; j
< nr_pages
; j
++) {
2000 wdata2
->pages
[j
] = wdata
->pages
[i
+ j
];
2001 lock_page(wdata2
->pages
[j
]);
2002 clear_page_dirty_for_io(wdata2
->pages
[j
]);
2005 wdata2
->sync_mode
= wdata
->sync_mode
;
2006 wdata2
->nr_pages
= nr_pages
;
2007 wdata2
->offset
= page_offset(wdata2
->pages
[0]);
2008 wdata2
->pagesz
= PAGE_SIZE
;
2009 wdata2
->tailsz
= tailsz
;
2010 wdata2
->bytes
= cur_len
;
2012 wdata2
->cfile
= find_writable_file(CIFS_I(inode
), false);
2013 if (!wdata2
->cfile
) {
2014 cifs_dbg(VFS
, "No writable handles for inode\n");
2018 wdata2
->pid
= wdata2
->cfile
->pid
;
2019 rc
= server
->ops
->async_writev(wdata2
, cifs_writedata_release
);
2021 for (j
= 0; j
< nr_pages
; j
++) {
2022 unlock_page(wdata2
->pages
[j
]);
2023 if (rc
!= 0 && rc
!= -EAGAIN
) {
2024 SetPageError(wdata2
->pages
[j
]);
2025 end_page_writeback(wdata2
->pages
[j
]);
2026 put_page(wdata2
->pages
[j
]);
2031 kref_put(&wdata2
->refcount
, cifs_writedata_release
);
2037 rest_len
-= cur_len
;
2039 } while (i
< wdata
->nr_pages
);
2041 mapping_set_error(inode
->i_mapping
, rc
);
2042 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2046 cifs_writev_complete(struct work_struct
*work
)
2048 struct cifs_writedata
*wdata
= container_of(work
,
2049 struct cifs_writedata
, work
);
2050 struct inode
*inode
= d_inode(wdata
->cfile
->dentry
);
2053 if (wdata
->result
== 0) {
2054 spin_lock(&inode
->i_lock
);
2055 cifs_update_eof(CIFS_I(inode
), wdata
->offset
, wdata
->bytes
);
2056 spin_unlock(&inode
->i_lock
);
2057 cifs_stats_bytes_written(tlink_tcon(wdata
->cfile
->tlink
),
2059 } else if (wdata
->sync_mode
== WB_SYNC_ALL
&& wdata
->result
== -EAGAIN
)
2060 return cifs_writev_requeue(wdata
);
2062 for (i
= 0; i
< wdata
->nr_pages
; i
++) {
2063 struct page
*page
= wdata
->pages
[i
];
2064 if (wdata
->result
== -EAGAIN
)
2065 __set_page_dirty_nobuffers(page
);
2066 else if (wdata
->result
< 0)
2068 end_page_writeback(page
);
2071 if (wdata
->result
!= -EAGAIN
)
2072 mapping_set_error(inode
->i_mapping
, wdata
->result
);
2073 kref_put(&wdata
->refcount
, cifs_writedata_release
);
2076 struct cifs_writedata
*
2077 cifs_writedata_alloc(unsigned int nr_pages
, work_func_t complete
)
2079 struct page
**pages
=
2080 kcalloc(nr_pages
, sizeof(struct page
*), GFP_NOFS
);
2082 return cifs_writedata_direct_alloc(pages
, complete
);
2087 struct cifs_writedata
*
2088 cifs_writedata_direct_alloc(struct page
**pages
, work_func_t complete
)
2090 struct cifs_writedata
*wdata
;
2092 wdata
= kzalloc(sizeof(*wdata
), GFP_NOFS
);
2093 if (wdata
!= NULL
) {
2094 wdata
->pages
= pages
;
2095 kref_init(&wdata
->refcount
);
2096 INIT_LIST_HEAD(&wdata
->list
);
2097 init_completion(&wdata
->done
);
2098 INIT_WORK(&wdata
->work
, complete
);
2104 * Check the mid_state and signature on received buffer (if any), and queue the
2105 * workqueue completion task.
2108 cifs_writev_callback(struct mid_q_entry
*mid
)
2110 struct cifs_writedata
*wdata
= mid
->callback_data
;
2111 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2112 unsigned int written
;
2113 WRITE_RSP
*smb
= (WRITE_RSP
*)mid
->resp_buf
;
2115 switch (mid
->mid_state
) {
2116 case MID_RESPONSE_RECEIVED
:
2117 wdata
->result
= cifs_check_receive(mid
, tcon
->ses
->server
, 0);
2118 if (wdata
->result
!= 0)
2121 written
= le16_to_cpu(smb
->CountHigh
);
2123 written
+= le16_to_cpu(smb
->Count
);
2125 * Mask off high 16 bits when bytes written as returned
2126 * by the server is greater than bytes requested by the
2127 * client. OS/2 servers are known to set incorrect
2130 if (written
> wdata
->bytes
)
2133 if (written
< wdata
->bytes
)
2134 wdata
->result
= -ENOSPC
;
2136 wdata
->bytes
= written
;
2138 case MID_REQUEST_SUBMITTED
:
2139 case MID_RETRY_NEEDED
:
2140 wdata
->result
= -EAGAIN
;
2143 wdata
->result
= -EIO
;
2147 queue_work(cifsiod_wq
, &wdata
->work
);
2148 DeleteMidQEntry(mid
);
2149 add_credits(tcon
->ses
->server
, 1, 0);
2152 /* cifs_async_writev - send an async write, and set up mid to handle result */
2154 cifs_async_writev(struct cifs_writedata
*wdata
,
2155 void (*release
)(struct kref
*kref
))
2158 WRITE_REQ
*smb
= NULL
;
2160 struct cifs_tcon
*tcon
= tlink_tcon(wdata
->cfile
->tlink
);
2162 struct smb_rqst rqst
= { };
2164 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2168 if (wdata
->offset
>> 32 > 0) {
2169 /* can not handle big offset for old srv */
2174 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **)&smb
);
2176 goto async_writev_out
;
2178 smb
->hdr
.Pid
= cpu_to_le16((__u16
)wdata
->pid
);
2179 smb
->hdr
.PidHigh
= cpu_to_le16((__u16
)(wdata
->pid
>> 16));
2181 smb
->AndXCommand
= 0xFF; /* none */
2182 smb
->Fid
= wdata
->cfile
->fid
.netfid
;
2183 smb
->OffsetLow
= cpu_to_le32(wdata
->offset
& 0xFFFFFFFF);
2185 smb
->OffsetHigh
= cpu_to_le32(wdata
->offset
>> 32);
2186 smb
->Reserved
= 0xFFFFFFFF;
2191 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2193 /* 4 for RFC1001 length + 1 for BCC */
2195 iov
[0].iov_base
= smb
;
2196 iov
[1].iov_len
= get_rfc1002_length(smb
) + 1;
2197 iov
[1].iov_base
= (char *)smb
+ 4;
2201 rqst
.rq_pages
= wdata
->pages
;
2202 rqst
.rq_npages
= wdata
->nr_pages
;
2203 rqst
.rq_pagesz
= wdata
->pagesz
;
2204 rqst
.rq_tailsz
= wdata
->tailsz
;
2206 cifs_dbg(FYI
, "async write at %llu %u bytes\n",
2207 wdata
->offset
, wdata
->bytes
);
2209 smb
->DataLengthLow
= cpu_to_le16(wdata
->bytes
& 0xFFFF);
2210 smb
->DataLengthHigh
= cpu_to_le16(wdata
->bytes
>> 16);
2213 inc_rfc1001_len(&smb
->hdr
, wdata
->bytes
+ 1);
2214 put_bcc(wdata
->bytes
+ 1, &smb
->hdr
);
2217 struct smb_com_writex_req
*smbw
=
2218 (struct smb_com_writex_req
*)smb
;
2219 inc_rfc1001_len(&smbw
->hdr
, wdata
->bytes
+ 5);
2220 put_bcc(wdata
->bytes
+ 5, &smbw
->hdr
);
2221 iov
[1].iov_len
+= 4; /* pad bigger by four bytes */
2224 kref_get(&wdata
->refcount
);
2225 rc
= cifs_call_async(tcon
->ses
->server
, &rqst
, NULL
,
2226 cifs_writev_callback
, NULL
, wdata
, 0);
2229 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2231 kref_put(&wdata
->refcount
, release
);
2234 cifs_small_buf_release(smb
);
2239 CIFSSMBWrite2(const unsigned int xid
, struct cifs_io_parms
*io_parms
,
2240 unsigned int *nbytes
, struct kvec
*iov
, int n_vec
)
2243 WRITE_REQ
*pSMB
= NULL
;
2246 int resp_buf_type
= 0;
2247 __u32 pid
= io_parms
->pid
;
2248 __u16 netfid
= io_parms
->netfid
;
2249 __u64 offset
= io_parms
->offset
;
2250 struct cifs_tcon
*tcon
= io_parms
->tcon
;
2251 unsigned int count
= io_parms
->length
;
2252 struct kvec rsp_iov
;
2256 cifs_dbg(FYI
, "write2 at %lld %d bytes\n", (long long)offset
, count
);
2258 if (tcon
->ses
->capabilities
& CAP_LARGE_FILES
) {
2262 if ((offset
>> 32) > 0) {
2263 /* can not handle big offset for old srv */
2267 rc
= small_smb_init(SMB_COM_WRITE_ANDX
, wct
, tcon
, (void **) &pSMB
);
2271 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid
);
2272 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid
>> 16));
2274 /* tcon and ses pointer are checked in smb_init */
2275 if (tcon
->ses
->server
== NULL
)
2276 return -ECONNABORTED
;
2278 pSMB
->AndXCommand
= 0xFF; /* none */
2280 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
2282 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
2283 pSMB
->Reserved
= 0xFFFFFFFF;
2284 pSMB
->WriteMode
= 0;
2285 pSMB
->Remaining
= 0;
2288 cpu_to_le16(offsetof(struct smb_com_write_req
, Data
) - 4);
2290 pSMB
->DataLengthLow
= cpu_to_le16(count
& 0xFFFF);
2291 pSMB
->DataLengthHigh
= cpu_to_le16(count
>> 16);
2292 /* header + 1 byte pad */
2293 smb_hdr_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 1;
2295 inc_rfc1001_len(pSMB
, count
+ 1);
2296 else /* wct == 12 */
2297 inc_rfc1001_len(pSMB
, count
+ 5); /* smb data starts later */
2299 pSMB
->ByteCount
= cpu_to_le16(count
+ 1);
2300 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2301 struct smb_com_writex_req
*pSMBW
=
2302 (struct smb_com_writex_req
*)pSMB
;
2303 pSMBW
->ByteCount
= cpu_to_le16(count
+ 5);
2305 iov
[0].iov_base
= pSMB
;
2307 iov
[0].iov_len
= smb_hdr_len
+ 4;
2308 else /* wct == 12 pad bigger by four bytes */
2309 iov
[0].iov_len
= smb_hdr_len
+ 8;
2311 rc
= SendReceive2(xid
, tcon
->ses
, iov
, n_vec
+ 1, &resp_buf_type
, 0,
2313 cifs_small_buf_release(pSMB
);
2314 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_writes
);
2316 cifs_dbg(FYI
, "Send error Write2 = %d\n", rc
);
2317 } else if (resp_buf_type
== 0) {
2318 /* presumably this can not happen, but best to be safe */
2321 WRITE_RSP
*pSMBr
= (WRITE_RSP
*)rsp_iov
.iov_base
;
2322 *nbytes
= le16_to_cpu(pSMBr
->CountHigh
);
2323 *nbytes
= (*nbytes
) << 16;
2324 *nbytes
+= le16_to_cpu(pSMBr
->Count
);
2327 * Mask off high 16 bits when bytes written as returned by the
2328 * server is greater than bytes requested by the client. OS/2
2329 * servers are known to set incorrect CountHigh values.
2331 if (*nbytes
> count
)
2335 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2337 /* Note: On -EAGAIN error only caller can retry on handle based calls
2338 since file handle passed in no longer valid */
2343 int cifs_lockv(const unsigned int xid
, struct cifs_tcon
*tcon
,
2344 const __u16 netfid
, const __u8 lock_type
, const __u32 num_unlock
,
2345 const __u32 num_lock
, LOCKING_ANDX_RANGE
*buf
)
2348 LOCK_REQ
*pSMB
= NULL
;
2350 struct kvec rsp_iov
;
2354 cifs_dbg(FYI
, "cifs_lockv num lock %d num unlock %d\n",
2355 num_lock
, num_unlock
);
2357 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2362 pSMB
->NumberOfLocks
= cpu_to_le16(num_lock
);
2363 pSMB
->NumberOfUnlocks
= cpu_to_le16(num_unlock
);
2364 pSMB
->LockType
= lock_type
;
2365 pSMB
->AndXCommand
= 0xFF; /* none */
2366 pSMB
->Fid
= netfid
; /* netfid stays le */
2368 count
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2369 inc_rfc1001_len(pSMB
, count
);
2370 pSMB
->ByteCount
= cpu_to_le16(count
);
2372 iov
[0].iov_base
= (char *)pSMB
;
2373 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4 -
2374 (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2375 iov
[1].iov_base
= (char *)buf
;
2376 iov
[1].iov_len
= (num_unlock
+ num_lock
) * sizeof(LOCKING_ANDX_RANGE
);
2378 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2379 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 2, &resp_buf_type
, CIFS_NO_RESP
,
2381 cifs_small_buf_release(pSMB
);
2383 cifs_dbg(FYI
, "Send error in cifs_lockv = %d\n", rc
);
2389 CIFSSMBLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2390 const __u16 smb_file_id
, const __u32 netpid
, const __u64 len
,
2391 const __u64 offset
, const __u32 numUnlock
,
2392 const __u32 numLock
, const __u8 lockType
,
2393 const bool waitFlag
, const __u8 oplock_level
)
2396 LOCK_REQ
*pSMB
= NULL
;
2397 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2402 cifs_dbg(FYI
, "CIFSSMBLock timeout %d numLock %d\n",
2403 (int)waitFlag
, numLock
);
2404 rc
= small_smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
);
2409 if (lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
2410 /* no response expected */
2411 flags
= CIFS_ASYNC_OP
| CIFS_OBREAK_OP
;
2413 } else if (waitFlag
) {
2414 flags
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2415 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
2420 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
2421 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
2422 pSMB
->LockType
= lockType
;
2423 pSMB
->OplockLevel
= oplock_level
;
2424 pSMB
->AndXCommand
= 0xFF; /* none */
2425 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
2427 if ((numLock
!= 0) || (numUnlock
!= 0)) {
2428 pSMB
->Locks
[0].Pid
= cpu_to_le16(netpid
);
2429 /* BB where to store pid high? */
2430 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
2431 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
2432 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
2433 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
2434 count
= sizeof(LOCKING_ANDX_RANGE
);
2439 inc_rfc1001_len(pSMB
, count
);
2440 pSMB
->ByteCount
= cpu_to_le16(count
);
2443 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2444 (struct smb_hdr
*) pSMB
, &bytes_returned
);
2446 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *)pSMB
, flags
);
2447 cifs_small_buf_release(pSMB
);
2448 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_locks
);
2450 cifs_dbg(FYI
, "Send error in Lock = %d\n", rc
);
2452 /* Note: On -EAGAIN error only caller can retry on handle based calls
2453 since file handle passed in no longer valid */
2458 CIFSSMBPosixLock(const unsigned int xid
, struct cifs_tcon
*tcon
,
2459 const __u16 smb_file_id
, const __u32 netpid
,
2460 const loff_t start_offset
, const __u64 len
,
2461 struct file_lock
*pLockData
, const __u16 lock_type
,
2462 const bool waitFlag
)
2464 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2465 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2466 struct cifs_posix_lock
*parm_data
;
2469 int bytes_returned
= 0;
2470 int resp_buf_type
= 0;
2471 __u16 params
, param_offset
, offset
, byte_count
, count
;
2473 struct kvec rsp_iov
;
2475 cifs_dbg(FYI
, "Posix Lock\n");
2477 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
2482 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)pSMB
;
2485 pSMB
->MaxSetupCount
= 0;
2488 pSMB
->Reserved2
= 0;
2489 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2490 offset
= param_offset
+ params
;
2492 count
= sizeof(struct cifs_posix_lock
);
2493 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2494 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2495 pSMB
->SetupCount
= 1;
2496 pSMB
->Reserved3
= 0;
2498 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
2500 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2501 byte_count
= 3 /* pad */ + params
+ count
;
2502 pSMB
->DataCount
= cpu_to_le16(count
);
2503 pSMB
->ParameterCount
= cpu_to_le16(params
);
2504 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2505 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2506 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2507 parm_data
= (struct cifs_posix_lock
*)
2508 (((char *) &pSMB
->hdr
.Protocol
) + offset
);
2510 parm_data
->lock_type
= cpu_to_le16(lock_type
);
2512 timeout
= CIFS_BLOCKING_OP
; /* blocking operation, no timeout */
2513 parm_data
->lock_flags
= cpu_to_le16(1);
2514 pSMB
->Timeout
= cpu_to_le32(-1);
2518 parm_data
->pid
= cpu_to_le32(netpid
);
2519 parm_data
->start
= cpu_to_le64(start_offset
);
2520 parm_data
->length
= cpu_to_le64(len
); /* normalize negative numbers */
2522 pSMB
->DataOffset
= cpu_to_le16(offset
);
2523 pSMB
->Fid
= smb_file_id
;
2524 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_LOCK
);
2525 pSMB
->Reserved4
= 0;
2526 inc_rfc1001_len(pSMB
, byte_count
);
2527 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2529 rc
= SendReceiveBlockingLock(xid
, tcon
, (struct smb_hdr
*) pSMB
,
2530 (struct smb_hdr
*) pSMBr
, &bytes_returned
);
2532 iov
[0].iov_base
= (char *)pSMB
;
2533 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
2534 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovecs */,
2535 &resp_buf_type
, timeout
, &rsp_iov
);
2536 pSMBr
= (struct smb_com_transaction2_sfi_rsp
*)rsp_iov
.iov_base
;
2538 cifs_small_buf_release(pSMB
);
2541 cifs_dbg(FYI
, "Send error in Posix Lock = %d\n", rc
);
2542 } else if (pLockData
) {
2543 /* lock structure can be returned on get */
2546 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
2548 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(*parm_data
)) {
2549 rc
= -EIO
; /* bad smb */
2552 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
2553 data_count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
2554 if (data_count
< sizeof(struct cifs_posix_lock
)) {
2558 parm_data
= (struct cifs_posix_lock
*)
2559 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
2560 if (parm_data
->lock_type
== cpu_to_le16(CIFS_UNLCK
))
2561 pLockData
->fl_type
= F_UNLCK
;
2563 if (parm_data
->lock_type
==
2564 cpu_to_le16(CIFS_RDLCK
))
2565 pLockData
->fl_type
= F_RDLCK
;
2566 else if (parm_data
->lock_type
==
2567 cpu_to_le16(CIFS_WRLCK
))
2568 pLockData
->fl_type
= F_WRLCK
;
2570 pLockData
->fl_start
= le64_to_cpu(parm_data
->start
);
2571 pLockData
->fl_end
= pLockData
->fl_start
+
2572 le64_to_cpu(parm_data
->length
) - 1;
2573 pLockData
->fl_pid
= -le32_to_cpu(parm_data
->pid
);
2578 free_rsp_buf(resp_buf_type
, rsp_iov
.iov_base
);
2580 /* Note: On -EAGAIN error only caller can retry on handle based calls
2581 since file handle passed in no longer valid */
2588 CIFSSMBClose(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2591 CLOSE_REQ
*pSMB
= NULL
;
2592 cifs_dbg(FYI
, "In CIFSSMBClose\n");
2594 /* do not retry on dead session on close */
2595 rc
= small_smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
);
2601 pSMB
->FileID
= (__u16
) smb_file_id
;
2602 pSMB
->LastWriteTime
= 0xFFFFFFFF;
2603 pSMB
->ByteCount
= 0;
2604 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2605 cifs_small_buf_release(pSMB
);
2606 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_closes
);
2609 /* EINTR is expected when user ctl-c to kill app */
2610 cifs_dbg(VFS
, "Send error in Close = %d\n", rc
);
2614 /* Since session is dead, file will be closed on server already */
2622 CIFSSMBFlush(const unsigned int xid
, struct cifs_tcon
*tcon
, int smb_file_id
)
2625 FLUSH_REQ
*pSMB
= NULL
;
2626 cifs_dbg(FYI
, "In CIFSSMBFlush\n");
2628 rc
= small_smb_init(SMB_COM_FLUSH
, 1, tcon
, (void **) &pSMB
);
2632 pSMB
->FileID
= (__u16
) smb_file_id
;
2633 pSMB
->ByteCount
= 0;
2634 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
2635 cifs_small_buf_release(pSMB
);
2636 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_flushes
);
2638 cifs_dbg(VFS
, "Send error in Flush = %d\n", rc
);
2644 CIFSSMBRename(const unsigned int xid
, struct cifs_tcon
*tcon
,
2645 const char *from_name
, const char *to_name
,
2646 struct cifs_sb_info
*cifs_sb
)
2649 RENAME_REQ
*pSMB
= NULL
;
2650 RENAME_RSP
*pSMBr
= NULL
;
2652 int name_len
, name_len2
;
2654 int remap
= cifs_remap(cifs_sb
);
2656 cifs_dbg(FYI
, "In CIFSSMBRename\n");
2658 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
2663 pSMB
->BufferFormat
= 0x04;
2664 pSMB
->SearchAttributes
=
2665 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
2668 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2669 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2670 from_name
, PATH_MAX
,
2671 cifs_sb
->local_nls
, remap
);
2672 name_len
++; /* trailing null */
2674 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2675 /* protocol requires ASCII signature byte on Unicode string */
2676 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2678 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2679 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
2681 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2682 name_len2
*= 2; /* convert to bytes */
2683 } else { /* BB improve the check for buffer overruns BB */
2684 name_len
= strnlen(from_name
, PATH_MAX
);
2685 name_len
++; /* trailing null */
2686 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
2687 name_len2
= strnlen(to_name
, PATH_MAX
);
2688 name_len2
++; /* trailing null */
2689 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2690 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
2691 name_len2
++; /* trailing null */
2692 name_len2
++; /* signature byte */
2695 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2696 inc_rfc1001_len(pSMB
, count
);
2697 pSMB
->ByteCount
= cpu_to_le16(count
);
2699 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2700 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2701 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_renames
);
2703 cifs_dbg(FYI
, "Send error in rename = %d\n", rc
);
2705 cifs_buf_release(pSMB
);
2713 int CIFSSMBRenameOpenFile(const unsigned int xid
, struct cifs_tcon
*pTcon
,
2714 int netfid
, const char *target_name
,
2715 const struct nls_table
*nls_codepage
, int remap
)
2717 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2718 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2719 struct set_file_rename
*rename_info
;
2721 char dummy_string
[30];
2723 int bytes_returned
= 0;
2725 __u16 params
, param_offset
, offset
, count
, byte_count
;
2727 cifs_dbg(FYI
, "Rename to File by handle\n");
2728 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
2734 pSMB
->MaxSetupCount
= 0;
2738 pSMB
->Reserved2
= 0;
2739 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2740 offset
= param_offset
+ params
;
2742 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2743 rename_info
= (struct set_file_rename
*) data_offset
;
2744 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2745 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB from sess */
2746 pSMB
->SetupCount
= 1;
2747 pSMB
->Reserved3
= 0;
2748 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2749 byte_count
= 3 /* pad */ + params
;
2750 pSMB
->ParameterCount
= cpu_to_le16(params
);
2751 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2752 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2753 pSMB
->DataOffset
= cpu_to_le16(offset
);
2754 /* construct random name ".cifs_tmp<inodenum><mid>" */
2755 rename_info
->overwrite
= cpu_to_le32(1);
2756 rename_info
->root_fid
= 0;
2757 /* unicode only call */
2758 if (target_name
== NULL
) {
2759 sprintf(dummy_string
, "cifs%x", pSMB
->hdr
.Mid
);
2761 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2762 dummy_string
, 24, nls_codepage
, remap
);
2765 cifsConvertToUTF16((__le16
*)rename_info
->target_name
,
2766 target_name
, PATH_MAX
, nls_codepage
,
2769 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
2770 count
= 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str
);
2771 byte_count
+= count
;
2772 pSMB
->DataCount
= cpu_to_le16(count
);
2773 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2775 pSMB
->InformationLevel
=
2776 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
2777 pSMB
->Reserved4
= 0;
2778 inc_rfc1001_len(pSMB
, byte_count
);
2779 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2780 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
2781 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2782 cifs_stats_inc(&pTcon
->stats
.cifs_stats
.num_t2renames
);
2784 cifs_dbg(FYI
, "Send error in Rename (by file handle) = %d\n",
2787 cifs_buf_release(pSMB
);
2789 /* Note: On -EAGAIN error only caller can retry on handle based calls
2790 since file handle passed in no longer valid */
2796 CIFSSMBCopy(const unsigned int xid
, struct cifs_tcon
*tcon
,
2797 const char *fromName
, const __u16 target_tid
, const char *toName
,
2798 const int flags
, const struct nls_table
*nls_codepage
, int remap
)
2801 COPY_REQ
*pSMB
= NULL
;
2802 COPY_RSP
*pSMBr
= NULL
;
2804 int name_len
, name_len2
;
2807 cifs_dbg(FYI
, "In CIFSSMBCopy\n");
2809 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
2814 pSMB
->BufferFormat
= 0x04;
2815 pSMB
->Tid2
= target_tid
;
2817 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
2819 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2820 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
,
2821 fromName
, PATH_MAX
, nls_codepage
,
2823 name_len
++; /* trailing null */
2825 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
2826 /* protocol requires ASCII signature byte on Unicode string */
2827 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
2829 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
2830 toName
, PATH_MAX
, nls_codepage
, remap
);
2831 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
2832 name_len2
*= 2; /* convert to bytes */
2833 } else { /* BB improve the check for buffer overruns BB */
2834 name_len
= strnlen(fromName
, PATH_MAX
);
2835 name_len
++; /* trailing null */
2836 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
2837 name_len2
= strnlen(toName
, PATH_MAX
);
2838 name_len2
++; /* trailing null */
2839 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
2840 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
2841 name_len2
++; /* trailing null */
2842 name_len2
++; /* signature byte */
2845 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
2846 inc_rfc1001_len(pSMB
, count
);
2847 pSMB
->ByteCount
= cpu_to_le16(count
);
2849 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2850 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2852 cifs_dbg(FYI
, "Send error in copy = %d with %d files copied\n",
2853 rc
, le16_to_cpu(pSMBr
->CopyCount
));
2855 cifs_buf_release(pSMB
);
2864 CIFSUnixCreateSymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2865 const char *fromName
, const char *toName
,
2866 const struct nls_table
*nls_codepage
, int remap
)
2868 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2869 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2872 int name_len_target
;
2874 int bytes_returned
= 0;
2875 __u16 params
, param_offset
, offset
, byte_count
;
2877 cifs_dbg(FYI
, "In Symlink Unix style\n");
2879 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2884 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2886 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fromName
,
2887 /* find define for this maxpathcomponent */
2888 PATH_MAX
, nls_codepage
, remap
);
2889 name_len
++; /* trailing null */
2892 } else { /* BB improve the check for buffer overruns BB */
2893 name_len
= strnlen(fromName
, PATH_MAX
);
2894 name_len
++; /* trailing null */
2895 strncpy(pSMB
->FileName
, fromName
, name_len
);
2897 params
= 6 + name_len
;
2898 pSMB
->MaxSetupCount
= 0;
2902 pSMB
->Reserved2
= 0;
2903 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2904 InformationLevel
) - 4;
2905 offset
= param_offset
+ params
;
2907 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2908 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2910 cifsConvertToUTF16((__le16
*) data_offset
, toName
,
2911 /* find define for this maxpathcomponent */
2912 PATH_MAX
, nls_codepage
, remap
);
2913 name_len_target
++; /* trailing null */
2914 name_len_target
*= 2;
2915 } else { /* BB improve the check for buffer overruns BB */
2916 name_len_target
= strnlen(toName
, PATH_MAX
);
2917 name_len_target
++; /* trailing null */
2918 strncpy(data_offset
, toName
, name_len_target
);
2921 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2922 /* BB find exact max on data count below from sess */
2923 pSMB
->MaxDataCount
= cpu_to_le16(1000);
2924 pSMB
->SetupCount
= 1;
2925 pSMB
->Reserved3
= 0;
2926 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2927 byte_count
= 3 /* pad */ + params
+ name_len_target
;
2928 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
2929 pSMB
->ParameterCount
= cpu_to_le16(params
);
2930 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2931 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2932 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2933 pSMB
->DataOffset
= cpu_to_le16(offset
);
2934 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
2935 pSMB
->Reserved4
= 0;
2936 inc_rfc1001_len(pSMB
, byte_count
);
2937 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2938 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2939 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2940 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_symlinks
);
2942 cifs_dbg(FYI
, "Send error in SetPathInfo create symlink = %d\n",
2945 cifs_buf_release(pSMB
);
2948 goto createSymLinkRetry
;
2954 CIFSUnixCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
2955 const char *fromName
, const char *toName
,
2956 const struct nls_table
*nls_codepage
, int remap
)
2958 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2959 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2962 int name_len_target
;
2964 int bytes_returned
= 0;
2965 __u16 params
, param_offset
, offset
, byte_count
;
2967 cifs_dbg(FYI
, "In Create Hard link Unix style\n");
2968 createHardLinkRetry
:
2969 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2974 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2975 name_len
= cifsConvertToUTF16((__le16
*) pSMB
->FileName
, toName
,
2976 PATH_MAX
, nls_codepage
, remap
);
2977 name_len
++; /* trailing null */
2980 } else { /* BB improve the check for buffer overruns BB */
2981 name_len
= strnlen(toName
, PATH_MAX
);
2982 name_len
++; /* trailing null */
2983 strncpy(pSMB
->FileName
, toName
, name_len
);
2985 params
= 6 + name_len
;
2986 pSMB
->MaxSetupCount
= 0;
2990 pSMB
->Reserved2
= 0;
2991 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2992 InformationLevel
) - 4;
2993 offset
= param_offset
+ params
;
2995 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2996 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2998 cifsConvertToUTF16((__le16
*) data_offset
, fromName
,
2999 PATH_MAX
, nls_codepage
, remap
);
3000 name_len_target
++; /* trailing null */
3001 name_len_target
*= 2;
3002 } else { /* BB improve the check for buffer overruns BB */
3003 name_len_target
= strnlen(fromName
, PATH_MAX
);
3004 name_len_target
++; /* trailing null */
3005 strncpy(data_offset
, fromName
, name_len_target
);
3008 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3009 /* BB find exact max on data count below from sess*/
3010 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3011 pSMB
->SetupCount
= 1;
3012 pSMB
->Reserved3
= 0;
3013 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3014 byte_count
= 3 /* pad */ + params
+ name_len_target
;
3015 pSMB
->ParameterCount
= cpu_to_le16(params
);
3016 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3017 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
3018 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3019 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3020 pSMB
->DataOffset
= cpu_to_le16(offset
);
3021 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
3022 pSMB
->Reserved4
= 0;
3023 inc_rfc1001_len(pSMB
, byte_count
);
3024 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3025 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3026 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3027 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3029 cifs_dbg(FYI
, "Send error in SetPathInfo (hard link) = %d\n",
3032 cifs_buf_release(pSMB
);
3034 goto createHardLinkRetry
;
3040 CIFSCreateHardLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3041 const char *from_name
, const char *to_name
,
3042 struct cifs_sb_info
*cifs_sb
)
3045 NT_RENAME_REQ
*pSMB
= NULL
;
3046 RENAME_RSP
*pSMBr
= NULL
;
3048 int name_len
, name_len2
;
3050 int remap
= cifs_remap(cifs_sb
);
3052 cifs_dbg(FYI
, "In CIFSCreateHardLink\n");
3053 winCreateHardLinkRetry
:
3055 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
3060 pSMB
->SearchAttributes
=
3061 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
3063 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
3064 pSMB
->ClusterCount
= 0;
3066 pSMB
->BufferFormat
= 0x04;
3068 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3070 cifsConvertToUTF16((__le16
*) pSMB
->OldFileName
, from_name
,
3071 PATH_MAX
, cifs_sb
->local_nls
, remap
);
3072 name_len
++; /* trailing null */
3075 /* protocol specifies ASCII buffer format (0x04) for unicode */
3076 pSMB
->OldFileName
[name_len
] = 0x04;
3077 pSMB
->OldFileName
[name_len
+ 1] = 0x00; /* pad */
3079 cifsConvertToUTF16((__le16
*)&pSMB
->OldFileName
[name_len
+2],
3080 to_name
, PATH_MAX
, cifs_sb
->local_nls
,
3082 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
3083 name_len2
*= 2; /* convert to bytes */
3084 } else { /* BB improve the check for buffer overruns BB */
3085 name_len
= strnlen(from_name
, PATH_MAX
);
3086 name_len
++; /* trailing null */
3087 strncpy(pSMB
->OldFileName
, from_name
, name_len
);
3088 name_len2
= strnlen(to_name
, PATH_MAX
);
3089 name_len2
++; /* trailing null */
3090 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
3091 strncpy(&pSMB
->OldFileName
[name_len
+ 1], to_name
, name_len2
);
3092 name_len2
++; /* trailing null */
3093 name_len2
++; /* signature byte */
3096 count
= 1 /* string type byte */ + name_len
+ name_len2
;
3097 inc_rfc1001_len(pSMB
, count
);
3098 pSMB
->ByteCount
= cpu_to_le16(count
);
3100 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3101 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3102 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_hardlinks
);
3104 cifs_dbg(FYI
, "Send error in hard link (NT rename) = %d\n", rc
);
3106 cifs_buf_release(pSMB
);
3108 goto winCreateHardLinkRetry
;
3114 CIFSSMBUnixQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3115 const unsigned char *searchName
, char **symlinkinfo
,
3116 const struct nls_table
*nls_codepage
, int remap
)
3118 /* SMB_QUERY_FILE_UNIX_LINK */
3119 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3120 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3124 __u16 params
, byte_count
;
3127 cifs_dbg(FYI
, "In QPathSymLinkInfo (Unix) for path %s\n", searchName
);
3130 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3135 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3137 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3138 searchName
, PATH_MAX
, nls_codepage
,
3140 name_len
++; /* trailing null */
3142 } else { /* BB improve the check for buffer overruns BB */
3143 name_len
= strnlen(searchName
, PATH_MAX
);
3144 name_len
++; /* trailing null */
3145 strncpy(pSMB
->FileName
, searchName
, name_len
);
3148 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3149 pSMB
->TotalDataCount
= 0;
3150 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3151 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
3152 pSMB
->MaxSetupCount
= 0;
3156 pSMB
->Reserved2
= 0;
3157 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3158 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
3159 pSMB
->DataCount
= 0;
3160 pSMB
->DataOffset
= 0;
3161 pSMB
->SetupCount
= 1;
3162 pSMB
->Reserved3
= 0;
3163 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3164 byte_count
= params
+ 1 /* pad */ ;
3165 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3166 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3167 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
3168 pSMB
->Reserved4
= 0;
3169 inc_rfc1001_len(pSMB
, byte_count
);
3170 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3172 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3173 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3175 cifs_dbg(FYI
, "Send error in QuerySymLinkInfo = %d\n", rc
);
3177 /* decode response */
3179 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3180 /* BB also check enough total bytes returned */
3181 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3185 u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3187 data_start
= ((char *) &pSMBr
->hdr
.Protocol
) +
3188 le16_to_cpu(pSMBr
->t2
.DataOffset
);
3190 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3195 /* BB FIXME investigate remapping reserved chars here */
3196 *symlinkinfo
= cifs_strndup_from_utf16(data_start
,
3197 count
, is_unicode
, nls_codepage
);
3202 cifs_buf_release(pSMB
);
3204 goto querySymLinkRetry
;
3209 * Recent Windows versions now create symlinks more frequently
3210 * and they use the "reparse point" mechanism below. We can of course
3211 * do symlinks nicely to Samba and other servers which support the
3212 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3213 * "MF" symlinks optionally, but for recent Windows we really need to
3214 * reenable the code below and fix the cifs_symlink callers to handle this.
3215 * In the interim this code has been moved to its own config option so
3216 * it is not compiled in by default until callers fixed up and more tested.
3219 CIFSSMBQuerySymLink(const unsigned int xid
, struct cifs_tcon
*tcon
,
3220 __u16 fid
, char **symlinkinfo
,
3221 const struct nls_table
*nls_codepage
)
3225 struct smb_com_transaction_ioctl_req
*pSMB
;
3226 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3228 unsigned int sub_len
;
3230 struct reparse_symlink_data
*reparse_buf
;
3231 struct reparse_posix_data
*posix_buf
;
3232 __u32 data_offset
, data_count
;
3235 cifs_dbg(FYI
, "In Windows reparse style QueryLink for fid %u\n", fid
);
3236 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3241 pSMB
->TotalParameterCount
= 0 ;
3242 pSMB
->TotalDataCount
= 0;
3243 pSMB
->MaxParameterCount
= cpu_to_le32(2);
3244 /* BB find exact data count max from sess structure BB */
3245 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3246 pSMB
->MaxSetupCount
= 4;
3248 pSMB
->ParameterOffset
= 0;
3249 pSMB
->DataCount
= 0;
3250 pSMB
->DataOffset
= 0;
3251 pSMB
->SetupCount
= 4;
3252 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3253 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3254 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
3255 pSMB
->IsFsctl
= 1; /* FSCTL */
3256 pSMB
->IsRootFlag
= 0;
3257 pSMB
->Fid
= fid
; /* file handle always le */
3258 pSMB
->ByteCount
= 0;
3260 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3261 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3263 cifs_dbg(FYI
, "Send error in QueryReparseLinkInfo = %d\n", rc
);
3267 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3268 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3269 if (get_bcc(&pSMBr
->hdr
) < 2 || data_offset
> 512) {
3270 /* BB also check enough total bytes returned */
3271 rc
= -EIO
; /* bad smb */
3274 if (!data_count
|| (data_count
> 2048)) {
3276 cifs_dbg(FYI
, "Invalid return data count on get reparse info ioctl\n");
3279 end_of_smb
= 2 + get_bcc(&pSMBr
->hdr
) + (char *)&pSMBr
->ByteCount
;
3280 reparse_buf
= (struct reparse_symlink_data
*)
3281 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
3282 if ((char *)reparse_buf
>= end_of_smb
) {
3286 if (reparse_buf
->ReparseTag
== cpu_to_le32(IO_REPARSE_TAG_NFS
)) {
3287 cifs_dbg(FYI
, "NFS style reparse tag\n");
3288 posix_buf
= (struct reparse_posix_data
*)reparse_buf
;
3290 if (posix_buf
->InodeType
!= cpu_to_le64(NFS_SPECFILE_LNK
)) {
3291 cifs_dbg(FYI
, "unsupported file type 0x%llx\n",
3292 le64_to_cpu(posix_buf
->InodeType
));
3297 sub_len
= le16_to_cpu(reparse_buf
->ReparseDataLength
);
3298 if (posix_buf
->PathBuffer
+ sub_len
> end_of_smb
) {
3299 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3303 *symlinkinfo
= cifs_strndup_from_utf16(posix_buf
->PathBuffer
,
3304 sub_len
, is_unicode
, nls_codepage
);
3306 } else if (reparse_buf
->ReparseTag
!=
3307 cpu_to_le32(IO_REPARSE_TAG_SYMLINK
)) {
3312 /* Reparse tag is NTFS symlink */
3313 sub_start
= le16_to_cpu(reparse_buf
->SubstituteNameOffset
) +
3314 reparse_buf
->PathBuffer
;
3315 sub_len
= le16_to_cpu(reparse_buf
->SubstituteNameLength
);
3316 if (sub_start
+ sub_len
> end_of_smb
) {
3317 cifs_dbg(FYI
, "reparse buf beyond SMB\n");
3321 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
3326 /* BB FIXME investigate remapping reserved chars here */
3327 *symlinkinfo
= cifs_strndup_from_utf16(sub_start
, sub_len
, is_unicode
,
3332 cifs_buf_release(pSMB
);
3335 * Note: On -EAGAIN error only caller can retry on handle based calls
3336 * since file handle passed in no longer valid.
3342 CIFSSMB_set_compression(const unsigned int xid
, struct cifs_tcon
*tcon
,
3347 struct smb_com_transaction_compr_ioctl_req
*pSMB
;
3348 struct smb_com_transaction_ioctl_rsp
*pSMBr
;
3350 cifs_dbg(FYI
, "Set compression for %u\n", fid
);
3351 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
3356 pSMB
->compression_state
= cpu_to_le16(COMPRESSION_FORMAT_DEFAULT
);
3358 pSMB
->TotalParameterCount
= 0;
3359 pSMB
->TotalDataCount
= cpu_to_le32(2);
3360 pSMB
->MaxParameterCount
= 0;
3361 pSMB
->MaxDataCount
= 0;
3362 pSMB
->MaxSetupCount
= 4;
3364 pSMB
->ParameterOffset
= 0;
3365 pSMB
->DataCount
= cpu_to_le32(2);
3367 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req
,
3368 compression_state
) - 4); /* 84 */
3369 pSMB
->SetupCount
= 4;
3370 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
3371 pSMB
->ParameterCount
= 0;
3372 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_SET_COMPRESSION
);
3373 pSMB
->IsFsctl
= 1; /* FSCTL */
3374 pSMB
->IsRootFlag
= 0;
3375 pSMB
->Fid
= fid
; /* file handle always le */
3376 /* 3 byte pad, followed by 2 byte compress state */
3377 pSMB
->ByteCount
= cpu_to_le16(5);
3378 inc_rfc1001_len(pSMB
, 5);
3380 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3381 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3383 cifs_dbg(FYI
, "Send error in SetCompression = %d\n", rc
);
3385 cifs_buf_release(pSMB
);
3388 * Note: On -EAGAIN error only caller can retry on handle based calls
3389 * since file handle passed in no longer valid.
3395 #ifdef CONFIG_CIFS_POSIX
3397 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3398 static void cifs_convert_ace(struct posix_acl_xattr_entry
*ace
,
3399 struct cifs_posix_ace
*cifs_ace
)
3401 /* u8 cifs fields do not need le conversion */
3402 ace
->e_perm
= cpu_to_le16(cifs_ace
->cifs_e_perm
);
3403 ace
->e_tag
= cpu_to_le16(cifs_ace
->cifs_e_tag
);
3404 ace
->e_id
= cpu_to_le32(le64_to_cpu(cifs_ace
->cifs_uid
));
3406 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3407 ace->e_perm, ace->e_tag, ace->e_id);
3413 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3414 static int cifs_copy_posix_acl(char *trgt
, char *src
, const int buflen
,
3415 const int acl_type
, const int size_of_data_area
)
3420 struct cifs_posix_ace
*pACE
;
3421 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)src
;
3422 struct posix_acl_xattr_header
*local_acl
= (void *)trgt
;
3424 if (le16_to_cpu(cifs_acl
->version
) != CIFS_ACL_VERSION
)
3427 if (acl_type
== ACL_TYPE_ACCESS
) {
3428 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3429 pACE
= &cifs_acl
->ace_array
[0];
3430 size
= sizeof(struct cifs_posix_acl
);
3431 size
+= sizeof(struct cifs_posix_ace
) * count
;
3432 /* check if we would go beyond end of SMB */
3433 if (size_of_data_area
< size
) {
3434 cifs_dbg(FYI
, "bad CIFS POSIX ACL size %d vs. %d\n",
3435 size_of_data_area
, size
);
3438 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3439 count
= le16_to_cpu(cifs_acl
->access_entry_count
);
3440 size
= sizeof(struct cifs_posix_acl
);
3441 size
+= sizeof(struct cifs_posix_ace
) * count
;
3442 /* skip past access ACEs to get to default ACEs */
3443 pACE
= &cifs_acl
->ace_array
[count
];
3444 count
= le16_to_cpu(cifs_acl
->default_entry_count
);
3445 size
+= sizeof(struct cifs_posix_ace
) * count
;
3446 /* check if we would go beyond end of SMB */
3447 if (size_of_data_area
< size
)
3454 size
= posix_acl_xattr_size(count
);
3455 if ((buflen
== 0) || (local_acl
== NULL
)) {
3456 /* used to query ACL EA size */
3457 } else if (size
> buflen
) {
3459 } else /* buffer big enough */ {
3460 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3462 local_acl
->a_version
= cpu_to_le32(POSIX_ACL_XATTR_VERSION
);
3463 for (i
= 0; i
< count
; i
++) {
3464 cifs_convert_ace(&ace
[i
], pACE
);
3471 static __u16
convert_ace_to_cifs_ace(struct cifs_posix_ace
*cifs_ace
,
3472 const struct posix_acl_xattr_entry
*local_ace
)
3474 __u16 rc
= 0; /* 0 = ACL converted ok */
3476 cifs_ace
->cifs_e_perm
= le16_to_cpu(local_ace
->e_perm
);
3477 cifs_ace
->cifs_e_tag
= le16_to_cpu(local_ace
->e_tag
);
3478 /* BB is there a better way to handle the large uid? */
3479 if (local_ace
->e_id
== cpu_to_le32(-1)) {
3480 /* Probably no need to le convert -1 on any arch but can not hurt */
3481 cifs_ace
->cifs_uid
= cpu_to_le64(-1);
3483 cifs_ace
->cifs_uid
= cpu_to_le64(le32_to_cpu(local_ace
->e_id
));
3485 cifs_dbg(FYI, "perm %d tag %d id %d\n",
3486 ace->e_perm, ace->e_tag, ace->e_id);
3491 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3492 static __u16
ACL_to_cifs_posix(char *parm_data
, const char *pACL
,
3493 const int buflen
, const int acl_type
)
3496 struct cifs_posix_acl
*cifs_acl
= (struct cifs_posix_acl
*)parm_data
;
3497 struct posix_acl_xattr_header
*local_acl
= (void *)pACL
;
3498 struct posix_acl_xattr_entry
*ace
= (void *)(local_acl
+ 1);
3502 if ((buflen
== 0) || (pACL
== NULL
) || (cifs_acl
== NULL
))
3505 count
= posix_acl_xattr_count((size_t)buflen
);
3506 cifs_dbg(FYI
, "setting acl with %d entries from buf of length %d and version of %d\n",
3507 count
, buflen
, le32_to_cpu(local_acl
->a_version
));
3508 if (le32_to_cpu(local_acl
->a_version
) != 2) {
3509 cifs_dbg(FYI
, "unknown POSIX ACL version %d\n",
3510 le32_to_cpu(local_acl
->a_version
));
3513 cifs_acl
->version
= cpu_to_le16(1);
3514 if (acl_type
== ACL_TYPE_ACCESS
) {
3515 cifs_acl
->access_entry_count
= cpu_to_le16(count
);
3516 cifs_acl
->default_entry_count
= cpu_to_le16(0xFFFF);
3517 } else if (acl_type
== ACL_TYPE_DEFAULT
) {
3518 cifs_acl
->default_entry_count
= cpu_to_le16(count
);
3519 cifs_acl
->access_entry_count
= cpu_to_le16(0xFFFF);
3521 cifs_dbg(FYI
, "unknown ACL type %d\n", acl_type
);
3524 for (i
= 0; i
< count
; i
++) {
3525 rc
= convert_ace_to_cifs_ace(&cifs_acl
->ace_array
[i
], &ace
[i
]);
3527 /* ACE not converted */
3532 rc
= (__u16
)(count
* sizeof(struct cifs_posix_ace
));
3533 rc
+= sizeof(struct cifs_posix_acl
);
3534 /* BB add check to make sure ACL does not overflow SMB */
3540 CIFSSMBGetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3541 const unsigned char *searchName
,
3542 char *acl_inf
, const int buflen
, const int acl_type
,
3543 const struct nls_table
*nls_codepage
, int remap
)
3545 /* SMB_QUERY_POSIX_ACL */
3546 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3547 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3551 __u16 params
, byte_count
;
3553 cifs_dbg(FYI
, "In GetPosixACL (Unix) for path %s\n", searchName
);
3556 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3561 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3563 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
3564 searchName
, PATH_MAX
, nls_codepage
,
3566 name_len
++; /* trailing null */
3568 pSMB
->FileName
[name_len
] = 0;
3569 pSMB
->FileName
[name_len
+1] = 0;
3570 } else { /* BB improve the check for buffer overruns BB */
3571 name_len
= strnlen(searchName
, PATH_MAX
);
3572 name_len
++; /* trailing null */
3573 strncpy(pSMB
->FileName
, searchName
, name_len
);
3576 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
3577 pSMB
->TotalDataCount
= 0;
3578 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3579 /* BB find exact max data count below from sess structure BB */
3580 pSMB
->MaxDataCount
= cpu_to_le16(4000);
3581 pSMB
->MaxSetupCount
= 0;
3585 pSMB
->Reserved2
= 0;
3586 pSMB
->ParameterOffset
= cpu_to_le16(
3587 offsetof(struct smb_com_transaction2_qpi_req
,
3588 InformationLevel
) - 4);
3589 pSMB
->DataCount
= 0;
3590 pSMB
->DataOffset
= 0;
3591 pSMB
->SetupCount
= 1;
3592 pSMB
->Reserved3
= 0;
3593 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3594 byte_count
= params
+ 1 /* pad */ ;
3595 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3596 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3597 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_ACL
);
3598 pSMB
->Reserved4
= 0;
3599 inc_rfc1001_len(pSMB
, byte_count
);
3600 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3602 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3603 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3604 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3606 cifs_dbg(FYI
, "Send error in Query POSIX ACL = %d\n", rc
);
3608 /* decode response */
3610 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3611 /* BB also check enough total bytes returned */
3612 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3613 rc
= -EIO
; /* bad smb */
3615 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3616 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3617 rc
= cifs_copy_posix_acl(acl_inf
,
3618 (char *)&pSMBr
->hdr
.Protocol
+data_offset
,
3619 buflen
, acl_type
, count
);
3622 cifs_buf_release(pSMB
);
3629 CIFSSMBSetPosixACL(const unsigned int xid
, struct cifs_tcon
*tcon
,
3630 const unsigned char *fileName
,
3631 const char *local_acl
, const int buflen
,
3633 const struct nls_table
*nls_codepage
, int remap
)
3635 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3636 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3640 int bytes_returned
= 0;
3641 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
3643 cifs_dbg(FYI
, "In SetPosixACL (Unix) for path %s\n", fileName
);
3645 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3649 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3651 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
3652 PATH_MAX
, nls_codepage
, remap
);
3653 name_len
++; /* trailing null */
3655 } else { /* BB improve the check for buffer overruns BB */
3656 name_len
= strnlen(fileName
, PATH_MAX
);
3657 name_len
++; /* trailing null */
3658 strncpy(pSMB
->FileName
, fileName
, name_len
);
3660 params
= 6 + name_len
;
3661 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3662 /* BB find max SMB size from sess */
3663 pSMB
->MaxDataCount
= cpu_to_le16(1000);
3664 pSMB
->MaxSetupCount
= 0;
3668 pSMB
->Reserved2
= 0;
3669 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3670 InformationLevel
) - 4;
3671 offset
= param_offset
+ params
;
3672 parm_data
= ((char *) &pSMB
->hdr
.Protocol
) + offset
;
3673 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3675 /* convert to on the wire format for POSIX ACL */
3676 data_count
= ACL_to_cifs_posix(parm_data
, local_acl
, buflen
, acl_type
);
3678 if (data_count
== 0) {
3680 goto setACLerrorExit
;
3682 pSMB
->DataOffset
= cpu_to_le16(offset
);
3683 pSMB
->SetupCount
= 1;
3684 pSMB
->Reserved3
= 0;
3685 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3686 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_POSIX_ACL
);
3687 byte_count
= 3 /* pad */ + params
+ data_count
;
3688 pSMB
->DataCount
= cpu_to_le16(data_count
);
3689 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3690 pSMB
->ParameterCount
= cpu_to_le16(params
);
3691 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3692 pSMB
->Reserved4
= 0;
3693 inc_rfc1001_len(pSMB
, byte_count
);
3694 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3695 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3696 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3698 cifs_dbg(FYI
, "Set POSIX ACL returned %d\n", rc
);
3701 cifs_buf_release(pSMB
);
3707 /* BB fix tabs in this function FIXME BB */
3709 CIFSGetExtAttr(const unsigned int xid
, struct cifs_tcon
*tcon
,
3710 const int netfid
, __u64
*pExtAttrBits
, __u64
*pMask
)
3713 struct smb_t2_qfi_req
*pSMB
= NULL
;
3714 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
3716 __u16 params
, byte_count
;
3718 cifs_dbg(FYI
, "In GetExtAttr\n");
3723 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3728 params
= 2 /* level */ + 2 /* fid */;
3729 pSMB
->t2
.TotalDataCount
= 0;
3730 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
3731 /* BB find exact max data count below from sess structure BB */
3732 pSMB
->t2
.MaxDataCount
= cpu_to_le16(4000);
3733 pSMB
->t2
.MaxSetupCount
= 0;
3734 pSMB
->t2
.Reserved
= 0;
3736 pSMB
->t2
.Timeout
= 0;
3737 pSMB
->t2
.Reserved2
= 0;
3738 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
3740 pSMB
->t2
.DataCount
= 0;
3741 pSMB
->t2
.DataOffset
= 0;
3742 pSMB
->t2
.SetupCount
= 1;
3743 pSMB
->t2
.Reserved3
= 0;
3744 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
3745 byte_count
= params
+ 1 /* pad */ ;
3746 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
3747 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
3748 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_ATTR_FLAGS
);
3751 inc_rfc1001_len(pSMB
, byte_count
);
3752 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
3754 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3755 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3757 cifs_dbg(FYI
, "error %d in GetExtAttr\n", rc
);
3759 /* decode response */
3760 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
3761 /* BB also check enough total bytes returned */
3762 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
3763 /* If rc should we check for EOPNOSUPP and
3764 disable the srvino flag? or in caller? */
3765 rc
= -EIO
; /* bad smb */
3767 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
3768 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
3769 struct file_chattr_info
*pfinfo
;
3770 /* BB Do we need a cast or hash here ? */
3772 cifs_dbg(FYI
, "Illegal size ret in GetExtAttr\n");
3776 pfinfo
= (struct file_chattr_info
*)
3777 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
3778 *pExtAttrBits
= le64_to_cpu(pfinfo
->mode
);
3779 *pMask
= le64_to_cpu(pfinfo
->mask
);
3783 cifs_buf_release(pSMB
);
3785 goto GetExtAttrRetry
;
3789 #endif /* CONFIG_POSIX */
3791 #ifdef CONFIG_CIFS_ACL
3793 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3794 * all NT TRANSACTS that we init here have total parm and data under about 400
3795 * bytes (to fit in small cifs buffer size), which is the case so far, it
3796 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3797 * returned setup area) and MaxParameterCount (returned parms size) must be set
3801 smb_init_nttransact(const __u16 sub_command
, const int setup_count
,
3802 const int parm_len
, struct cifs_tcon
*tcon
,
3807 struct smb_com_ntransact_req
*pSMB
;
3809 rc
= small_smb_init(SMB_COM_NT_TRANSACT
, 19 + setup_count
, tcon
,
3813 *ret_buf
= (void *)pSMB
;
3815 pSMB
->TotalParameterCount
= cpu_to_le32(parm_len
);
3816 pSMB
->TotalDataCount
= 0;
3817 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
3818 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3819 pSMB
->DataCount
= pSMB
->TotalDataCount
;
3820 temp_offset
= offsetof(struct smb_com_ntransact_req
, Parms
) +
3821 (setup_count
* 2) - 4 /* for rfc1001 length itself */;
3822 pSMB
->ParameterOffset
= cpu_to_le32(temp_offset
);
3823 pSMB
->DataOffset
= cpu_to_le32(temp_offset
+ parm_len
);
3824 pSMB
->SetupCount
= setup_count
; /* no need to le convert byte fields */
3825 pSMB
->SubCommand
= cpu_to_le16(sub_command
);
3830 validate_ntransact(char *buf
, char **ppparm
, char **ppdata
,
3831 __u32
*pparmlen
, __u32
*pdatalen
)
3834 __u32 data_count
, data_offset
, parm_count
, parm_offset
;
3835 struct smb_com_ntransact_rsp
*pSMBr
;
3844 pSMBr
= (struct smb_com_ntransact_rsp
*)buf
;
3846 bcc
= get_bcc(&pSMBr
->hdr
);
3847 end_of_smb
= 2 /* sizeof byte count */ + bcc
+
3848 (char *)&pSMBr
->ByteCount
;
3850 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
3851 data_count
= le32_to_cpu(pSMBr
->DataCount
);
3852 parm_offset
= le32_to_cpu(pSMBr
->ParameterOffset
);
3853 parm_count
= le32_to_cpu(pSMBr
->ParameterCount
);
3855 *ppparm
= (char *)&pSMBr
->hdr
.Protocol
+ parm_offset
;
3856 *ppdata
= (char *)&pSMBr
->hdr
.Protocol
+ data_offset
;
3858 /* should we also check that parm and data areas do not overlap? */
3859 if (*ppparm
> end_of_smb
) {
3860 cifs_dbg(FYI
, "parms start after end of smb\n");
3862 } else if (parm_count
+ *ppparm
> end_of_smb
) {
3863 cifs_dbg(FYI
, "parm end after end of smb\n");
3865 } else if (*ppdata
> end_of_smb
) {
3866 cifs_dbg(FYI
, "data starts after end of smb\n");
3868 } else if (data_count
+ *ppdata
> end_of_smb
) {
3869 cifs_dbg(FYI
, "data %p + count %d (%p) past smb end %p start %p\n",
3870 *ppdata
, data_count
, (data_count
+ *ppdata
),
3873 } else if (parm_count
+ data_count
> bcc
) {
3874 cifs_dbg(FYI
, "parm count and data count larger than SMB\n");
3877 *pdatalen
= data_count
;
3878 *pparmlen
= parm_count
;
3882 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3884 CIFSSMBGetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3885 struct cifs_ntsd
**acl_inf
, __u32
*pbuflen
)
3889 QUERY_SEC_DESC_REQ
*pSMB
;
3891 struct kvec rsp_iov
;
3893 cifs_dbg(FYI
, "GetCifsACL\n");
3898 rc
= smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC
, 0,
3899 8 /* parm len */, tcon
, (void **) &pSMB
);
3903 pSMB
->MaxParameterCount
= cpu_to_le32(4);
3904 /* BB TEST with big acls that might need to be e.g. larger than 16K */
3905 pSMB
->MaxSetupCount
= 0;
3906 pSMB
->Fid
= fid
; /* file handle always le */
3907 pSMB
->AclFlags
= cpu_to_le32(CIFS_ACL_OWNER
| CIFS_ACL_GROUP
|
3909 pSMB
->ByteCount
= cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3910 inc_rfc1001_len(pSMB
, 11);
3911 iov
[0].iov_base
= (char *)pSMB
;
3912 iov
[0].iov_len
= be32_to_cpu(pSMB
->hdr
.smb_buf_length
) + 4;
3914 rc
= SendReceive2(xid
, tcon
->ses
, iov
, 1 /* num iovec */, &buf_type
,
3916 cifs_small_buf_release(pSMB
);
3917 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_acl_get
);
3919 cifs_dbg(FYI
, "Send error in QuerySecDesc = %d\n", rc
);
3920 } else { /* decode response */
3924 struct smb_com_ntransact_rsp
*pSMBr
;
3927 /* validate_nttransact */
3928 rc
= validate_ntransact(rsp_iov
.iov_base
, (char **)&parm
,
3929 &pdata
, &parm_len
, pbuflen
);
3932 pSMBr
= (struct smb_com_ntransact_rsp
*)rsp_iov
.iov_base
;
3934 cifs_dbg(FYI
, "smb %p parm %p data %p\n",
3935 pSMBr
, parm
, *acl_inf
);
3937 if (le32_to_cpu(pSMBr
->ParameterCount
) != 4) {
3938 rc
= -EIO
; /* bad smb */
3943 /* BB check that data area is minimum length and as big as acl_len */
3945 acl_len
= le32_to_cpu(*parm
);
3946 if (acl_len
!= *pbuflen
) {
3947 cifs_dbg(VFS
, "acl length %d does not match %d\n",
3949 if (*pbuflen
> acl_len
)
3953 /* check if buffer is big enough for the acl
3954 header followed by the smallest SID */
3955 if ((*pbuflen
< sizeof(struct cifs_ntsd
) + 8) ||
3956 (*pbuflen
>= 64 * 1024)) {
3957 cifs_dbg(VFS
, "bad acl length %d\n", *pbuflen
);
3961 *acl_inf
= kmemdup(pdata
, *pbuflen
, GFP_KERNEL
);
3962 if (*acl_inf
== NULL
) {
3969 free_rsp_buf(buf_type
, rsp_iov
.iov_base
);
3974 CIFSSMBSetCIFSACL(const unsigned int xid
, struct cifs_tcon
*tcon
, __u16 fid
,
3975 struct cifs_ntsd
*pntsd
, __u32 acllen
, int aclflag
)
3977 __u16 byte_count
, param_count
, data_count
, param_offset
, data_offset
;
3979 int bytes_returned
= 0;
3980 SET_SEC_DESC_REQ
*pSMB
= NULL
;
3984 rc
= smb_init(SMB_COM_NT_TRANSACT
, 19, tcon
, (void **) &pSMB
, &pSMBr
);
3988 pSMB
->MaxSetupCount
= 0;
3992 param_offset
= offsetof(struct smb_com_transaction_ssec_req
, Fid
) - 4;
3993 data_count
= acllen
;
3994 data_offset
= param_offset
+ param_count
;
3995 byte_count
= 3 /* pad */ + param_count
;
3997 pSMB
->DataCount
= cpu_to_le32(data_count
);
3998 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3999 pSMB
->MaxParameterCount
= cpu_to_le32(4);
4000 pSMB
->MaxDataCount
= cpu_to_le32(16384);
4001 pSMB
->ParameterCount
= cpu_to_le32(param_count
);
4002 pSMB
->ParameterOffset
= cpu_to_le32(param_offset
);
4003 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4004 pSMB
->DataOffset
= cpu_to_le32(data_offset
);
4005 pSMB
->SetupCount
= 0;
4006 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC
);
4007 pSMB
->ByteCount
= cpu_to_le16(byte_count
+data_count
);
4009 pSMB
->Fid
= fid
; /* file handle always le */
4010 pSMB
->Reserved2
= 0;
4011 pSMB
->AclFlags
= cpu_to_le32(aclflag
);
4013 if (pntsd
&& acllen
) {
4014 memcpy((char *)pSMBr
+ offsetof(struct smb_hdr
, Protocol
) +
4015 data_offset
, pntsd
, acllen
);
4016 inc_rfc1001_len(pSMB
, byte_count
+ data_count
);
4018 inc_rfc1001_len(pSMB
, byte_count
);
4020 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4021 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4023 cifs_dbg(FYI
, "SetCIFSACL bytes_returned: %d, rc: %d\n",
4024 bytes_returned
, rc
);
4026 cifs_dbg(FYI
, "Set CIFS ACL returned %d\n", rc
);
4027 cifs_buf_release(pSMB
);
4030 goto setCifsAclRetry
;
4035 #endif /* CONFIG_CIFS_ACL */
4037 /* Legacy Query Path Information call for lookup to old servers such
4040 SMBQueryInformation(const unsigned int xid
, struct cifs_tcon
*tcon
,
4041 const char *search_name
, FILE_ALL_INFO
*data
,
4042 const struct nls_table
*nls_codepage
, int remap
)
4044 QUERY_INFORMATION_REQ
*pSMB
;
4045 QUERY_INFORMATION_RSP
*pSMBr
;
4050 cifs_dbg(FYI
, "In SMBQPath path %s\n", search_name
);
4052 rc
= smb_init(SMB_COM_QUERY_INFORMATION
, 0, tcon
, (void **) &pSMB
,
4057 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4059 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4060 search_name
, PATH_MAX
, nls_codepage
,
4062 name_len
++; /* trailing null */
4065 name_len
= strnlen(search_name
, PATH_MAX
);
4066 name_len
++; /* trailing null */
4067 strncpy(pSMB
->FileName
, search_name
, name_len
);
4069 pSMB
->BufferFormat
= 0x04;
4070 name_len
++; /* account for buffer type byte */
4071 inc_rfc1001_len(pSMB
, (__u16
)name_len
);
4072 pSMB
->ByteCount
= cpu_to_le16(name_len
);
4074 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4075 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4077 cifs_dbg(FYI
, "Send error in QueryInfo = %d\n", rc
);
4080 __u32 time
= le32_to_cpu(pSMBr
->last_write_time
);
4082 /* decode response */
4083 /* BB FIXME - add time zone adjustment BB */
4084 memset(data
, 0, sizeof(FILE_ALL_INFO
));
4087 /* decode time fields */
4088 data
->ChangeTime
= cpu_to_le64(cifs_UnixTimeToNT(ts
));
4089 data
->LastWriteTime
= data
->ChangeTime
;
4090 data
->LastAccessTime
= 0;
4091 data
->AllocationSize
=
4092 cpu_to_le64(le32_to_cpu(pSMBr
->size
));
4093 data
->EndOfFile
= data
->AllocationSize
;
4095 cpu_to_le32(le16_to_cpu(pSMBr
->attr
));
4097 rc
= -EIO
; /* bad buffer passed in */
4099 cifs_buf_release(pSMB
);
4108 CIFSSMBQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4109 u16 netfid
, FILE_ALL_INFO
*pFindData
)
4111 struct smb_t2_qfi_req
*pSMB
= NULL
;
4112 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4115 __u16 params
, byte_count
;
4118 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4123 params
= 2 /* level */ + 2 /* fid */;
4124 pSMB
->t2
.TotalDataCount
= 0;
4125 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4126 /* BB find exact max data count below from sess structure BB */
4127 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4128 pSMB
->t2
.MaxSetupCount
= 0;
4129 pSMB
->t2
.Reserved
= 0;
4131 pSMB
->t2
.Timeout
= 0;
4132 pSMB
->t2
.Reserved2
= 0;
4133 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4135 pSMB
->t2
.DataCount
= 0;
4136 pSMB
->t2
.DataOffset
= 0;
4137 pSMB
->t2
.SetupCount
= 1;
4138 pSMB
->t2
.Reserved3
= 0;
4139 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4140 byte_count
= params
+ 1 /* pad */ ;
4141 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4142 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4143 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4146 inc_rfc1001_len(pSMB
, byte_count
);
4147 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4149 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4150 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4152 cifs_dbg(FYI
, "Send error in QFileInfo = %d", rc
);
4153 } else { /* decode response */
4154 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4156 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4158 else if (get_bcc(&pSMBr
->hdr
) < 40)
4159 rc
= -EIO
; /* bad smb */
4160 else if (pFindData
) {
4161 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4162 memcpy((char *) pFindData
,
4163 (char *) &pSMBr
->hdr
.Protocol
+
4164 data_offset
, sizeof(FILE_ALL_INFO
));
4168 cifs_buf_release(pSMB
);
4170 goto QFileInfoRetry
;
4176 CIFSSMBQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4177 const char *search_name
, FILE_ALL_INFO
*data
,
4178 int legacy
/* old style infolevel */,
4179 const struct nls_table
*nls_codepage
, int remap
)
4181 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4182 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4183 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4187 __u16 params
, byte_count
;
4189 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4191 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4196 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4198 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, search_name
,
4199 PATH_MAX
, nls_codepage
, remap
);
4200 name_len
++; /* trailing null */
4202 } else { /* BB improve the check for buffer overruns BB */
4203 name_len
= strnlen(search_name
, PATH_MAX
);
4204 name_len
++; /* trailing null */
4205 strncpy(pSMB
->FileName
, search_name
, name_len
);
4208 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4209 pSMB
->TotalDataCount
= 0;
4210 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4211 /* BB find exact max SMB PDU from sess structure BB */
4212 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4213 pSMB
->MaxSetupCount
= 0;
4217 pSMB
->Reserved2
= 0;
4218 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4219 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4220 pSMB
->DataCount
= 0;
4221 pSMB
->DataOffset
= 0;
4222 pSMB
->SetupCount
= 1;
4223 pSMB
->Reserved3
= 0;
4224 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4225 byte_count
= params
+ 1 /* pad */ ;
4226 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4227 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4229 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
4231 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
4232 pSMB
->Reserved4
= 0;
4233 inc_rfc1001_len(pSMB
, byte_count
);
4234 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4236 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4237 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4239 cifs_dbg(FYI
, "Send error in QPathInfo = %d\n", rc
);
4240 } else { /* decode response */
4241 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4243 if (rc
) /* BB add auto retry on EOPNOTSUPP? */
4245 else if (!legacy
&& get_bcc(&pSMBr
->hdr
) < 40)
4246 rc
= -EIO
; /* bad smb */
4247 else if (legacy
&& get_bcc(&pSMBr
->hdr
) < 24)
4248 rc
= -EIO
; /* 24 or 26 expected but we do not read
4252 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4255 * On legacy responses we do not read the last field,
4256 * EAsize, fortunately since it varies by subdialect and
4257 * also note it differs on Set vs Get, ie two bytes or 4
4258 * bytes depending but we don't care here.
4261 size
= sizeof(FILE_INFO_STANDARD
);
4263 size
= sizeof(FILE_ALL_INFO
);
4264 memcpy((char *) data
, (char *) &pSMBr
->hdr
.Protocol
+
4269 cifs_buf_release(pSMB
);
4271 goto QPathInfoRetry
;
4277 CIFSSMBUnixQFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4278 u16 netfid
, FILE_UNIX_BASIC_INFO
*pFindData
)
4280 struct smb_t2_qfi_req
*pSMB
= NULL
;
4281 struct smb_t2_qfi_rsp
*pSMBr
= NULL
;
4284 __u16 params
, byte_count
;
4287 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4292 params
= 2 /* level */ + 2 /* fid */;
4293 pSMB
->t2
.TotalDataCount
= 0;
4294 pSMB
->t2
.MaxParameterCount
= cpu_to_le16(4);
4295 /* BB find exact max data count below from sess structure BB */
4296 pSMB
->t2
.MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
4297 pSMB
->t2
.MaxSetupCount
= 0;
4298 pSMB
->t2
.Reserved
= 0;
4300 pSMB
->t2
.Timeout
= 0;
4301 pSMB
->t2
.Reserved2
= 0;
4302 pSMB
->t2
.ParameterOffset
= cpu_to_le16(offsetof(struct smb_t2_qfi_req
,
4304 pSMB
->t2
.DataCount
= 0;
4305 pSMB
->t2
.DataOffset
= 0;
4306 pSMB
->t2
.SetupCount
= 1;
4307 pSMB
->t2
.Reserved3
= 0;
4308 pSMB
->t2
.SubCommand
= cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION
);
4309 byte_count
= params
+ 1 /* pad */ ;
4310 pSMB
->t2
.TotalParameterCount
= cpu_to_le16(params
);
4311 pSMB
->t2
.ParameterCount
= pSMB
->t2
.TotalParameterCount
;
4312 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4315 inc_rfc1001_len(pSMB
, byte_count
);
4316 pSMB
->t2
.ByteCount
= cpu_to_le16(byte_count
);
4318 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4319 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4321 cifs_dbg(FYI
, "Send error in UnixQFileInfo = %d", rc
);
4322 } else { /* decode response */
4323 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4325 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4326 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4327 rc
= -EIO
; /* bad smb */
4329 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4330 memcpy((char *) pFindData
,
4331 (char *) &pSMBr
->hdr
.Protocol
+
4333 sizeof(FILE_UNIX_BASIC_INFO
));
4337 cifs_buf_release(pSMB
);
4339 goto UnixQFileInfoRetry
;
4345 CIFSSMBUnixQPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4346 const unsigned char *searchName
,
4347 FILE_UNIX_BASIC_INFO
*pFindData
,
4348 const struct nls_table
*nls_codepage
, int remap
)
4350 /* SMB_QUERY_FILE_UNIX_BASIC */
4351 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4352 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4354 int bytes_returned
= 0;
4356 __u16 params
, byte_count
;
4358 cifs_dbg(FYI
, "In QPathInfo (Unix) the path %s\n", searchName
);
4360 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4365 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4367 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4368 PATH_MAX
, nls_codepage
, remap
);
4369 name_len
++; /* trailing null */
4371 } else { /* BB improve the check for buffer overruns BB */
4372 name_len
= strnlen(searchName
, PATH_MAX
);
4373 name_len
++; /* trailing null */
4374 strncpy(pSMB
->FileName
, searchName
, name_len
);
4377 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */;
4378 pSMB
->TotalDataCount
= 0;
4379 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4380 /* BB find exact max SMB PDU from sess structure BB */
4381 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4382 pSMB
->MaxSetupCount
= 0;
4386 pSMB
->Reserved2
= 0;
4387 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4388 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4389 pSMB
->DataCount
= 0;
4390 pSMB
->DataOffset
= 0;
4391 pSMB
->SetupCount
= 1;
4392 pSMB
->Reserved3
= 0;
4393 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4394 byte_count
= params
+ 1 /* pad */ ;
4395 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4396 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4397 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
4398 pSMB
->Reserved4
= 0;
4399 inc_rfc1001_len(pSMB
, byte_count
);
4400 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4402 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4403 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4405 cifs_dbg(FYI
, "Send error in UnixQPathInfo = %d", rc
);
4406 } else { /* decode response */
4407 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4409 if (rc
|| get_bcc(&pSMBr
->hdr
) < sizeof(FILE_UNIX_BASIC_INFO
)) {
4410 cifs_dbg(VFS
, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4411 rc
= -EIO
; /* bad smb */
4413 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4414 memcpy((char *) pFindData
,
4415 (char *) &pSMBr
->hdr
.Protocol
+
4417 sizeof(FILE_UNIX_BASIC_INFO
));
4420 cifs_buf_release(pSMB
);
4422 goto UnixQPathInfoRetry
;
4427 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4429 CIFSFindFirst(const unsigned int xid
, struct cifs_tcon
*tcon
,
4430 const char *searchName
, struct cifs_sb_info
*cifs_sb
,
4431 __u16
*pnetfid
, __u16 search_flags
,
4432 struct cifs_search_info
*psrch_inf
, bool msearch
)
4434 /* level 257 SMB_ */
4435 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
4436 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
4437 T2_FFIRST_RSP_PARMS
*parms
;
4439 int bytes_returned
= 0;
4440 int name_len
, remap
;
4441 __u16 params
, byte_count
;
4442 struct nls_table
*nls_codepage
;
4444 cifs_dbg(FYI
, "In FindFirst for %s\n", searchName
);
4447 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4452 nls_codepage
= cifs_sb
->local_nls
;
4453 remap
= cifs_remap(cifs_sb
);
4455 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4457 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
4458 PATH_MAX
, nls_codepage
, remap
);
4459 /* We can not add the asterik earlier in case
4460 it got remapped to 0xF03A as if it were part of the
4461 directory name instead of a wildcard */
4464 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4465 pSMB
->FileName
[name_len
+1] = 0;
4466 pSMB
->FileName
[name_len
+2] = '*';
4467 pSMB
->FileName
[name_len
+3] = 0;
4468 name_len
+= 4; /* now the trailing null */
4469 /* null terminate just in case */
4470 pSMB
->FileName
[name_len
] = 0;
4471 pSMB
->FileName
[name_len
+1] = 0;
4474 } else { /* BB add check for overrun of SMB buf BB */
4475 name_len
= strnlen(searchName
, PATH_MAX
);
4476 /* BB fix here and in unicode clause above ie
4477 if (name_len > buffersize-header)
4478 free buffer exit; BB */
4479 strncpy(pSMB
->FileName
, searchName
, name_len
);
4481 pSMB
->FileName
[name_len
] = CIFS_DIR_SEP(cifs_sb
);
4482 pSMB
->FileName
[name_len
+1] = '*';
4483 pSMB
->FileName
[name_len
+2] = 0;
4488 params
= 12 + name_len
/* includes null */ ;
4489 pSMB
->TotalDataCount
= 0; /* no EAs */
4490 pSMB
->MaxParameterCount
= cpu_to_le16(10);
4491 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4492 pSMB
->MaxSetupCount
= 0;
4496 pSMB
->Reserved2
= 0;
4497 byte_count
= params
+ 1 /* pad */ ;
4498 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4499 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4500 pSMB
->ParameterOffset
= cpu_to_le16(
4501 offsetof(struct smb_com_transaction2_ffirst_req
, SearchAttributes
)
4503 pSMB
->DataCount
= 0;
4504 pSMB
->DataOffset
= 0;
4505 pSMB
->SetupCount
= 1; /* one byte, no need to make endian neutral */
4506 pSMB
->Reserved3
= 0;
4507 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
4508 pSMB
->SearchAttributes
=
4509 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
4511 pSMB
->SearchCount
= cpu_to_le16(CIFSMaxBufSize
/sizeof(FILE_UNIX_INFO
));
4512 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4513 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4515 /* BB what should we set StorageType to? Does it matter? BB */
4516 pSMB
->SearchStorageType
= 0;
4517 inc_rfc1001_len(pSMB
, byte_count
);
4518 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4520 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4521 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4522 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_ffirst
);
4524 if (rc
) {/* BB add logic to retry regular search if Unix search
4525 rejected unexpectedly by server */
4526 /* BB Add code to handle unsupported level rc */
4527 cifs_dbg(FYI
, "Error in FindFirst = %d\n", rc
);
4529 cifs_buf_release(pSMB
);
4531 /* BB eventually could optimize out free and realloc of buf */
4534 goto findFirstRetry
;
4535 } else { /* decode response */
4536 /* BB remember to free buffer if error BB */
4537 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4541 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4542 psrch_inf
->unicode
= true;
4544 psrch_inf
->unicode
= false;
4546 psrch_inf
->ntwrk_buf_start
= (char *)pSMBr
;
4547 psrch_inf
->smallBuf
= 0;
4548 psrch_inf
->srch_entries_start
=
4549 (char *) &pSMBr
->hdr
.Protocol
+
4550 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4551 parms
= (T2_FFIRST_RSP_PARMS
*)((char *) &pSMBr
->hdr
.Protocol
+
4552 le16_to_cpu(pSMBr
->t2
.ParameterOffset
));
4554 if (parms
->EndofSearch
)
4555 psrch_inf
->endOfSearch
= true;
4557 psrch_inf
->endOfSearch
= false;
4559 psrch_inf
->entries_in_buffer
=
4560 le16_to_cpu(parms
->SearchCount
);
4561 psrch_inf
->index_of_last_entry
= 2 /* skip . and .. */ +
4562 psrch_inf
->entries_in_buffer
;
4563 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4564 if (CIFSMaxBufSize
< lnoff
) {
4565 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4566 psrch_inf
->last_entry
= NULL
;
4570 psrch_inf
->last_entry
= psrch_inf
->srch_entries_start
+
4574 *pnetfid
= parms
->SearchHandle
;
4576 cifs_buf_release(pSMB
);
4583 int CIFSFindNext(const unsigned int xid
, struct cifs_tcon
*tcon
,
4584 __u16 searchHandle
, __u16 search_flags
,
4585 struct cifs_search_info
*psrch_inf
)
4587 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
4588 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
4589 T2_FNEXT_RSP_PARMS
*parms
;
4590 char *response_data
;
4593 unsigned int name_len
;
4594 __u16 params
, byte_count
;
4596 cifs_dbg(FYI
, "In FindNext\n");
4598 if (psrch_inf
->endOfSearch
)
4601 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4606 params
= 14; /* includes 2 bytes of null string, converted to LE below*/
4608 pSMB
->TotalDataCount
= 0; /* no EAs */
4609 pSMB
->MaxParameterCount
= cpu_to_le16(8);
4610 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
& 0xFFFFFF00);
4611 pSMB
->MaxSetupCount
= 0;
4615 pSMB
->Reserved2
= 0;
4616 pSMB
->ParameterOffset
= cpu_to_le16(
4617 offsetof(struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
4618 pSMB
->DataCount
= 0;
4619 pSMB
->DataOffset
= 0;
4620 pSMB
->SetupCount
= 1;
4621 pSMB
->Reserved3
= 0;
4622 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
4623 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
4625 cpu_to_le16(CIFSMaxBufSize
/ sizeof(FILE_UNIX_INFO
));
4626 pSMB
->InformationLevel
= cpu_to_le16(psrch_inf
->info_level
);
4627 pSMB
->ResumeKey
= psrch_inf
->resume_key
;
4628 pSMB
->SearchFlags
= cpu_to_le16(search_flags
);
4630 name_len
= psrch_inf
->resume_name_len
;
4632 if (name_len
< PATH_MAX
) {
4633 memcpy(pSMB
->ResumeFileName
, psrch_inf
->presume_name
, name_len
);
4634 byte_count
+= name_len
;
4635 /* 14 byte parm len above enough for 2 byte null terminator */
4636 pSMB
->ResumeFileName
[name_len
] = 0;
4637 pSMB
->ResumeFileName
[name_len
+1] = 0;
4640 goto FNext2_err_exit
;
4642 byte_count
= params
+ 1 /* pad */ ;
4643 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4644 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4645 inc_rfc1001_len(pSMB
, byte_count
);
4646 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4648 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4649 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4650 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fnext
);
4653 psrch_inf
->endOfSearch
= true;
4654 cifs_buf_release(pSMB
);
4655 rc
= 0; /* search probably was closed at end of search*/
4657 cifs_dbg(FYI
, "FindNext returned = %d\n", rc
);
4658 } else { /* decode response */
4659 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4664 /* BB fixme add lock for file (srch_info) struct here */
4665 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
4666 psrch_inf
->unicode
= true;
4668 psrch_inf
->unicode
= false;
4669 response_data
= (char *) &pSMBr
->hdr
.Protocol
+
4670 le16_to_cpu(pSMBr
->t2
.ParameterOffset
);
4671 parms
= (T2_FNEXT_RSP_PARMS
*)response_data
;
4672 response_data
= (char *)&pSMBr
->hdr
.Protocol
+
4673 le16_to_cpu(pSMBr
->t2
.DataOffset
);
4674 if (psrch_inf
->smallBuf
)
4675 cifs_small_buf_release(
4676 psrch_inf
->ntwrk_buf_start
);
4678 cifs_buf_release(psrch_inf
->ntwrk_buf_start
);
4679 psrch_inf
->srch_entries_start
= response_data
;
4680 psrch_inf
->ntwrk_buf_start
= (char *)pSMB
;
4681 psrch_inf
->smallBuf
= 0;
4682 if (parms
->EndofSearch
)
4683 psrch_inf
->endOfSearch
= true;
4685 psrch_inf
->endOfSearch
= false;
4686 psrch_inf
->entries_in_buffer
=
4687 le16_to_cpu(parms
->SearchCount
);
4688 psrch_inf
->index_of_last_entry
+=
4689 psrch_inf
->entries_in_buffer
;
4690 lnoff
= le16_to_cpu(parms
->LastNameOffset
);
4691 if (CIFSMaxBufSize
< lnoff
) {
4692 cifs_dbg(VFS
, "ignoring corrupt resume name\n");
4693 psrch_inf
->last_entry
= NULL
;
4696 psrch_inf
->last_entry
=
4697 psrch_inf
->srch_entries_start
+ lnoff
;
4699 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4700 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4702 /* BB fixme add unlock here */
4707 /* BB On error, should we leave previous search buf (and count and
4708 last entry fields) intact or free the previous one? */
4710 /* Note: On -EAGAIN error only caller can retry on handle based calls
4711 since file handle passed in no longer valid */
4714 cifs_buf_release(pSMB
);
4719 CIFSFindClose(const unsigned int xid
, struct cifs_tcon
*tcon
,
4720 const __u16 searchHandle
)
4723 FINDCLOSE_REQ
*pSMB
= NULL
;
4725 cifs_dbg(FYI
, "In CIFSSMBFindClose\n");
4726 rc
= small_smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **)&pSMB
);
4728 /* no sense returning error if session restarted
4729 as file handle has been closed */
4735 pSMB
->FileID
= searchHandle
;
4736 pSMB
->ByteCount
= 0;
4737 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
4738 cifs_small_buf_release(pSMB
);
4740 cifs_dbg(VFS
, "Send error in FindClose = %d\n", rc
);
4742 cifs_stats_inc(&tcon
->stats
.cifs_stats
.num_fclose
);
4744 /* Since session is dead, search handle closed on server already */
4752 CIFSGetSrvInodeNumber(const unsigned int xid
, struct cifs_tcon
*tcon
,
4753 const char *search_name
, __u64
*inode_number
,
4754 const struct nls_table
*nls_codepage
, int remap
)
4757 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
4758 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
4759 int name_len
, bytes_returned
;
4760 __u16 params
, byte_count
;
4762 cifs_dbg(FYI
, "In GetSrvInodeNum for %s\n", search_name
);
4766 GetInodeNumberRetry
:
4767 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4772 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
4774 cifsConvertToUTF16((__le16
*) pSMB
->FileName
,
4775 search_name
, PATH_MAX
, nls_codepage
,
4777 name_len
++; /* trailing null */
4779 } else { /* BB improve the check for buffer overruns BB */
4780 name_len
= strnlen(search_name
, PATH_MAX
);
4781 name_len
++; /* trailing null */
4782 strncpy(pSMB
->FileName
, search_name
, name_len
);
4785 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
4786 pSMB
->TotalDataCount
= 0;
4787 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4788 /* BB find exact max data count below from sess structure BB */
4789 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4790 pSMB
->MaxSetupCount
= 0;
4794 pSMB
->Reserved2
= 0;
4795 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4796 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
4797 pSMB
->DataCount
= 0;
4798 pSMB
->DataOffset
= 0;
4799 pSMB
->SetupCount
= 1;
4800 pSMB
->Reserved3
= 0;
4801 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
4802 byte_count
= params
+ 1 /* pad */ ;
4803 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4804 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4805 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO
);
4806 pSMB
->Reserved4
= 0;
4807 inc_rfc1001_len(pSMB
, byte_count
);
4808 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4810 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
4811 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4813 cifs_dbg(FYI
, "error %d in QueryInternalInfo\n", rc
);
4815 /* decode response */
4816 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4817 /* BB also check enough total bytes returned */
4818 if (rc
|| get_bcc(&pSMBr
->hdr
) < 2)
4819 /* If rc should we check for EOPNOSUPP and
4820 disable the srvino flag? or in caller? */
4821 rc
= -EIO
; /* bad smb */
4823 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
4824 __u16 count
= le16_to_cpu(pSMBr
->t2
.DataCount
);
4825 struct file_internal_info
*pfinfo
;
4826 /* BB Do we need a cast or hash here ? */
4828 cifs_dbg(FYI
, "Illegal size ret in QryIntrnlInf\n");
4830 goto GetInodeNumOut
;
4832 pfinfo
= (struct file_internal_info
*)
4833 (data_offset
+ (char *) &pSMBr
->hdr
.Protocol
);
4834 *inode_number
= le64_to_cpu(pfinfo
->UniqueId
);
4838 cifs_buf_release(pSMB
);
4840 goto GetInodeNumberRetry
;
4845 CIFSGetDFSRefer(const unsigned int xid
, struct cifs_ses
*ses
,
4846 const char *search_name
, struct dfs_info3_param
**target_nodes
,
4847 unsigned int *num_of_nodes
,
4848 const struct nls_table
*nls_codepage
, int remap
)
4850 /* TRANS2_GET_DFS_REFERRAL */
4851 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
4852 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
4856 __u16 params
, byte_count
;
4858 *target_nodes
= NULL
;
4860 cifs_dbg(FYI
, "In GetDFSRefer the path %s\n", search_name
);
4861 if (ses
== NULL
|| ses
->tcon_ipc
== NULL
)
4865 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, ses
->tcon_ipc
, (void **) &pSMB
,
4870 /* server pointer checked in called function,
4871 but should never be null here anyway */
4872 pSMB
->hdr
.Mid
= get_next_mid(ses
->server
);
4873 pSMB
->hdr
.Tid
= ses
->tcon_ipc
->tid
;
4874 pSMB
->hdr
.Uid
= ses
->Suid
;
4875 if (ses
->capabilities
& CAP_STATUS32
)
4876 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
4877 if (ses
->capabilities
& CAP_DFS
)
4878 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
4880 if (ses
->capabilities
& CAP_UNICODE
) {
4881 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
4883 cifsConvertToUTF16((__le16
*) pSMB
->RequestFileName
,
4884 search_name
, PATH_MAX
, nls_codepage
,
4886 name_len
++; /* trailing null */
4888 } else { /* BB improve the check for buffer overruns BB */
4889 name_len
= strnlen(search_name
, PATH_MAX
);
4890 name_len
++; /* trailing null */
4891 strncpy(pSMB
->RequestFileName
, search_name
, name_len
);
4894 if (ses
->server
->sign
)
4895 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
4897 pSMB
->hdr
.Uid
= ses
->Suid
;
4899 params
= 2 /* level */ + name_len
/*includes null */ ;
4900 pSMB
->TotalDataCount
= 0;
4901 pSMB
->DataCount
= 0;
4902 pSMB
->DataOffset
= 0;
4903 pSMB
->MaxParameterCount
= 0;
4904 /* BB find exact max SMB PDU from sess structure BB */
4905 pSMB
->MaxDataCount
= cpu_to_le16(4000);
4906 pSMB
->MaxSetupCount
= 0;
4910 pSMB
->Reserved2
= 0;
4911 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4912 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
4913 pSMB
->SetupCount
= 1;
4914 pSMB
->Reserved3
= 0;
4915 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
4916 byte_count
= params
+ 3 /* pad */ ;
4917 pSMB
->ParameterCount
= cpu_to_le16(params
);
4918 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
4919 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
4920 inc_rfc1001_len(pSMB
, byte_count
);
4921 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4923 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
4924 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
4926 cifs_dbg(FYI
, "Send error in GetDFSRefer = %d\n", rc
);
4929 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
4931 /* BB Also check if enough total bytes returned? */
4932 if (rc
|| get_bcc(&pSMBr
->hdr
) < 17) {
4933 rc
= -EIO
; /* bad smb */
4937 cifs_dbg(FYI
, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
4938 get_bcc(&pSMBr
->hdr
), le16_to_cpu(pSMBr
->t2
.DataOffset
));
4940 /* parse returned result into more usable form */
4941 rc
= parse_dfs_referrals(&pSMBr
->dfs_data
,
4942 le16_to_cpu(pSMBr
->t2
.DataCount
),
4943 num_of_nodes
, target_nodes
, nls_codepage
,
4945 (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) != 0);
4948 cifs_buf_release(pSMB
);
4956 /* Query File System Info such as free space to old servers such as Win 9x */
4958 SMBOldQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
4959 struct kstatfs
*FSData
)
4961 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4962 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
4963 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
4964 FILE_SYSTEM_ALLOC_INFO
*response_data
;
4966 int bytes_returned
= 0;
4967 __u16 params
, byte_count
;
4969 cifs_dbg(FYI
, "OldQFSInfo\n");
4971 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
4976 params
= 2; /* level */
4977 pSMB
->TotalDataCount
= 0;
4978 pSMB
->MaxParameterCount
= cpu_to_le16(2);
4979 pSMB
->MaxDataCount
= cpu_to_le16(1000);
4980 pSMB
->MaxSetupCount
= 0;
4984 pSMB
->Reserved2
= 0;
4985 byte_count
= params
+ 1 /* pad */ ;
4986 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
4987 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
4988 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
4989 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
4990 pSMB
->DataCount
= 0;
4991 pSMB
->DataOffset
= 0;
4992 pSMB
->SetupCount
= 1;
4993 pSMB
->Reserved3
= 0;
4994 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
4995 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_ALLOCATION
);
4996 inc_rfc1001_len(pSMB
, byte_count
);
4997 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
4999 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5000 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5002 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5003 } else { /* decode response */
5004 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5006 if (rc
|| get_bcc(&pSMBr
->hdr
) < 18)
5007 rc
= -EIO
; /* bad smb */
5009 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5010 cifs_dbg(FYI
, "qfsinf resp BCC: %d Offset %d\n",
5011 get_bcc(&pSMBr
->hdr
), data_offset
);
5013 response_data
= (FILE_SYSTEM_ALLOC_INFO
*)
5014 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
5016 le16_to_cpu(response_data
->BytesPerSector
) *
5017 le32_to_cpu(response_data
->
5018 SectorsPerAllocationUnit
);
5020 le32_to_cpu(response_data
->TotalAllocationUnits
);
5021 FSData
->f_bfree
= FSData
->f_bavail
=
5022 le32_to_cpu(response_data
->FreeAllocationUnits
);
5023 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5024 (unsigned long long)FSData
->f_blocks
,
5025 (unsigned long long)FSData
->f_bfree
,
5029 cifs_buf_release(pSMB
);
5032 goto oldQFSInfoRetry
;
5038 CIFSSMBQFSInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5039 struct kstatfs
*FSData
)
5041 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5042 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5043 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5044 FILE_SYSTEM_INFO
*response_data
;
5046 int bytes_returned
= 0;
5047 __u16 params
, byte_count
;
5049 cifs_dbg(FYI
, "In QFSInfo\n");
5051 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5056 params
= 2; /* level */
5057 pSMB
->TotalDataCount
= 0;
5058 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5059 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5060 pSMB
->MaxSetupCount
= 0;
5064 pSMB
->Reserved2
= 0;
5065 byte_count
= params
+ 1 /* pad */ ;
5066 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5067 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5068 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5069 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5070 pSMB
->DataCount
= 0;
5071 pSMB
->DataOffset
= 0;
5072 pSMB
->SetupCount
= 1;
5073 pSMB
->Reserved3
= 0;
5074 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5075 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
5076 inc_rfc1001_len(pSMB
, byte_count
);
5077 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5079 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5080 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5082 cifs_dbg(FYI
, "Send error in QFSInfo = %d\n", rc
);
5083 } else { /* decode response */
5084 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5086 if (rc
|| get_bcc(&pSMBr
->hdr
) < 24)
5087 rc
= -EIO
; /* bad smb */
5089 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5093 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5096 le32_to_cpu(response_data
->BytesPerSector
) *
5097 le32_to_cpu(response_data
->
5098 SectorsPerAllocationUnit
);
5100 le64_to_cpu(response_data
->TotalAllocationUnits
);
5101 FSData
->f_bfree
= FSData
->f_bavail
=
5102 le64_to_cpu(response_data
->FreeAllocationUnits
);
5103 cifs_dbg(FYI
, "Blocks: %lld Free: %lld Block size %ld\n",
5104 (unsigned long long)FSData
->f_blocks
,
5105 (unsigned long long)FSData
->f_bfree
,
5109 cifs_buf_release(pSMB
);
5118 CIFSSMBQFSAttributeInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5120 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
5121 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5122 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5123 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
5125 int bytes_returned
= 0;
5126 __u16 params
, byte_count
;
5128 cifs_dbg(FYI
, "In QFSAttributeInfo\n");
5130 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5135 params
= 2; /* level */
5136 pSMB
->TotalDataCount
= 0;
5137 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5138 /* BB find exact max SMB PDU from sess structure BB */
5139 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5140 pSMB
->MaxSetupCount
= 0;
5144 pSMB
->Reserved2
= 0;
5145 byte_count
= params
+ 1 /* pad */ ;
5146 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5147 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5148 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5149 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5150 pSMB
->DataCount
= 0;
5151 pSMB
->DataOffset
= 0;
5152 pSMB
->SetupCount
= 1;
5153 pSMB
->Reserved3
= 0;
5154 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5155 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
5156 inc_rfc1001_len(pSMB
, byte_count
);
5157 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5159 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5160 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5162 cifs_dbg(VFS
, "Send error in QFSAttributeInfo = %d\n", rc
);
5163 } else { /* decode response */
5164 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5166 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5167 /* BB also check if enough bytes returned */
5168 rc
= -EIO
; /* bad smb */
5170 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5172 (FILE_SYSTEM_ATTRIBUTE_INFO
5173 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5175 memcpy(&tcon
->fsAttrInfo
, response_data
,
5176 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO
));
5179 cifs_buf_release(pSMB
);
5182 goto QFSAttributeRetry
;
5188 CIFSSMBQFSDeviceInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5190 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5191 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5192 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5193 FILE_SYSTEM_DEVICE_INFO
*response_data
;
5195 int bytes_returned
= 0;
5196 __u16 params
, byte_count
;
5198 cifs_dbg(FYI
, "In QFSDeviceInfo\n");
5200 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5205 params
= 2; /* level */
5206 pSMB
->TotalDataCount
= 0;
5207 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5208 /* BB find exact max SMB PDU from sess structure BB */
5209 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5210 pSMB
->MaxSetupCount
= 0;
5214 pSMB
->Reserved2
= 0;
5215 byte_count
= params
+ 1 /* pad */ ;
5216 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
5217 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
5218 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
5219 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5221 pSMB
->DataCount
= 0;
5222 pSMB
->DataOffset
= 0;
5223 pSMB
->SetupCount
= 1;
5224 pSMB
->Reserved3
= 0;
5225 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5226 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
5227 inc_rfc1001_len(pSMB
, byte_count
);
5228 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5230 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5231 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5233 cifs_dbg(FYI
, "Send error in QFSDeviceInfo = %d\n", rc
);
5234 } else { /* decode response */
5235 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5237 if (rc
|| get_bcc(&pSMBr
->hdr
) <
5238 sizeof(FILE_SYSTEM_DEVICE_INFO
))
5239 rc
= -EIO
; /* bad smb */
5241 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5243 (FILE_SYSTEM_DEVICE_INFO
*)
5244 (((char *) &pSMBr
->hdr
.Protocol
) +
5246 memcpy(&tcon
->fsDevInfo
, response_data
,
5247 sizeof(FILE_SYSTEM_DEVICE_INFO
));
5250 cifs_buf_release(pSMB
);
5253 goto QFSDeviceRetry
;
5259 CIFSSMBQFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
)
5261 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
5262 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5263 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5264 FILE_SYSTEM_UNIX_INFO
*response_data
;
5266 int bytes_returned
= 0;
5267 __u16 params
, byte_count
;
5269 cifs_dbg(FYI
, "In QFSUnixInfo\n");
5271 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5272 (void **) &pSMB
, (void **) &pSMBr
);
5276 params
= 2; /* level */
5277 pSMB
->TotalDataCount
= 0;
5278 pSMB
->DataCount
= 0;
5279 pSMB
->DataOffset
= 0;
5280 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5281 /* BB find exact max SMB PDU from sess structure BB */
5282 pSMB
->MaxDataCount
= cpu_to_le16(100);
5283 pSMB
->MaxSetupCount
= 0;
5287 pSMB
->Reserved2
= 0;
5288 byte_count
= params
+ 1 /* pad */ ;
5289 pSMB
->ParameterCount
= cpu_to_le16(params
);
5290 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5291 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5292 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5293 pSMB
->SetupCount
= 1;
5294 pSMB
->Reserved3
= 0;
5295 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5296 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
5297 inc_rfc1001_len(pSMB
, byte_count
);
5298 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5300 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5301 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5303 cifs_dbg(VFS
, "Send error in QFSUnixInfo = %d\n", rc
);
5304 } else { /* decode response */
5305 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5307 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5308 rc
= -EIO
; /* bad smb */
5310 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5312 (FILE_SYSTEM_UNIX_INFO
5313 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5315 memcpy(&tcon
->fsUnixInfo
, response_data
,
5316 sizeof(FILE_SYSTEM_UNIX_INFO
));
5319 cifs_buf_release(pSMB
);
5329 CIFSSMBSetFSUnixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
, __u64 cap
)
5331 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
5332 TRANSACTION2_SETFSI_REQ
*pSMB
= NULL
;
5333 TRANSACTION2_SETFSI_RSP
*pSMBr
= NULL
;
5335 int bytes_returned
= 0;
5336 __u16 params
, param_offset
, offset
, byte_count
;
5338 cifs_dbg(FYI
, "In SETFSUnixInfo\n");
5340 /* BB switch to small buf init to save memory */
5341 rc
= smb_init_no_reconnect(SMB_COM_TRANSACTION2
, 15, tcon
,
5342 (void **) &pSMB
, (void **) &pSMBr
);
5346 params
= 4; /* 2 bytes zero followed by info level. */
5347 pSMB
->MaxSetupCount
= 0;
5351 pSMB
->Reserved2
= 0;
5352 param_offset
= offsetof(struct smb_com_transaction2_setfsi_req
, FileNum
)
5354 offset
= param_offset
+ params
;
5356 pSMB
->MaxParameterCount
= cpu_to_le16(4);
5357 /* BB find exact max SMB PDU from sess structure BB */
5358 pSMB
->MaxDataCount
= cpu_to_le16(100);
5359 pSMB
->SetupCount
= 1;
5360 pSMB
->Reserved3
= 0;
5361 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FS_INFORMATION
);
5362 byte_count
= 1 /* pad */ + params
+ 12;
5364 pSMB
->DataCount
= cpu_to_le16(12);
5365 pSMB
->ParameterCount
= cpu_to_le16(params
);
5366 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5367 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5368 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5369 pSMB
->DataOffset
= cpu_to_le16(offset
);
5373 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_CIFS_UNIX_INFO
);
5376 pSMB
->ClientUnixMajor
= cpu_to_le16(CIFS_UNIX_MAJOR_VERSION
);
5377 pSMB
->ClientUnixMinor
= cpu_to_le16(CIFS_UNIX_MINOR_VERSION
);
5378 pSMB
->ClientUnixCap
= cpu_to_le64(cap
);
5380 inc_rfc1001_len(pSMB
, byte_count
);
5381 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5383 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5384 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5386 cifs_dbg(VFS
, "Send error in SETFSUnixInfo = %d\n", rc
);
5387 } else { /* decode response */
5388 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5390 rc
= -EIO
; /* bad smb */
5392 cifs_buf_release(pSMB
);
5395 goto SETFSUnixRetry
;
5403 CIFSSMBQFSPosixInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5404 struct kstatfs
*FSData
)
5406 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
5407 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
5408 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
5409 FILE_SYSTEM_POSIX_INFO
*response_data
;
5411 int bytes_returned
= 0;
5412 __u16 params
, byte_count
;
5414 cifs_dbg(FYI
, "In QFSPosixInfo\n");
5416 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5421 params
= 2; /* level */
5422 pSMB
->TotalDataCount
= 0;
5423 pSMB
->DataCount
= 0;
5424 pSMB
->DataOffset
= 0;
5425 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5426 /* BB find exact max SMB PDU from sess structure BB */
5427 pSMB
->MaxDataCount
= cpu_to_le16(100);
5428 pSMB
->MaxSetupCount
= 0;
5432 pSMB
->Reserved2
= 0;
5433 byte_count
= params
+ 1 /* pad */ ;
5434 pSMB
->ParameterCount
= cpu_to_le16(params
);
5435 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5436 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
5437 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
5438 pSMB
->SetupCount
= 1;
5439 pSMB
->Reserved3
= 0;
5440 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
5441 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_POSIX_FS_INFO
);
5442 inc_rfc1001_len(pSMB
, byte_count
);
5443 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5445 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5446 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5448 cifs_dbg(FYI
, "Send error in QFSUnixInfo = %d\n", rc
);
5449 } else { /* decode response */
5450 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
5452 if (rc
|| get_bcc(&pSMBr
->hdr
) < 13) {
5453 rc
= -EIO
; /* bad smb */
5455 __u16 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
5457 (FILE_SYSTEM_POSIX_INFO
5458 *) (((char *) &pSMBr
->hdr
.Protocol
) +
5461 le32_to_cpu(response_data
->BlockSize
);
5463 le64_to_cpu(response_data
->TotalBlocks
);
5465 le64_to_cpu(response_data
->BlocksAvail
);
5466 if (response_data
->UserBlocksAvail
== cpu_to_le64(-1)) {
5467 FSData
->f_bavail
= FSData
->f_bfree
;
5470 le64_to_cpu(response_data
->UserBlocksAvail
);
5472 if (response_data
->TotalFileNodes
!= cpu_to_le64(-1))
5474 le64_to_cpu(response_data
->TotalFileNodes
);
5475 if (response_data
->FreeFileNodes
!= cpu_to_le64(-1))
5477 le64_to_cpu(response_data
->FreeFileNodes
);
5480 cifs_buf_release(pSMB
);
5490 * We can not use write of zero bytes trick to set file size due to need for
5491 * large file support. Also note that this SetPathInfo is preferred to
5492 * SetFileInfo based method in next routine which is only needed to work around
5493 * a sharing violation bugin Samba which this routine can run into.
5496 CIFSSMBSetEOF(const unsigned int xid
, struct cifs_tcon
*tcon
,
5497 const char *file_name
, __u64 size
, struct cifs_sb_info
*cifs_sb
,
5498 bool set_allocation
)
5500 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
5501 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
5502 struct file_end_of_file_info
*parm_data
;
5505 int bytes_returned
= 0;
5506 int remap
= cifs_remap(cifs_sb
);
5508 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
5510 cifs_dbg(FYI
, "In SetEOF\n");
5512 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5517 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5519 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
5520 PATH_MAX
, cifs_sb
->local_nls
, remap
);
5521 name_len
++; /* trailing null */
5523 } else { /* BB improve the check for buffer overruns BB */
5524 name_len
= strnlen(file_name
, PATH_MAX
);
5525 name_len
++; /* trailing null */
5526 strncpy(pSMB
->FileName
, file_name
, name_len
);
5528 params
= 6 + name_len
;
5529 data_count
= sizeof(struct file_end_of_file_info
);
5530 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5531 pSMB
->MaxDataCount
= cpu_to_le16(4100);
5532 pSMB
->MaxSetupCount
= 0;
5536 pSMB
->Reserved2
= 0;
5537 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5538 InformationLevel
) - 4;
5539 offset
= param_offset
+ params
;
5540 if (set_allocation
) {
5541 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5542 pSMB
->InformationLevel
=
5543 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5545 pSMB
->InformationLevel
=
5546 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5547 } else /* Set File Size */ {
5548 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5549 pSMB
->InformationLevel
=
5550 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5552 pSMB
->InformationLevel
=
5553 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5557 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
5559 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5560 pSMB
->DataOffset
= cpu_to_le16(offset
);
5561 pSMB
->SetupCount
= 1;
5562 pSMB
->Reserved3
= 0;
5563 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5564 byte_count
= 3 /* pad */ + params
+ data_count
;
5565 pSMB
->DataCount
= cpu_to_le16(data_count
);
5566 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5567 pSMB
->ParameterCount
= cpu_to_le16(params
);
5568 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5569 pSMB
->Reserved4
= 0;
5570 inc_rfc1001_len(pSMB
, byte_count
);
5571 parm_data
->FileSize
= cpu_to_le64(size
);
5572 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5573 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5574 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5576 cifs_dbg(FYI
, "SetPathInfo (file size) returned %d\n", rc
);
5578 cifs_buf_release(pSMB
);
5587 CIFSSMBSetFileSize(const unsigned int xid
, struct cifs_tcon
*tcon
,
5588 struct cifsFileInfo
*cfile
, __u64 size
, bool set_allocation
)
5590 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5591 struct file_end_of_file_info
*parm_data
;
5593 __u16 params
, param_offset
, offset
, byte_count
, count
;
5595 cifs_dbg(FYI
, "SetFileSize (via SetFileInfo) %lld\n",
5597 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5602 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)cfile
->pid
);
5603 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(cfile
->pid
>> 16));
5606 pSMB
->MaxSetupCount
= 0;
5610 pSMB
->Reserved2
= 0;
5611 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5612 offset
= param_offset
+ params
;
5614 count
= sizeof(struct file_end_of_file_info
);
5615 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5616 /* BB find exact max SMB PDU from sess structure BB */
5617 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5618 pSMB
->SetupCount
= 1;
5619 pSMB
->Reserved3
= 0;
5620 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5621 byte_count
= 3 /* pad */ + params
+ count
;
5622 pSMB
->DataCount
= cpu_to_le16(count
);
5623 pSMB
->ParameterCount
= cpu_to_le16(params
);
5624 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5625 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5626 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5628 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
)
5630 pSMB
->DataOffset
= cpu_to_le16(offset
);
5631 parm_data
->FileSize
= cpu_to_le64(size
);
5632 pSMB
->Fid
= cfile
->fid
.netfid
;
5633 if (set_allocation
) {
5634 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5635 pSMB
->InformationLevel
=
5636 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
5638 pSMB
->InformationLevel
=
5639 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
5640 } else /* Set File Size */ {
5641 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5642 pSMB
->InformationLevel
=
5643 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
5645 pSMB
->InformationLevel
=
5646 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
5648 pSMB
->Reserved4
= 0;
5649 inc_rfc1001_len(pSMB
, byte_count
);
5650 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5651 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5652 cifs_small_buf_release(pSMB
);
5654 cifs_dbg(FYI
, "Send error in SetFileInfo (SetFileSize) = %d\n",
5658 /* Note: On -EAGAIN error only caller can retry on handle based calls
5659 since file handle passed in no longer valid */
5664 /* Some legacy servers such as NT4 require that the file times be set on
5665 an open handle, rather than by pathname - this is awkward due to
5666 potential access conflicts on the open, but it is unavoidable for these
5667 old servers since the only other choice is to go from 100 nanosecond DCE
5668 time and resort to the original setpathinfo level which takes the ancient
5669 DOS time format with 2 second granularity */
5671 CIFSSMBSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5672 const FILE_BASIC_INFO
*data
, __u16 fid
, __u32 pid_of_opener
)
5674 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5677 __u16 params
, param_offset
, offset
, byte_count
, count
;
5679 cifs_dbg(FYI
, "Set Times (via SetFileInfo)\n");
5680 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5685 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5686 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5689 pSMB
->MaxSetupCount
= 0;
5693 pSMB
->Reserved2
= 0;
5694 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5695 offset
= param_offset
+ params
;
5697 data_offset
= (char *)pSMB
+
5698 offsetof(struct smb_hdr
, Protocol
) + offset
;
5700 count
= sizeof(FILE_BASIC_INFO
);
5701 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5702 /* BB find max SMB PDU from sess */
5703 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5704 pSMB
->SetupCount
= 1;
5705 pSMB
->Reserved3
= 0;
5706 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5707 byte_count
= 3 /* pad */ + params
+ count
;
5708 pSMB
->DataCount
= cpu_to_le16(count
);
5709 pSMB
->ParameterCount
= cpu_to_le16(params
);
5710 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5711 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5712 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5713 pSMB
->DataOffset
= cpu_to_le16(offset
);
5715 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5716 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5718 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5719 pSMB
->Reserved4
= 0;
5720 inc_rfc1001_len(pSMB
, byte_count
);
5721 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5722 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5723 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5724 cifs_small_buf_release(pSMB
);
5726 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
5729 /* Note: On -EAGAIN error only caller can retry on handle based calls
5730 since file handle passed in no longer valid */
5736 CIFSSMBSetFileDisposition(const unsigned int xid
, struct cifs_tcon
*tcon
,
5737 bool delete_file
, __u16 fid
, __u32 pid_of_opener
)
5739 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5742 __u16 params
, param_offset
, offset
, byte_count
, count
;
5744 cifs_dbg(FYI
, "Set File Disposition (via SetFileInfo)\n");
5745 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5750 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5751 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5754 pSMB
->MaxSetupCount
= 0;
5758 pSMB
->Reserved2
= 0;
5759 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5760 offset
= param_offset
+ params
;
5762 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5765 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5766 /* BB find max SMB PDU from sess */
5767 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5768 pSMB
->SetupCount
= 1;
5769 pSMB
->Reserved3
= 0;
5770 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
5771 byte_count
= 3 /* pad */ + params
+ count
;
5772 pSMB
->DataCount
= cpu_to_le16(count
);
5773 pSMB
->ParameterCount
= cpu_to_le16(params
);
5774 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5775 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5776 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5777 pSMB
->DataOffset
= cpu_to_le16(offset
);
5779 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO
);
5780 pSMB
->Reserved4
= 0;
5781 inc_rfc1001_len(pSMB
, byte_count
);
5782 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5783 *data_offset
= delete_file
? 1 : 0;
5784 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
5785 cifs_small_buf_release(pSMB
);
5787 cifs_dbg(FYI
, "Send error in SetFileDisposition = %d\n", rc
);
5793 CIFSSMBSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5794 const char *fileName
, const FILE_BASIC_INFO
*data
,
5795 const struct nls_table
*nls_codepage
, int remap
)
5797 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
5798 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
5801 int bytes_returned
= 0;
5803 __u16 params
, param_offset
, offset
, byte_count
, count
;
5805 cifs_dbg(FYI
, "In SetTimes\n");
5808 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
5813 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5815 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
5816 PATH_MAX
, nls_codepage
, remap
);
5817 name_len
++; /* trailing null */
5819 } else { /* BB improve the check for buffer overruns BB */
5820 name_len
= strnlen(fileName
, PATH_MAX
);
5821 name_len
++; /* trailing null */
5822 strncpy(pSMB
->FileName
, fileName
, name_len
);
5825 params
= 6 + name_len
;
5826 count
= sizeof(FILE_BASIC_INFO
);
5827 pSMB
->MaxParameterCount
= cpu_to_le16(2);
5828 /* BB find max SMB PDU from sess structure BB */
5829 pSMB
->MaxDataCount
= cpu_to_le16(1000);
5830 pSMB
->MaxSetupCount
= 0;
5834 pSMB
->Reserved2
= 0;
5835 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
5836 InformationLevel
) - 4;
5837 offset
= param_offset
+ params
;
5838 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
5839 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
5840 pSMB
->DataOffset
= cpu_to_le16(offset
);
5841 pSMB
->SetupCount
= 1;
5842 pSMB
->Reserved3
= 0;
5843 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
5844 byte_count
= 3 /* pad */ + params
+ count
;
5846 pSMB
->DataCount
= cpu_to_le16(count
);
5847 pSMB
->ParameterCount
= cpu_to_le16(params
);
5848 pSMB
->TotalDataCount
= pSMB
->DataCount
;
5849 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
5850 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
5851 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
5853 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
5854 pSMB
->Reserved4
= 0;
5855 inc_rfc1001_len(pSMB
, byte_count
);
5856 memcpy(data_offset
, data
, sizeof(FILE_BASIC_INFO
));
5857 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
5858 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5859 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5861 cifs_dbg(FYI
, "SetPathInfo (times) returned %d\n", rc
);
5863 cifs_buf_release(pSMB
);
5871 /* Can not be used to set time stamps yet (due to old DOS time format) */
5872 /* Can be used to set attributes */
5873 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
5874 handling it anyway and NT4 was what we thought it would be needed for
5875 Do not delete it until we prove whether needed for Win9x though */
5877 CIFSSMBSetAttrLegacy(unsigned int xid
, struct cifs_tcon
*tcon
, char *fileName
,
5878 __u16 dos_attrs
, const struct nls_table
*nls_codepage
)
5880 SETATTR_REQ
*pSMB
= NULL
;
5881 SETATTR_RSP
*pSMBr
= NULL
;
5886 cifs_dbg(FYI
, "In SetAttrLegacy\n");
5889 rc
= smb_init(SMB_COM_SETATTR
, 8, tcon
, (void **) &pSMB
,
5894 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
5896 ConvertToUTF16((__le16
*) pSMB
->fileName
, fileName
,
5897 PATH_MAX
, nls_codepage
);
5898 name_len
++; /* trailing null */
5900 } else { /* BB improve the check for buffer overruns BB */
5901 name_len
= strnlen(fileName
, PATH_MAX
);
5902 name_len
++; /* trailing null */
5903 strncpy(pSMB
->fileName
, fileName
, name_len
);
5905 pSMB
->attr
= cpu_to_le16(dos_attrs
);
5906 pSMB
->BufferFormat
= 0x04;
5907 inc_rfc1001_len(pSMB
, name_len
+ 1);
5908 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
5909 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
5910 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
5912 cifs_dbg(FYI
, "Error in LegacySetAttr = %d\n", rc
);
5914 cifs_buf_release(pSMB
);
5917 goto SetAttrLgcyRetry
;
5921 #endif /* temporarily unneeded SetAttr legacy function */
5924 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO
*data_offset
,
5925 const struct cifs_unix_set_info_args
*args
)
5927 u64 uid
= NO_CHANGE_64
, gid
= NO_CHANGE_64
;
5928 u64 mode
= args
->mode
;
5930 if (uid_valid(args
->uid
))
5931 uid
= from_kuid(&init_user_ns
, args
->uid
);
5932 if (gid_valid(args
->gid
))
5933 gid
= from_kgid(&init_user_ns
, args
->gid
);
5936 * Samba server ignores set of file size to zero due to bugs in some
5937 * older clients, but we should be precise - we use SetFileSize to
5938 * set file size and do not want to truncate file size to zero
5939 * accidentally as happened on one Samba server beta by putting
5940 * zero instead of -1 here
5942 data_offset
->EndOfFile
= cpu_to_le64(NO_CHANGE_64
);
5943 data_offset
->NumOfBytes
= cpu_to_le64(NO_CHANGE_64
);
5944 data_offset
->LastStatusChange
= cpu_to_le64(args
->ctime
);
5945 data_offset
->LastAccessTime
= cpu_to_le64(args
->atime
);
5946 data_offset
->LastModificationTime
= cpu_to_le64(args
->mtime
);
5947 data_offset
->Uid
= cpu_to_le64(uid
);
5948 data_offset
->Gid
= cpu_to_le64(gid
);
5949 /* better to leave device as zero when it is */
5950 data_offset
->DevMajor
= cpu_to_le64(MAJOR(args
->device
));
5951 data_offset
->DevMinor
= cpu_to_le64(MINOR(args
->device
));
5952 data_offset
->Permissions
= cpu_to_le64(mode
);
5955 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
5956 else if (S_ISDIR(mode
))
5957 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
5958 else if (S_ISLNK(mode
))
5959 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
5960 else if (S_ISCHR(mode
))
5961 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
5962 else if (S_ISBLK(mode
))
5963 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
5964 else if (S_ISFIFO(mode
))
5965 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
5966 else if (S_ISSOCK(mode
))
5967 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
5971 CIFSSMBUnixSetFileInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
5972 const struct cifs_unix_set_info_args
*args
,
5973 u16 fid
, u32 pid_of_opener
)
5975 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
5978 u16 params
, param_offset
, offset
, byte_count
, count
;
5980 cifs_dbg(FYI
, "Set Unix Info (via SetFileInfo)\n");
5981 rc
= small_smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
);
5986 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
5987 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
5990 pSMB
->MaxSetupCount
= 0;
5994 pSMB
->Reserved2
= 0;
5995 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
5996 offset
= param_offset
+ params
;
5998 data_offset
= (char *)pSMB
+
5999 offsetof(struct smb_hdr
, Protocol
) + offset
;
6001 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6003 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6004 /* BB find max SMB PDU from sess */
6005 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6006 pSMB
->SetupCount
= 1;
6007 pSMB
->Reserved3
= 0;
6008 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
6009 byte_count
= 3 /* pad */ + params
+ count
;
6010 pSMB
->DataCount
= cpu_to_le16(count
);
6011 pSMB
->ParameterCount
= cpu_to_le16(params
);
6012 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6013 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6014 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6015 pSMB
->DataOffset
= cpu_to_le16(offset
);
6017 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6018 pSMB
->Reserved4
= 0;
6019 inc_rfc1001_len(pSMB
, byte_count
);
6020 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6022 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO
*)data_offset
, args
);
6024 rc
= SendReceiveNoRsp(xid
, tcon
->ses
, (char *) pSMB
, 0);
6025 cifs_small_buf_release(pSMB
);
6027 cifs_dbg(FYI
, "Send error in Set Time (SetFileInfo) = %d\n",
6030 /* Note: On -EAGAIN error only caller can retry on handle based calls
6031 since file handle passed in no longer valid */
6037 CIFSSMBUnixSetPathInfo(const unsigned int xid
, struct cifs_tcon
*tcon
,
6038 const char *file_name
,
6039 const struct cifs_unix_set_info_args
*args
,
6040 const struct nls_table
*nls_codepage
, int remap
)
6042 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
6043 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
6046 int bytes_returned
= 0;
6047 FILE_UNIX_BASIC_INFO
*data_offset
;
6048 __u16 params
, param_offset
, offset
, count
, byte_count
;
6050 cifs_dbg(FYI
, "In SetUID/GID/Mode\n");
6052 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6057 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6059 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, file_name
,
6060 PATH_MAX
, nls_codepage
, remap
);
6061 name_len
++; /* trailing null */
6063 } else { /* BB improve the check for buffer overruns BB */
6064 name_len
= strnlen(file_name
, PATH_MAX
);
6065 name_len
++; /* trailing null */
6066 strncpy(pSMB
->FileName
, file_name
, name_len
);
6069 params
= 6 + name_len
;
6070 count
= sizeof(FILE_UNIX_BASIC_INFO
);
6071 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6072 /* BB find max SMB PDU from sess structure BB */
6073 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6074 pSMB
->MaxSetupCount
= 0;
6078 pSMB
->Reserved2
= 0;
6079 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6080 InformationLevel
) - 4;
6081 offset
= param_offset
+ params
;
6083 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
6085 memset(data_offset
, 0, count
);
6086 pSMB
->DataOffset
= cpu_to_le16(offset
);
6087 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6088 pSMB
->SetupCount
= 1;
6089 pSMB
->Reserved3
= 0;
6090 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6091 byte_count
= 3 /* pad */ + params
+ count
;
6092 pSMB
->ParameterCount
= cpu_to_le16(params
);
6093 pSMB
->DataCount
= cpu_to_le16(count
);
6094 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6095 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6096 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
6097 pSMB
->Reserved4
= 0;
6098 inc_rfc1001_len(pSMB
, byte_count
);
6100 cifs_fill_unix_set_info(data_offset
, args
);
6102 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6103 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6104 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6106 cifs_dbg(FYI
, "SetPathInfo (perms) returned %d\n", rc
);
6108 cifs_buf_release(pSMB
);
6114 #ifdef CONFIG_CIFS_XATTR
6116 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6117 * function used by listxattr and getxattr type calls. When ea_name is set,
6118 * it looks for that attribute name and stuffs that value into the EAData
6119 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6120 * buffer. In both cases, the return value is either the length of the
6121 * resulting data or a negative error code. If EAData is a NULL pointer then
6122 * the data isn't copied to it, but the length is returned.
6125 CIFSSMBQAllEAs(const unsigned int xid
, struct cifs_tcon
*tcon
,
6126 const unsigned char *searchName
, const unsigned char *ea_name
,
6127 char *EAData
, size_t buf_size
,
6128 struct cifs_sb_info
*cifs_sb
)
6130 /* BB assumes one setup word */
6131 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
6132 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
6133 int remap
= cifs_remap(cifs_sb
);
6134 struct nls_table
*nls_codepage
= cifs_sb
->local_nls
;
6138 struct fealist
*ea_response_data
;
6139 struct fea
*temp_fea
;
6142 __u16 params
, byte_count
, data_offset
;
6143 unsigned int ea_name_len
= ea_name
? strlen(ea_name
) : 0;
6145 cifs_dbg(FYI
, "In Query All EAs path %s\n", searchName
);
6147 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6152 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6154 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, searchName
,
6155 PATH_MAX
, nls_codepage
, remap
);
6156 list_len
++; /* trailing null */
6158 } else { /* BB improve the check for buffer overruns BB */
6159 list_len
= strnlen(searchName
, PATH_MAX
);
6160 list_len
++; /* trailing null */
6161 strncpy(pSMB
->FileName
, searchName
, list_len
);
6164 params
= 2 /* level */ + 4 /* reserved */ + list_len
/* includes NUL */;
6165 pSMB
->TotalDataCount
= 0;
6166 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6167 /* BB find exact max SMB PDU from sess structure BB */
6168 pSMB
->MaxDataCount
= cpu_to_le16(CIFSMaxBufSize
);
6169 pSMB
->MaxSetupCount
= 0;
6173 pSMB
->Reserved2
= 0;
6174 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
6175 struct smb_com_transaction2_qpi_req
, InformationLevel
) - 4);
6176 pSMB
->DataCount
= 0;
6177 pSMB
->DataOffset
= 0;
6178 pSMB
->SetupCount
= 1;
6179 pSMB
->Reserved3
= 0;
6180 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
6181 byte_count
= params
+ 1 /* pad */ ;
6182 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
6183 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6184 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
6185 pSMB
->Reserved4
= 0;
6186 inc_rfc1001_len(pSMB
, byte_count
);
6187 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6189 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6190 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6192 cifs_dbg(FYI
, "Send error in QueryAllEAs = %d\n", rc
);
6197 /* BB also check enough total bytes returned */
6198 /* BB we need to improve the validity checking
6199 of these trans2 responses */
6201 rc
= validate_t2((struct smb_t2_rsp
*)pSMBr
);
6202 if (rc
|| get_bcc(&pSMBr
->hdr
) < 4) {
6203 rc
= -EIO
; /* bad smb */
6207 /* check that length of list is not more than bcc */
6208 /* check that each entry does not go beyond length
6210 /* check that each element of each entry does not
6211 go beyond end of list */
6212 /* validate_trans2_offsets() */
6213 /* BB check if start of smb + data_offset > &bcc+ bcc */
6215 data_offset
= le16_to_cpu(pSMBr
->t2
.DataOffset
);
6216 ea_response_data
= (struct fealist
*)
6217 (((char *) &pSMBr
->hdr
.Protocol
) + data_offset
);
6219 list_len
= le32_to_cpu(ea_response_data
->list_len
);
6220 cifs_dbg(FYI
, "ea length %d\n", list_len
);
6221 if (list_len
<= 8) {
6222 cifs_dbg(FYI
, "empty EA list returned from server\n");
6223 /* didn't find the named attribute */
6229 /* make sure list_len doesn't go past end of SMB */
6230 end_of_smb
= (char *)pByteArea(&pSMBr
->hdr
) + get_bcc(&pSMBr
->hdr
);
6231 if ((char *)ea_response_data
+ list_len
> end_of_smb
) {
6232 cifs_dbg(FYI
, "EA list appears to go beyond SMB\n");
6237 /* account for ea list len */
6239 temp_fea
= ea_response_data
->list
;
6240 temp_ptr
= (char *)temp_fea
;
6241 while (list_len
> 0) {
6242 unsigned int name_len
;
6247 /* make sure we can read name_len and value_len */
6249 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6254 name_len
= temp_fea
->name_len
;
6255 value_len
= le16_to_cpu(temp_fea
->value_len
);
6256 list_len
-= name_len
+ 1 + value_len
;
6258 cifs_dbg(FYI
, "EA entry goes beyond length of list\n");
6264 if (ea_name_len
== name_len
&&
6265 memcmp(ea_name
, temp_ptr
, name_len
) == 0) {
6266 temp_ptr
+= name_len
+ 1;
6270 if ((size_t)value_len
> buf_size
) {
6274 memcpy(EAData
, temp_ptr
, value_len
);
6278 /* account for prefix user. and trailing null */
6279 rc
+= (5 + 1 + name_len
);
6280 if (rc
< (int) buf_size
) {
6281 memcpy(EAData
, "user.", 5);
6283 memcpy(EAData
, temp_ptr
, name_len
);
6285 /* null terminate name */
6288 } else if (buf_size
== 0) {
6289 /* skip copy - calc size only */
6291 /* stop before overrun buffer */
6296 temp_ptr
+= name_len
+ 1 + value_len
;
6297 temp_fea
= (struct fea
*)temp_ptr
;
6300 /* didn't find the named attribute */
6305 cifs_buf_release(pSMB
);
6313 CIFSSMBSetEA(const unsigned int xid
, struct cifs_tcon
*tcon
,
6314 const char *fileName
, const char *ea_name
, const void *ea_value
,
6315 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
,
6316 struct cifs_sb_info
*cifs_sb
)
6318 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
6319 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
6320 struct fealist
*parm_data
;
6323 int bytes_returned
= 0;
6324 __u16 params
, param_offset
, byte_count
, offset
, count
;
6325 int remap
= cifs_remap(cifs_sb
);
6327 cifs_dbg(FYI
, "In SetEA\n");
6329 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
6334 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
6336 cifsConvertToUTF16((__le16
*) pSMB
->FileName
, fileName
,
6337 PATH_MAX
, nls_codepage
, remap
);
6338 name_len
++; /* trailing null */
6340 } else { /* BB improve the check for buffer overruns BB */
6341 name_len
= strnlen(fileName
, PATH_MAX
);
6342 name_len
++; /* trailing null */
6343 strncpy(pSMB
->FileName
, fileName
, name_len
);
6346 params
= 6 + name_len
;
6348 /* done calculating parms using name_len of file name,
6349 now use name_len to calculate length of ea name
6350 we are going to create in the inode xattrs */
6351 if (ea_name
== NULL
)
6354 name_len
= strnlen(ea_name
, 255);
6356 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
;
6357 pSMB
->MaxParameterCount
= cpu_to_le16(2);
6358 /* BB find max SMB PDU from sess */
6359 pSMB
->MaxDataCount
= cpu_to_le16(1000);
6360 pSMB
->MaxSetupCount
= 0;
6364 pSMB
->Reserved2
= 0;
6365 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
6366 InformationLevel
) - 4;
6367 offset
= param_offset
+ params
;
6368 pSMB
->InformationLevel
=
6369 cpu_to_le16(SMB_SET_FILE_EA
);
6371 parm_data
= (void *)pSMB
+ offsetof(struct smb_hdr
, Protocol
) + offset
;
6372 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
6373 pSMB
->DataOffset
= cpu_to_le16(offset
);
6374 pSMB
->SetupCount
= 1;
6375 pSMB
->Reserved3
= 0;
6376 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
6377 byte_count
= 3 /* pad */ + params
+ count
;
6378 pSMB
->DataCount
= cpu_to_le16(count
);
6379 parm_data
->list_len
= cpu_to_le32(count
);
6380 parm_data
->list
[0].EA_flags
= 0;
6381 /* we checked above that name len is less than 255 */
6382 parm_data
->list
[0].name_len
= (__u8
)name_len
;
6383 /* EA names are always ASCII */
6385 strncpy(parm_data
->list
[0].name
, ea_name
, name_len
);
6386 parm_data
->list
[0].name
[name_len
] = 0;
6387 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
6388 /* caller ensures that ea_value_len is less than 64K but
6389 we need to ensure that it fits within the smb */
6391 /*BB add length check to see if it would fit in
6392 negotiated SMB buffer size BB */
6393 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6395 memcpy(parm_data
->list
[0].name
+name_len
+1,
6396 ea_value
, ea_value_len
);
6398 pSMB
->TotalDataCount
= pSMB
->DataCount
;
6399 pSMB
->ParameterCount
= cpu_to_le16(params
);
6400 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
6401 pSMB
->Reserved4
= 0;
6402 inc_rfc1001_len(pSMB
, byte_count
);
6403 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
6404 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6405 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
6407 cifs_dbg(FYI
, "SetPathInfo (EA) returned %d\n", rc
);
6409 cifs_buf_release(pSMB
);
6418 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6420 * Years ago the kernel added a "dnotify" function for Samba server,
6421 * to allow network clients (such as Windows) to display updated
6422 * lists of files in directory listings automatically when
6423 * files are added by one user when another user has the
6424 * same directory open on their desktop. The Linux cifs kernel
6425 * client hooked into the kernel side of this interface for
6426 * the same reason, but ironically when the VFS moved from
6427 * "dnotify" to "inotify" it became harder to plug in Linux
6428 * network file system clients (the most obvious use case
6429 * for notify interfaces is when multiple users can update
6430 * the contents of the same directory - exactly what network
6431 * file systems can do) although the server (Samba) could
6432 * still use it. For the short term we leave the worker
6433 * function ifdeffed out (below) until inotify is fixed
6434 * in the VFS to make it easier to plug in network file
6435 * system clients. If inotify turns out to be permanently
6436 * incompatible for network fs clients, we could instead simply
6437 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
6439 int CIFSSMBNotify(const unsigned int xid
, struct cifs_tcon
*tcon
,
6440 const int notify_subdirs
, const __u16 netfid
,
6441 __u32 filter
, struct file
*pfile
, int multishot
,
6442 const struct nls_table
*nls_codepage
)
6445 struct smb_com_transaction_change_notify_req
*pSMB
= NULL
;
6446 struct smb_com_ntransaction_change_notify_rsp
*pSMBr
= NULL
;
6447 struct dir_notify_req
*dnotify_req
;
6450 cifs_dbg(FYI
, "In CIFSSMBNotify for file handle %d\n", (int)netfid
);
6451 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
6456 pSMB
->TotalParameterCount
= 0 ;
6457 pSMB
->TotalDataCount
= 0;
6458 pSMB
->MaxParameterCount
= cpu_to_le32(2);
6459 pSMB
->MaxDataCount
= cpu_to_le32(CIFSMaxBufSize
& 0xFFFFFF00);
6460 pSMB
->MaxSetupCount
= 4;
6462 pSMB
->ParameterOffset
= 0;
6463 pSMB
->DataCount
= 0;
6464 pSMB
->DataOffset
= 0;
6465 pSMB
->SetupCount
= 4; /* single byte does not need le conversion */
6466 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE
);
6467 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
6469 pSMB
->WatchTree
= 1; /* one byte - no le conversion needed */
6470 pSMB
->Reserved2
= 0;
6471 pSMB
->CompletionFilter
= cpu_to_le32(filter
);
6472 pSMB
->Fid
= netfid
; /* file handle always le */
6473 pSMB
->ByteCount
= 0;
6475 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
6476 (struct smb_hdr
*)pSMBr
, &bytes_returned
,
6479 cifs_dbg(FYI
, "Error in Notify = %d\n", rc
);
6481 /* Add file to outstanding requests */
6482 /* BB change to kmem cache alloc */
6483 dnotify_req
= kmalloc(
6484 sizeof(struct dir_notify_req
),
6487 dnotify_req
->Pid
= pSMB
->hdr
.Pid
;
6488 dnotify_req
->PidHigh
= pSMB
->hdr
.PidHigh
;
6489 dnotify_req
->Mid
= pSMB
->hdr
.Mid
;
6490 dnotify_req
->Tid
= pSMB
->hdr
.Tid
;
6491 dnotify_req
->Uid
= pSMB
->hdr
.Uid
;
6492 dnotify_req
->netfid
= netfid
;
6493 dnotify_req
->pfile
= pfile
;
6494 dnotify_req
->filter
= filter
;
6495 dnotify_req
->multishot
= multishot
;
6496 spin_lock(&GlobalMid_Lock
);
6497 list_add_tail(&dnotify_req
->lhead
,
6498 &GlobalDnotifyReqList
);
6499 spin_unlock(&GlobalMid_Lock
);
6503 cifs_buf_release(pSMB
);
6506 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */