Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
bf67b9be
Commit
bf67b9be
authored
Jan 21, 2011
by
Steve French
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-next'
parents
8d99641f
84cdf74e
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
402 additions
and
237 deletions
+402
-237
fs/cifs/cifs_fs_sb.h
fs/cifs/cifs_fs_sb.h
+1
-0
fs/cifs/cifs_unicode.c
fs/cifs/cifs_unicode.c
+104
-23
fs/cifs/cifsfs.c
fs/cifs/cifsfs.c
+38
-0
fs/cifs/cifsfs.h
fs/cifs/cifsfs.h
+10
-3
fs/cifs/cifsglob.h
fs/cifs/cifsglob.h
+14
-22
fs/cifs/cifspdu.h
fs/cifs/cifspdu.h
+43
-4
fs/cifs/cifssmb.c
fs/cifs/cifssmb.c
+25
-29
fs/cifs/connect.c
fs/cifs/connect.c
+19
-24
fs/cifs/file.c
fs/cifs/file.c
+130
-45
fs/cifs/inode.c
fs/cifs/inode.c
+6
-2
fs/cifs/misc.c
fs/cifs/misc.c
+0
-71
fs/cifs/netmisc.c
fs/cifs/netmisc.c
+2
-2
fs/cifs/sess.c
fs/cifs/sess.c
+6
-7
fs/cifs/transport.c
fs/cifs/transport.c
+4
-5
No files found.
fs/cifs/cifs_fs_sb.h
View file @
bf67b9be
...
...
@@ -40,6 +40,7 @@
#define CIFS_MOUNT_FSCACHE 0x8000
/* local caching enabled */
#define CIFS_MOUNT_MF_SYMLINKS 0x10000
/* Minshall+French Symlinks enabled */
#define CIFS_MOUNT_MULTIUSER 0x20000
/* multiuser mount */
#define CIFS_MOUNT_STRICT_IO 0x40000
/* strict cache mode */
struct
cifs_sb_info
{
struct
rb_root
tlink_tree
;
...
...
fs/cifs/cifs_unicode.c
View file @
bf67b9be
...
...
@@ -44,10 +44,14 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes,
int
charlen
,
outlen
=
0
;
int
maxwords
=
maxbytes
/
2
;
char
tmp
[
NLS_MAX_CHARSET_SIZE
];
__u16
ftmp
;
for
(
i
=
0
;
i
<
maxwords
&&
from
[
i
];
i
++
)
{
charlen
=
codepage
->
uni2char
(
le16_to_cpu
(
from
[
i
]),
tmp
,
NLS_MAX_CHARSET_SIZE
);
for
(
i
=
0
;
i
<
maxwords
;
i
++
)
{
ftmp
=
get_unaligned_le16
(
&
from
[
i
]);
if
(
ftmp
==
0
)
break
;
charlen
=
codepage
->
uni2char
(
ftmp
,
tmp
,
NLS_MAX_CHARSET_SIZE
);
if
(
charlen
>
0
)
outlen
+=
charlen
;
else
...
...
@@ -58,9 +62,9 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes,
}
/*
* cifs_mapchar - convert a
little
-endian char to proper char in codepage
* cifs_mapchar - convert a
host
-endian char to proper char in codepage
* @target - where converted character should be copied
* @src_char - 2 byte
little
-endian source character
* @src_char - 2 byte
host
-endian source character
* @cp - codepage to which character should be converted
* @mapchar - should character be mapped according to mapchars mount option?
*
...
...
@@ -69,7 +73,7 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes,
* enough to hold the result of the conversion (at least NLS_MAX_CHARSET_SIZE).
*/
static
int
cifs_mapchar
(
char
*
target
,
const
__
le
16
src_char
,
const
struct
nls_table
*
cp
,
cifs_mapchar
(
char
*
target
,
const
__
u
16
src_char
,
const
struct
nls_table
*
cp
,
bool
mapchar
)
{
int
len
=
1
;
...
...
@@ -82,7 +86,7 @@ cifs_mapchar(char *target, const __le16 src_char, const struct nls_table *cp,
* build_path_from_dentry are modified, as they use slash as
* separator.
*/
switch
(
le16_to_cpu
(
src_char
)
)
{
switch
(
src_char
)
{
case
UNI_COLON
:
*
target
=
':'
;
break
;
...
...
@@ -109,8 +113,7 @@ cifs_mapchar(char *target, const __le16 src_char, const struct nls_table *cp,
return
len
;
cp_convert:
len
=
cp
->
uni2char
(
le16_to_cpu
(
src_char
),
target
,
NLS_MAX_CHARSET_SIZE
);
len
=
cp
->
uni2char
(
src_char
,
target
,
NLS_MAX_CHARSET_SIZE
);
if
(
len
<=
0
)
{
*
target
=
'?'
;
len
=
1
;
...
...
@@ -149,6 +152,7 @@ cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
int
nullsize
=
nls_nullsize
(
codepage
);
int
fromwords
=
fromlen
/
2
;
char
tmp
[
NLS_MAX_CHARSET_SIZE
];
__u16
ftmp
;
/*
* because the chars can be of varying widths, we need to take care
...
...
@@ -158,19 +162,23 @@ cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
*/
safelen
=
tolen
-
(
NLS_MAX_CHARSET_SIZE
+
nullsize
);
for
(
i
=
0
;
i
<
fromwords
&&
from
[
i
];
i
++
)
{
for
(
i
=
0
;
i
<
fromwords
;
i
++
)
{
ftmp
=
get_unaligned_le16
(
&
from
[
i
]);
if
(
ftmp
==
0
)
break
;
/*
* check to see if converting this character might make the
* conversion bleed into the null terminator
*/
if
(
outlen
>=
safelen
)
{
charlen
=
cifs_mapchar
(
tmp
,
f
rom
[
i
]
,
codepage
,
mapchar
);
charlen
=
cifs_mapchar
(
tmp
,
f
tmp
,
codepage
,
mapchar
);
if
((
outlen
+
charlen
)
>
(
tolen
-
nullsize
))
break
;
}
/* put converted char into 'to' buffer */
charlen
=
cifs_mapchar
(
&
to
[
outlen
],
f
rom
[
i
]
,
codepage
,
mapchar
);
charlen
=
cifs_mapchar
(
&
to
[
outlen
],
f
tmp
,
codepage
,
mapchar
);
outlen
+=
charlen
;
}
...
...
@@ -193,24 +201,21 @@ cifs_strtoUCS(__le16 *to, const char *from, int len,
{
int
charlen
;
int
i
;
wchar_t
*
wchar_to
=
(
wchar_t
*
)
to
;
/* needed to quiet sparse */
wchar_t
wchar_
to
;
/* needed to quiet sparse */
for
(
i
=
0
;
len
&&
*
from
;
i
++
,
from
+=
charlen
,
len
-=
charlen
)
{
/* works for 2.4.0 kernel or later */
charlen
=
codepage
->
char2uni
(
from
,
len
,
&
wchar_to
[
i
]);
charlen
=
codepage
->
char2uni
(
from
,
len
,
&
wchar_to
);
if
(
charlen
<
1
)
{
cERROR
(
1
,
"strtoUCS: char2uni of
%d
returned %d"
,
(
int
)
*
from
,
charlen
);
cERROR
(
1
,
"strtoUCS: char2uni of
0x%x
returned %d"
,
*
from
,
charlen
);
/* A question mark */
to
[
i
]
=
cpu_to_le16
(
0x003f
)
;
wchar_to
=
0x003f
;
charlen
=
1
;
}
else
to
[
i
]
=
cpu_to_le16
(
wchar_to
[
i
]);
}
put_unaligned_le16
(
wchar_to
,
&
to
[
i
]);
}
to
[
i
]
=
0
;
put_unaligned_le16
(
0
,
&
to
[
i
])
;
return
i
;
}
...
...
@@ -252,3 +257,79 @@ cifs_strndup_from_ucs(const char *src, const int maxlen, const bool is_unicode,
return
dst
;
}
/*
* Convert 16 bit Unicode pathname to wire format from string in current code
* page. Conversion may involve remapping up the six characters that are
* only legal in POSIX-like OS (if they are present in the string). Path
* names are little endian 16 bit Unicode on the wire
*/
int
cifsConvertToUCS
(
__le16
*
target
,
const
char
*
source
,
int
maxlen
,
const
struct
nls_table
*
cp
,
int
mapChars
)
{
int
i
,
j
,
charlen
;
int
len_remaining
=
maxlen
;
char
src_char
;
__u16
temp
;
if
(
!
mapChars
)
return
cifs_strtoUCS
(
target
,
source
,
PATH_MAX
,
cp
);
for
(
i
=
0
,
j
=
0
;
i
<
maxlen
;
j
++
)
{
src_char
=
source
[
i
];
switch
(
src_char
)
{
case
0
:
put_unaligned_le16
(
0
,
&
target
[
j
]);
goto
ctoUCS_out
;
case
':'
:
temp
=
UNI_COLON
;
break
;
case
'*'
:
temp
=
UNI_ASTERIK
;
break
;
case
'?'
:
temp
=
UNI_QUESTION
;
break
;
case
'<'
:
temp
=
UNI_LESSTHAN
;
break
;
case
'>'
:
temp
=
UNI_GRTRTHAN
;
break
;
case
'|'
:
temp
=
UNI_PIPE
;
break
;
/*
* FIXME: We can not handle remapping backslash (UNI_SLASH)
* until all the calls to build_path_from_dentry are modified,
* as they use backslash as separator.
*/
default:
charlen
=
cp
->
char2uni
(
source
+
i
,
len_remaining
,
&
temp
);
/*
* if no match, use question mark, which at least in
* some cases serves as wild card
*/
if
(
charlen
<
1
)
{
temp
=
0x003f
;
charlen
=
1
;
}
len_remaining
-=
charlen
;
/*
* character may take more than one byte in the source
* string, but will take exactly two bytes in the
* target string
*/
i
+=
charlen
;
continue
;
}
put_unaligned_le16
(
temp
,
&
target
[
j
]);
i
++
;
/* move to next char in source string */
len_remaining
--
;
}
ctoUCS_out:
return
i
;
}
fs/cifs/cifsfs.c
View file @
bf67b9be
...
...
@@ -733,6 +733,25 @@ const struct file_operations cifs_file_ops = {
.
setlease
=
cifs_setlease
,
};
const
struct
file_operations
cifs_file_strict_ops
=
{
.
read
=
do_sync_read
,
.
write
=
do_sync_write
,
.
aio_read
=
cifs_strict_readv
,
.
aio_write
=
cifs_file_aio_write
,
.
open
=
cifs_open
,
.
release
=
cifs_close
,
.
lock
=
cifs_lock
,
.
fsync
=
cifs_strict_fsync
,
.
flush
=
cifs_flush
,
.
mmap
=
cifs_file_strict_mmap
,
.
splice_read
=
generic_file_splice_read
,
.
llseek
=
cifs_llseek
,
#ifdef CONFIG_CIFS_POSIX
.
unlocked_ioctl
=
cifs_ioctl
,
#endif
/* CONFIG_CIFS_POSIX */
.
setlease
=
cifs_setlease
,
};
const
struct
file_operations
cifs_file_direct_ops
=
{
/* no aio, no readv -
BB reevaluate whether they can be done with directio, no cache */
...
...
@@ -751,6 +770,7 @@ const struct file_operations cifs_file_direct_ops = {
.
llseek
=
cifs_llseek
,
.
setlease
=
cifs_setlease
,
};
const
struct
file_operations
cifs_file_nobrl_ops
=
{
.
read
=
do_sync_read
,
.
write
=
do_sync_write
,
...
...
@@ -769,6 +789,24 @@ const struct file_operations cifs_file_nobrl_ops = {
.
setlease
=
cifs_setlease
,
};
const
struct
file_operations
cifs_file_strict_nobrl_ops
=
{
.
read
=
do_sync_read
,
.
write
=
do_sync_write
,
.
aio_read
=
cifs_strict_readv
,
.
aio_write
=
cifs_file_aio_write
,
.
open
=
cifs_open
,
.
release
=
cifs_close
,
.
fsync
=
cifs_strict_fsync
,
.
flush
=
cifs_flush
,
.
mmap
=
cifs_file_strict_mmap
,
.
splice_read
=
generic_file_splice_read
,
.
llseek
=
cifs_llseek
,
#ifdef CONFIG_CIFS_POSIX
.
unlocked_ioctl
=
cifs_ioctl
,
#endif
/* CONFIG_CIFS_POSIX */
.
setlease
=
cifs_setlease
,
};
const
struct
file_operations
cifs_file_direct_nobrl_ops
=
{
/* no mmap, no aio, no readv -
BB reevaluate whether they can be done with directio, no cache */
...
...
fs/cifs/cifsfs.h
View file @
bf67b9be
...
...
@@ -61,6 +61,7 @@ extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
struct
dentry
*
);
extern
int
cifs_revalidate_file
(
struct
file
*
filp
);
extern
int
cifs_revalidate_dentry
(
struct
dentry
*
);
extern
void
cifs_invalidate_mapping
(
struct
inode
*
inode
);
extern
int
cifs_getattr
(
struct
vfsmount
*
,
struct
dentry
*
,
struct
kstat
*
);
extern
int
cifs_setattr
(
struct
dentry
*
,
struct
iattr
*
);
...
...
@@ -72,19 +73,25 @@ extern const struct inode_operations cifs_dfs_referral_inode_operations;
/* Functions related to files and directories */
extern
const
struct
file_operations
cifs_file_ops
;
extern
const
struct
file_operations
cifs_file_direct_ops
;
/* if directio mnt */
extern
const
struct
file_operations
cifs_file_nobrl_ops
;
extern
const
struct
file_operations
cifs_file_direct_nobrl_ops
;
/* no brlocks */
extern
const
struct
file_operations
cifs_file_strict_ops
;
/* if strictio mnt */
extern
const
struct
file_operations
cifs_file_nobrl_ops
;
/* no brlocks */
extern
const
struct
file_operations
cifs_file_direct_nobrl_ops
;
extern
const
struct
file_operations
cifs_file_strict_nobrl_ops
;
extern
int
cifs_open
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_close
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_closedir
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
ssize_t
cifs_user_read
(
struct
file
*
file
,
char
__user
*
read_data
,
size_t
read_size
,
loff_t
*
poffset
);
size_t
read_size
,
loff_t
*
poffset
);
extern
ssize_t
cifs_strict_readv
(
struct
kiocb
*
iocb
,
const
struct
iovec
*
iov
,
unsigned
long
nr_segs
,
loff_t
pos
);
extern
ssize_t
cifs_user_write
(
struct
file
*
file
,
const
char
__user
*
write_data
,
size_t
write_size
,
loff_t
*
poffset
);
extern
int
cifs_lock
(
struct
file
*
,
int
,
struct
file_lock
*
);
extern
int
cifs_fsync
(
struct
file
*
,
int
);
extern
int
cifs_strict_fsync
(
struct
file
*
,
int
);
extern
int
cifs_flush
(
struct
file
*
,
fl_owner_t
id
);
extern
int
cifs_file_mmap
(
struct
file
*
,
struct
vm_area_struct
*
);
extern
int
cifs_file_strict_mmap
(
struct
file
*
,
struct
vm_area_struct
*
);
extern
const
struct
file_operations
cifs_dir_ops
;
extern
int
cifs_dir_open
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_readdir
(
struct
file
*
file
,
void
*
direntry
,
filldir_t
filldir
);
...
...
fs/cifs/cifsglob.h
View file @
bf67b9be
...
...
@@ -161,6 +161,7 @@ struct TCP_Server_Info {
int
srv_count
;
/* reference counter */
/* 15 character server name + 0x20 16th byte indicating type = srv */
char
server_RFC1001_name
[
RFC1001_NAME_LEN_WITH_NULL
];
enum
statusEnum
tcpStatus
;
/* what we think the status is */
char
*
hostname
;
/* hostname portion of UNC string */
struct
socket
*
ssocket
;
struct
sockaddr_storage
dstaddr
;
...
...
@@ -168,25 +169,16 @@ struct TCP_Server_Info {
wait_queue_head_t
response_q
;
wait_queue_head_t
request_q
;
/* if more than maxmpx to srvr must block*/
struct
list_head
pending_mid_q
;
void
*
Server_NlsInfo
;
/* BB - placeholder for future NLS info */
unsigned
short
server_codepage
;
/* codepage for the server */
enum
protocolEnum
protocolType
;
char
versionMajor
;
char
versionMinor
;
bool
svlocal
:
1
;
/* local server or remote */
bool
noblocksnd
;
/* use blocking sendmsg */
bool
noautotune
;
/* do not autotune send buf sizes */
bool
tcp_nodelay
;
atomic_t
inFlight
;
/* number of requests on the wire to server */
#ifdef CONFIG_CIFS_STATS2
atomic_t
inSend
;
/* requests trying to send */
atomic_t
num_waiters
;
/* blocked waiting to get in sendrecv */
#endif
enum
statusEnum
tcpStatus
;
/* what we think the status is */
struct
mutex
srv_mutex
;
struct
task_struct
*
tsk
;
char
server_GUID
[
16
];
char
secMode
;
bool
session_estab
;
/* mark when very first sess is established */
u16
dialect
;
/* dialect index that server chose */
enum
securityEnum
secType
;
unsigned
int
maxReq
;
/* Clients should submit no more */
/* than maxReq distinct unanswered SMBs to the server when using */
...
...
@@ -199,8 +191,6 @@ struct TCP_Server_Info {
unsigned
int
max_vcs
;
/* maximum number of smb sessions, at least
those that can be specified uniquely with
vcnumbers */
char
sessid
[
4
];
/* unique token id for this session */
/* (returned on Negotiate */
int
capabilities
;
/* allow selective disabling of caps by smb sess */
int
timeAdj
;
/* Adjust for difference in server time zone in sec */
__u16
CurrentMid
;
/* multiplex id - rotating counter */
...
...
@@ -210,18 +200,20 @@ struct TCP_Server_Info {
__u32
sequence_number
;
/* for signing, protected by srv_mutex */
struct
session_key
session_key
;
unsigned
long
lstrp
;
/* when we got last response from this server */
u16
dialect
;
/* dialect index that server chose */
struct
cifs_secmech
secmech
;
/* crypto sec mech functs, descriptors */
/* extended security flavors that server supports */
bool
sec_ntlmssp
;
/* supports NTLMSSP */
bool
sec_kerberosu2u
;
/* supports U2U Kerberos */
bool
sec_kerberos
;
/* supports plain Kerberos */
bool
sec_mskerberos
;
/* supports legacy MS Kerberos */
bool
sec_kerberosu2u
;
/* supports U2U Kerberos */
bool
sec_ntlmssp
;
/* supports NTLMSSP */
bool
session_estab
;
/* mark when very first sess is established */
struct
delayed_work
echo
;
/* echo ping workqueue job */
#ifdef CONFIG_CIFS_FSCACHE
struct
fscache_cookie
*
fscache
;
/* client index cache cookie */
#endif
#ifdef CONFIG_CIFS_STATS2
atomic_t
inSend
;
/* requests trying to send */
atomic_t
num_waiters
;
/* blocked waiting to get in sendrecv */
#endif
};
/*
...
...
@@ -447,11 +439,11 @@ struct cifsInodeInfo {
/* BB add in lists for dirty pages i.e. write caching info for oplock */
struct
list_head
openFileList
;
__u32
cifsAttrs
;
/* e.g. DOS archive bit, sparse, compressed, system */
unsigned
long
time
;
/* jiffies of last update/check of inode
*/
bool
clientCanCache
Read
:
1
;
/* rea
d oplock */
bool
clientCanCacheAll
:
1
;
/* read and writebehind oplock
*/
bool
delete_pending
:
1
;
/* DELETE_ON_CLOSE is set
*/
bool
invalid_mapping
:
1
;
/* pagecache is invalid
*/
bool
clientCanCacheRead
;
/* read oplock
*/
bool
clientCanCache
All
;
/* read and writebehin
d oplock */
bool
delete_pending
;
/* DELETE_ON_CLOSE is set
*/
bool
invalid_mapping
;
/* pagecache is invalid
*/
unsigned
long
time
;
/* jiffies of last update of inode
*/
u64
server_eof
;
/* current file size on server */
u64
uniqueid
;
/* server inode number */
u64
createtime
;
/* creation time on server */
...
...
fs/cifs/cifspdu.h
View file @
bf67b9be
...
...
@@ -23,6 +23,7 @@
#define _CIFSPDU_H
#include <net/sock.h>
#include <asm/unaligned.h>
#include "smbfsctl.h"
#ifdef CONFIG_CIFS_WEAK_PW_HASH
...
...
@@ -426,11 +427,49 @@ struct smb_hdr {
__u16
Mid
;
__u8
WordCount
;
}
__attribute__
((
packed
));
/* given a pointer to an smb_hdr retrieve the value of byte count */
#define BCC(smb_var) (*(__u16 *)((char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount)))
#define BCC_LE(smb_var) (*(__le16 *)((char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount)))
/* given a pointer to an smb_hdr retrieve a char pointer to the byte count */
#define BCC(smb_var) ((unsigned char *)(smb_var) + sizeof(struct smb_hdr) + \
(2 * (smb_var)->WordCount))
/* given a pointer to an smb_hdr retrieve the pointer to the byte area */
#define pByteArea(smb_var) ((unsigned char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount) + 2)
#define pByteArea(smb_var) (BCC(smb_var) + 2)
/* get the converted ByteCount for a SMB packet and return it */
static
inline
__u16
get_bcc
(
struct
smb_hdr
*
hdr
)
{
__u16
*
bc_ptr
=
(
__u16
*
)
BCC
(
hdr
);
return
get_unaligned
(
bc_ptr
);
}
/* get the unconverted ByteCount for a SMB packet and return it */
static
inline
__u16
get_bcc_le
(
struct
smb_hdr
*
hdr
)
{
__le16
*
bc_ptr
=
(
__le16
*
)
BCC
(
hdr
);
return
get_unaligned_le16
(
bc_ptr
);
}
/* set the ByteCount for a SMB packet in host-byte order */
static
inline
void
put_bcc
(
__u16
count
,
struct
smb_hdr
*
hdr
)
{
__u16
*
bc_ptr
=
(
__u16
*
)
BCC
(
hdr
);
put_unaligned
(
count
,
bc_ptr
);
}
/* set the ByteCount for a SMB packet in little-endian */
static
inline
void
put_bcc_le
(
__u16
count
,
struct
smb_hdr
*
hdr
)
{
__le16
*
bc_ptr
=
(
__le16
*
)
BCC
(
hdr
);
put_unaligned_le16
(
count
,
bc_ptr
);
}
/*
* Computer Name Length (since Netbios name was length 16 with last byte 0x20)
...
...
fs/cifs/cifssmb.c
View file @
bf67b9be
...
...
@@ -331,37 +331,35 @@ smb_init_no_reconnect(int smb_command, int wct, struct cifsTconInfo *tcon,
static
int
validate_t2
(
struct
smb_t2_rsp
*
pSMB
)
{
int
rc
=
-
EINVAL
;
int
total_size
;
char
*
pBCC
;
unsigned
int
total_size
;
/* check for plausible wct */
if
(
pSMB
->
hdr
.
WordCount
<
10
)
goto
vt2_err
;
/* check for plausible wct, bcc and t2 data and parm sizes */
/* check for parm and data offset going beyond end of smb */
if
(
pSMB
->
hdr
.
WordCount
>=
10
)
{
if
((
le16_to_cpu
(
pSMB
->
t2_rsp
.
ParameterOffset
)
<=
1024
)
&&
(
le16_to_cpu
(
pSMB
->
t2_rsp
.
DataOffset
)
<=
1024
))
{
/* check that bcc is at least as big as parms + data */
/* check that bcc is less than negotiated smb buffer */
total_size
=
le16_to_cpu
(
pSMB
->
t2_rsp
.
ParameterCount
);
if
(
total_size
<
512
)
{
total_size
+=
le16_to_cpu
(
pSMB
->
t2_rsp
.
DataCount
);
/* BCC le converted in SendReceive */
pBCC
=
(
pSMB
->
hdr
.
WordCount
*
2
)
+
sizeof
(
struct
smb_hdr
)
+
(
char
*
)
pSMB
;
if
((
total_size
<=
(
*
(
u16
*
)
pBCC
))
&&
(
total_size
<
CIFSMaxBufSize
+
MAX_CIFS_HDR_SIZE
))
{
return
0
;
}
}
}
}
if
(
get_unaligned_le16
(
&
pSMB
->
t2_rsp
.
ParameterOffset
)
>
1024
||
get_unaligned_le16
(
&
pSMB
->
t2_rsp
.
DataOffset
)
>
1024
)
goto
vt2_err
;
/* check that bcc is at least as big as parms + data */
/* check that bcc is less than negotiated smb buffer */
total_size
=
get_unaligned_le16
(
&
pSMB
->
t2_rsp
.
ParameterCount
);
if
(
total_size
>=
512
)
goto
vt2_err
;
total_size
+=
get_unaligned_le16
(
&
pSMB
->
t2_rsp
.
DataCount
);
if
(
total_size
>
get_bcc
(
&
pSMB
->
hdr
)
||
total_size
>=
CIFSMaxBufSize
+
MAX_CIFS_HDR_SIZE
)
goto
vt2_err
;
return
0
;
vt2_err:
cifs_dump_mem
(
"Invalid transact2 SMB: "
,
(
char
*
)
pSMB
,
sizeof
(
struct
smb_t2_rsp
)
+
16
);
return
rc
;
return
-
EINVAL
;
}
int
CIFSSMBNegotiate
(
unsigned
int
xid
,
struct
cifsSesInfo
*
ses
)
{
...
...
@@ -452,7 +450,6 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
server
->
maxBuf
=
min
((
__u32
)
le16_to_cpu
(
rsp
->
MaxBufSize
),
(
__u32
)
CIFSMaxBufSize
+
MAX_CIFS_HDR_SIZE
);
server
->
max_vcs
=
le16_to_cpu
(
rsp
->
MaxNumberVcs
);
GETU32
(
server
->
sessid
)
=
le32_to_cpu
(
rsp
->
SessionKey
);
/* even though we do not use raw we might as well set this
accurately, in case we ever find a need for it */
if
((
le16_to_cpu
(
rsp
->
RawMode
)
&
RAW_ENABLE
)
==
RAW_ENABLE
)
{
...
...
@@ -566,7 +563,6 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
(
__u32
)
CIFSMaxBufSize
+
MAX_CIFS_HDR_SIZE
);
server
->
max_rw
=
le32_to_cpu
(
pSMBr
->
MaxRawSize
);
cFYI
(
DBG2
,
"Max buf = %d"
,
ses
->
server
->
maxBuf
);
GETU32
(
ses
->
server
->
sessid
)
=
le32_to_cpu
(
pSMBr
->
SessionKey
);
server
->
capabilities
=
le32_to_cpu
(
pSMBr
->
Capabilities
);
server
->
timeAdj
=
(
int
)(
__s16
)
le16_to_cpu
(
pSMBr
->
ServerTimeZone
);
server
->
timeAdj
*=
60
;
...
...
@@ -5611,7 +5607,7 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
}
/* make sure list_len doesn't go past end of SMB */
end_of_smb
=
(
char
*
)
pByteArea
(
&
pSMBr
->
hdr
)
+
BCC
(
&
pSMBr
->
hdr
);
end_of_smb
=
(
char
*
)
pByteArea
(
&
pSMBr
->
hdr
)
+
get_bcc
(
&
pSMBr
->
hdr
);
if
((
char
*
)
ea_response_data
+
list_len
>
end_of_smb
)
{
cFYI
(
1
,
"EA list appears to go beyond SMB"
);
rc
=
-
EIO
;
...
...
fs/cifs/connect.c
View file @
bf67b9be
...
...
@@ -232,9 +232,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
static
int
check2ndT2
(
struct
smb_hdr
*
pSMB
,
unsigned
int
maxBufSize
)
{
struct
smb_t2_rsp
*
pSMBt
;
int
total_data_size
;
int
data_in_this_rsp
;
int
remaining
;
__u16
total_data_size
,
data_in_this_rsp
;
if
(
pSMB
->
Command
!=
SMB_COM_TRANSACTION2
)
return
0
;
...
...
@@ -248,8 +247,8 @@ static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
pSMBt
=
(
struct
smb_t2_rsp
*
)
pSMB
;
total_data_size
=
le16_to_cpu
(
pSMBt
->
t2_rsp
.
TotalDataCount
);
data_in_this_rsp
=
le16_to_cpu
(
pSMBt
->
t2_rsp
.
DataCount
);
total_data_size
=
get_unaligned_le16
(
&
pSMBt
->
t2_rsp
.
TotalDataCount
);
data_in_this_rsp
=
get_unaligned_le16
(
&
pSMBt
->
t2_rsp
.
DataCount
);
remaining
=
total_data_size
-
data_in_this_rsp
;
...
...
@@ -275,21 +274,18 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
{
struct
smb_t2_rsp
*
pSMB2
=
(
struct
smb_t2_rsp
*
)
psecond
;
struct
smb_t2_rsp
*
pSMBt
=
(
struct
smb_t2_rsp
*
)
pTargetSMB
;
int
total_data_size
;
int
total_in_buf
;
int
remaining
;
int
total_in_buf2
;
char
*
data_area_of_target
;
char
*
data_area_of_buf2
;
__u16
byte_count
;
int
remaining
;
__u16
byte_count
,
total_data_size
,
total_in_buf
,
total_in_buf2
;
total_data_size
=
le16_to_cpu
(
pSMBt
->
t2_rsp
.
TotalDataCount
);
total_data_size
=
get_unaligned_le16
(
&
pSMBt
->
t2_rsp
.
TotalDataCount
);
if
(
total_data_size
!=
le16_to_cpu
(
pSMB2
->
t2_rsp
.
TotalDataCount
))
{
if
(
total_data_size
!=
get_unaligned_le16
(
&
pSMB2
->
t2_rsp
.
TotalDataCount
))
cFYI
(
1
,
"total data size of primary and secondary t2 differ"
);
}
total_in_buf
=
le16_to_cpu
(
pSMBt
->
t2_rsp
.
DataCount
);
total_in_buf
=
get_unaligned_le16
(
&
pSMBt
->
t2_rsp
.
DataCount
);
remaining
=
total_data_size
-
total_in_buf
;
...
...
@@ -299,28 +295,28 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
if
(
remaining
==
0
)
/* nothing to do, ignore */
return
0
;
total_in_buf2
=
le16_to_cpu
(
pSMB2
->
t2_rsp
.
DataCount
);
total_in_buf2
=
get_unaligned_le16
(
&
pSMB2
->
t2_rsp
.
DataCount
);
if
(
remaining
<
total_in_buf2
)
{
cFYI
(
1
,
"transact2 2nd response contains too much data"
);
}
/* find end of first SMB data area */
data_area_of_target
=
(
char
*
)
&
pSMBt
->
hdr
.
Protocol
+
le16_to_cpu
(
pSMBt
->
t2_rsp
.
DataOffset
);
get_unaligned_le16
(
&
pSMBt
->
t2_rsp
.
DataOffset
);
/* validate target area */
data_area_of_buf2
=
(
char
*
)
&
pSMB2
->
hdr
.
Protocol
+
le16_to_cpu
(
pSMB2
->
t2_rsp
.
DataOffset
);
data_area_of_buf2
=
(
char
*
)
&
pSMB2
->
hdr
.
Protocol
+
get_unaligned_le16
(
&
pSMB2
->
t2_rsp
.
DataOffset
);
data_area_of_target
+=
total_in_buf
;
/* copy second buffer into end of first buffer */
memcpy
(
data_area_of_target
,
data_area_of_buf2
,
total_in_buf2
);
total_in_buf
+=
total_in_buf2
;
p
SMBt
->
t2_rsp
.
DataCount
=
cpu_to_le16
(
total_in_buf
);
byte_count
=
le16_to_cpu
(
BCC_LE
(
pTargetSMB
)
);
p
ut_unaligned_le16
(
total_in_buf
,
&
pSMBt
->
t2_rsp
.
DataCount
);
byte_count
=
get_bcc_le
(
pTargetSMB
);
byte_count
+=
total_in_buf2
;
BCC_LE
(
pTargetSMB
)
=
cpu_to_le16
(
byte_count
);
put_bcc_le
(
byte_count
,
pTargetSMB
);
byte_count
=
pTargetSMB
->
smb_buf_length
;
byte_count
+=
total_in_buf2
;
...
...
@@ -334,7 +330,6 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
return
0
;
/* we are done */
}
else
/* more responses to go */
return
1
;
}
static
void
...
...
@@ -2937,8 +2932,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
TCONX_RSP
*
pSMBr
;
unsigned
char
*
bcc_ptr
;
int
rc
=
0
;
int
length
,
bytes_left
;
__u16
count
;
int
length
;
__u16
bytes_left
,
count
;
if
(
ses
==
NULL
)
return
-
EIO
;
...
...
@@ -3032,7 +3027,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
tcon
->
need_reconnect
=
false
;
tcon
->
tid
=
smb_buffer_response
->
Tid
;
bcc_ptr
=
pByteArea
(
smb_buffer_response
);
bytes_left
=
BCC
(
smb_buffer_response
);
bytes_left
=
get_bcc
(
smb_buffer_response
);
length
=
strnlen
(
bcc_ptr
,
bytes_left
-
2
);
if
(
smb_buffer
->
Flags2
&
SMBFLG2_UNICODE
)
is_unicode
=
true
;
...
...
fs/cifs/file.c
View file @
bf67b9be
...
...
@@ -287,6 +287,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
struct
inode
*
inode
=
cifs_file
->
dentry
->
d_inode
;
struct
cifsTconInfo
*
tcon
=
tlink_tcon
(
cifs_file
->
tlink
);
struct
cifsInodeInfo
*
cifsi
=
CIFS_I
(
inode
);
struct
cifs_sb_info
*
cifs_sb
=
CIFS_SB
(
inode
->
i_sb
);
struct
cifsLockInfo
*
li
,
*
tmp
;
spin_lock
(
&
cifs_file_list_lock
);
...
...
@@ -302,6 +303,13 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
if
(
list_empty
(
&
cifsi
->
openFileList
))
{
cFYI
(
1
,
"closing last open instance for inode %p"
,
cifs_file
->
dentry
->
d_inode
);
/* in strict cache mode we need invalidate mapping on the last
close because it may cause a error when we open this file
again and get at least level II oplock */
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_STRICT_IO
)
CIFS_I
(
inode
)
->
invalid_mapping
=
true
;
cifs_set_oplock_level
(
cifsi
,
0
);
}
spin_unlock
(
&
cifs_file_list_lock
);
...
...
@@ -1520,27 +1528,47 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
return
rc
;
}
int
cifs_fsync
(
struct
file
*
file
,
int
datasync
)
int
cifs_
strict_
fsync
(
struct
file
*
file
,
int
datasync
)
{
int
xid
;
int
rc
=
0
;
struct
cifsTconInfo
*
tcon
;
struct
cifsFileInfo
*
smbfile
=
file
->
private_data
;
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
struct
cifs_sb_info
*
cifs_sb
=
CIFS_SB
(
inode
->
i_sb
);
xid
=
GetXid
();
cFYI
(
1
,
"Sync file - name: %s datasync: 0x%x"
,
file
->
f_path
.
dentry
->
d_name
.
name
,
datasync
);
rc
=
filemap_write_and_wait
(
inode
->
i_mapping
);
if
(
rc
==
0
)
{
struct
cifs_sb_info
*
cifs_sb
=
CIFS_SB
(
inode
->
i_sb
);
if
(
!
CIFS_I
(
inode
)
->
clientCanCacheRead
)
cifs_invalidate_mapping
(
inode
);
tcon
=
tlink_tcon
(
smbfile
->
tlink
);
if
(
!
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NOSSYNC
))
rc
=
CIFSSMBFlush
(
xid
,
tcon
,
smbfile
->
netfid
);
}
tcon
=
tlink_tcon
(
smbfile
->
tlink
);
if
(
!
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NOSSYNC
))
rc
=
CIFSSMBFlush
(
xid
,
tcon
,
smbfile
->
netfid
);
FreeXid
(
xid
);
return
rc
;
}
int
cifs_fsync
(
struct
file
*
file
,
int
datasync
)
{
int
xid
;
int
rc
=
0
;
struct
cifsTconInfo
*
tcon
;
struct
cifsFileInfo
*
smbfile
=
file
->
private_data
;
struct
cifs_sb_info
*
cifs_sb
=
CIFS_SB
(
file
->
f_path
.
dentry
->
d_sb
);
xid
=
GetXid
();
cFYI
(
1
,
"Sync file - name: %s datasync: 0x%x"
,
file
->
f_path
.
dentry
->
d_name
.
name
,
datasync
);
tcon
=
tlink_tcon
(
smbfile
->
tlink
);
if
(
!
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NOSSYNC
))
rc
=
CIFSSMBFlush
(
xid
,
tcon
,
smbfile
->
netfid
);
FreeXid
(
xid
);
return
rc
;
...
...
@@ -1591,42 +1619,42 @@ int cifs_flush(struct file *file, fl_owner_t id)
return
rc
;
}
ssize_t
cifs_user_read
(
struct
file
*
file
,
char
__user
*
read_data
,
size_t
read_size
,
loff_t
*
poffset
)
static
ssize_t
cifs_iovec_read
(
struct
file
*
file
,
const
struct
iovec
*
iov
,
unsigned
long
nr_segs
,
loff_t
*
poffset
)
{
int
rc
=
-
EACCES
;
unsigned
int
bytes_read
=
0
;
unsigned
int
total_read
=
0
;
unsigned
int
current_read_size
;
int
rc
;
int
xid
;
unsigned
int
total_read
,
bytes_read
=
0
;
size_t
len
,
cur_len
;
int
iov_offset
=
0
;
struct
cifs_sb_info
*
cifs_sb
;
struct
cifsTconInfo
*
pTcon
;
int
xid
;
struct
cifsFileInfo
*
open_file
;
char
*
smb_read_data
;
char
__user
*
current_offset
;
struct
smb_com_read_rsp
*
pSMBr
;
char
*
read_data
;
if
(
!
nr_segs
)
return
0
;
len
=
iov_length
(
iov
,
nr_segs
);
if
(
!
len
)
return
0
;
xid
=
GetXid
();
cifs_sb
=
CIFS_SB
(
file
->
f_path
.
dentry
->
d_sb
);
if
(
file
->
private_data
==
NULL
)
{
rc
=
-
EBADF
;
FreeXid
(
xid
);
return
rc
;
}
open_file
=
file
->
private_data
;
pTcon
=
tlink_tcon
(
open_file
->
tlink
);
if
((
file
->
f_flags
&
O_ACCMODE
)
==
O_WRONLY
)
cFYI
(
1
,
"attempting read on write only file instance"
);
for
(
total_read
=
0
,
current_offset
=
read_data
;
read_size
>
total_read
;
total_read
+=
bytes_read
,
current_offset
+=
bytes_read
)
{
current_read_size
=
min_t
(
const
int
,
read_size
-
total_read
,
cifs_sb
->
rsize
);
for
(
total_read
=
0
;
total_read
<
len
;
total_read
+=
bytes_read
)
{
cur_len
=
min_t
(
const
size_t
,
len
-
total_read
,
cifs_sb
->
rsize
);
rc
=
-
EAGAIN
;
smb_read_data
=
NULL
;
read_data
=
NULL
;
while
(
rc
==
-
EAGAIN
)
{
int
buf_type
=
CIFS_NO_BUFFER
;
if
(
open_file
->
invalidHandle
)
{
...
...
@@ -1634,27 +1662,25 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
if
(
rc
!=
0
)
break
;
}
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
open_file
->
netfid
,
current_read_size
,
*
poffset
,
&
bytes_read
,
&
smb_read_data
,
&
buf_type
);
pSMBr
=
(
struct
smb_com_read_rsp
*
)
smb_read_data
;
if
(
smb_read_data
)
{
if
(
copy_to_user
(
current_offset
,
smb_read_data
+
4
/* RFC1001 length field */
+
le16_to_cpu
(
pSMBr
->
DataOffset
),
bytes_read
))
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
open_file
->
netfid
,
cur_len
,
*
poffset
,
&
bytes_read
,
&
read_data
,
&
buf_type
);
pSMBr
=
(
struct
smb_com_read_rsp
*
)
read_data
;
if
(
read_data
)
{
char
*
data_offset
=
read_data
+
4
+
le16_to_cpu
(
pSMBr
->
DataOffset
);
if
(
memcpy_toiovecend
(
iov
,
data_offset
,
iov_offset
,
bytes_read
))
rc
=
-
EFAULT
;
if
(
buf_type
==
CIFS_SMALL_BUFFER
)
cifs_small_buf_release
(
smb_
read_data
);
cifs_small_buf_release
(
read_data
);
else
if
(
buf_type
==
CIFS_LARGE_BUFFER
)
cifs_buf_release
(
smb_read_data
);
smb_read_data
=
NULL
;
cifs_buf_release
(
read_data
);
read_data
=
NULL
;
iov_offset
+=
bytes_read
;
}
}
if
(
rc
||
(
bytes_read
==
0
))
{
if
(
total_read
)
{
break
;
...
...
@@ -1667,13 +1693,57 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
*
poffset
+=
bytes_read
;
}
}
FreeXid
(
xid
);
return
total_read
;
}
ssize_t
cifs_user_read
(
struct
file
*
file
,
char
__user
*
read_data
,
size_t
read_size
,
loff_t
*
poffset
)
{
struct
iovec
iov
;
iov
.
iov_base
=
read_data
;
iov
.
iov_len
=
read_size
;
return
cifs_iovec_read
(
file
,
&
iov
,
1
,
poffset
);
}
static
ssize_t
cifs_user_readv
(
struct
kiocb
*
iocb
,
const
struct
iovec
*
iov
,
unsigned
long
nr_segs
,
loff_t
pos
)
{
ssize_t
read
;
read
=
cifs_iovec_read
(
iocb
->
ki_filp
,
iov
,
nr_segs
,
&
pos
);
if
(
read
>
0
)
iocb
->
ki_pos
=
pos
;
return
read
;
}
ssize_t
cifs_strict_readv
(
struct
kiocb
*
iocb
,
const
struct
iovec
*
iov
,
unsigned
long
nr_segs
,
loff_t
pos
)
{
struct
inode
*
inode
;
inode
=
iocb
->
ki_filp
->
f_path
.
dentry
->
d_inode
;
if
(
CIFS_I
(
inode
)
->
clientCanCacheRead
)
return
generic_file_aio_read
(
iocb
,
iov
,
nr_segs
,
pos
);
/*
* In strict cache mode we need to read from the server all the time
* if we don't have level II oplock because the server can delay mtime
* change - so we can't make a decision about inode invalidating.
* And we can also fail with pagereading if there are mandatory locks
* on pages affected by this read but not on the region from pos to
* pos+len-1.
*/
return
cifs_user_readv
(
iocb
,
iov
,
nr_segs
,
pos
);
}
static
ssize_t
cifs_read
(
struct
file
*
file
,
char
*
read_data
,
size_t
read_size
,
loff_t
*
poffset
)
loff_t
*
poffset
)
{
int
rc
=
-
EACCES
;
unsigned
int
bytes_read
=
0
;
...
...
@@ -1741,6 +1811,21 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
return
total_read
;
}
int
cifs_file_strict_mmap
(
struct
file
*
file
,
struct
vm_area_struct
*
vma
)
{
int
rc
,
xid
;
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
xid
=
GetXid
();
if
(
!
CIFS_I
(
inode
)
->
clientCanCacheRead
)
cifs_invalidate_mapping
(
inode
);
rc
=
generic_file_mmap
(
file
,
vma
);
FreeXid
(
xid
);
return
rc
;
}
int
cifs_file_mmap
(
struct
file
*
file
,
struct
vm_area_struct
*
vma
)
{
int
rc
,
xid
;
...
...
fs/cifs/inode.c
View file @
bf67b9be
...
...
@@ -44,13 +44,17 @@ static void cifs_set_ops(struct inode *inode)
inode
->
i_fop
=
&
cifs_file_direct_nobrl_ops
;
else
inode
->
i_fop
=
&
cifs_file_direct_ops
;
}
else
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_STRICT_IO
)
{
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
inode
->
i_fop
=
&
cifs_file_strict_nobrl_ops
;
else
inode
->
i_fop
=
&
cifs_file_strict_ops
;
}
else
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
inode
->
i_fop
=
&
cifs_file_nobrl_ops
;
else
{
/* not direct, send byte range locks */
inode
->
i_fop
=
&
cifs_file_ops
;
}
/* check if server can support readpages */
if
(
cifs_sb_master_tcon
(
cifs_sb
)
->
ses
->
server
->
maxBuf
<
PAGE_CACHE_SIZE
+
MAX_CIFS_HDR_SIZE
)
...
...
@@ -1679,7 +1683,7 @@ cifs_inode_needs_reval(struct inode *inode)
/*
* Zap the cache. Called when invalid_mapping flag is set.
*/
static
void
void
cifs_invalidate_mapping
(
struct
inode
*
inode
)
{
int
rc
;
...
...
fs/cifs/misc.c
View file @
bf67b9be
...
...
@@ -637,77 +637,6 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
return
;
}
/* Convert 16 bit Unicode pathname to wire format from string in current code
page. Conversion may involve remapping up the seven characters that are
only legal in POSIX-like OS (if they are present in the string). Path
names are little endian 16 bit Unicode on the wire */
int
cifsConvertToUCS
(
__le16
*
target
,
const
char
*
source
,
int
maxlen
,
const
struct
nls_table
*
cp
,
int
mapChars
)
{
int
i
,
j
,
charlen
;
int
len_remaining
=
maxlen
;
char
src_char
;
__u16
temp
;
if
(
!
mapChars
)
return
cifs_strtoUCS
(
target
,
source
,
PATH_MAX
,
cp
);
for
(
i
=
0
,
j
=
0
;
i
<
maxlen
;
j
++
)
{
src_char
=
source
[
i
];
switch
(
src_char
)
{
case
0
:
target
[
j
]
=
0
;
goto
ctoUCS_out
;
case
':'
:
target
[
j
]
=
cpu_to_le16
(
UNI_COLON
);
break
;
case
'*'
:
target
[
j
]
=
cpu_to_le16
(
UNI_ASTERIK
);
break
;
case
'?'
:
target
[
j
]
=
cpu_to_le16
(
UNI_QUESTION
);
break
;
case
'<'
:
target
[
j
]
=
cpu_to_le16
(
UNI_LESSTHAN
);
break
;
case
'>'
:
target
[
j
]
=
cpu_to_le16
(
UNI_GRTRTHAN
);
break
;
case
'|'
:
target
[
j
]
=
cpu_to_le16
(
UNI_PIPE
);
break
;
/* BB We can not handle remapping slash until
all the calls to build_path_from_dentry
are modified, as they use slash as separator BB */
/* case '\\':
target[j] = cpu_to_le16(UNI_SLASH);
break;*/
default:
charlen
=
cp
->
char2uni
(
source
+
i
,
len_remaining
,
&
temp
);
/* if no match, use question mark, which
at least in some cases servers as wild card */
if
(
charlen
<
1
)
{
target
[
j
]
=
cpu_to_le16
(
0x003f
);
charlen
=
1
;
}
else
target
[
j
]
=
cpu_to_le16
(
temp
);
len_remaining
-=
charlen
;
/* character may take more than one byte in the
the source string, but will take exactly two
bytes in the target string */
i
+=
charlen
;
continue
;
}
i
++
;
/* move to next char in source string */
len_remaining
--
;
}
ctoUCS_out:
return
i
;
}
void
cifs_autodisable_serverino
(
struct
cifs_sb_info
*
cifs_sb
)
{
...
...
fs/cifs/netmisc.c
View file @
bf67b9be
...
...
@@ -916,14 +916,14 @@ unsigned int
smbCalcSize
(
struct
smb_hdr
*
ptr
)
{
return
(
sizeof
(
struct
smb_hdr
)
+
(
2
*
ptr
->
WordCount
)
+
2
/* size of the bcc field */
+
BCC
(
ptr
));
2
/* size of the bcc field */
+
get_bcc
(
ptr
));
}
unsigned
int
smbCalcSize_LE
(
struct
smb_hdr
*
ptr
)
{
return
(
sizeof
(
struct
smb_hdr
)
+
(
2
*
ptr
->
WordCount
)
+
2
/* size of the bcc field */
+
le16_to_cpu
(
BCC_LE
(
ptr
)
));
2
/* size of the bcc field */
+
get_bcc_le
(
ptr
));
}
/* The following are taken from fs/ntfs/util.c */
...
...
fs/cifs/sess.c
View file @
bf67b9be
...
...
@@ -277,7 +277,7 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
}
static
void
decode_unicode_ssetup
(
char
**
pbcc_area
,
int
bleft
,
struct
cifsSesInfo
*
ses
,
decode_unicode_ssetup
(
char
**
pbcc_area
,
__u16
bleft
,
struct
cifsSesInfo
*
ses
,
const
struct
nls_table
*
nls_cp
)
{
int
len
;
...
...
@@ -323,7 +323,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
return
;
}
static
int
decode_ascii_ssetup
(
char
**
pbcc_area
,
int
bleft
,
static
int
decode_ascii_ssetup
(
char
**
pbcc_area
,
__u16
bleft
,
struct
cifsSesInfo
*
ses
,
const
struct
nls_table
*
nls_cp
)
{
...
...
@@ -575,12 +575,11 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
char
*
str_area
;
SESSION_SETUP_ANDX
*
pSMB
;
__u32
capabilities
;
int
count
;
__u16
count
;
int
resp_buf_type
;
struct
kvec
iov
[
3
];
enum
securityEnum
type
;
__u16
action
;
int
bytes_remaining
;
__u16
action
,
bytes_remaining
;
struct
key
*
spnego_key
=
NULL
;
__le32
phase
=
NtLmNegotiate
;
/* NTLMSSP, if needed, is multistage */
u16
blob_len
;
...
...
@@ -876,7 +875,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
count
=
iov
[
1
].
iov_len
+
iov
[
2
].
iov_len
;
smb_buf
->
smb_buf_length
+=
count
;
BCC_LE
(
smb_buf
)
=
cpu_to_le16
(
count
);
put_bcc_le
(
count
,
smb_buf
);
rc
=
SendReceive2
(
xid
,
ses
,
iov
,
3
/* num_iovecs */
,
&
resp_buf_type
,
CIFS_LOG_ERROR
);
...
...
@@ -910,7 +909,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
cFYI
(
1
,
"UID = %d "
,
ses
->
Suid
);
/* response can have either 3 or 4 word count - Samba sends 3 */
/* and lanman response is 3 */
bytes_remaining
=
BCC
(
smb_buf
);
bytes_remaining
=
get_bcc
(
smb_buf
);
bcc_ptr
=
pByteArea
(
smb_buf
);
if
(
smb_buf
->
WordCount
==
4
)
{
...
...
fs/cifs/transport.c
View file @
bf67b9be
...
...
@@ -484,7 +484,7 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
in_buf
->
smb_buf_length
=
sizeof
(
struct
smb_hdr
)
-
4
+
2
;
in_buf
->
Command
=
SMB_COM_NT_CANCEL
;
in_buf
->
WordCount
=
0
;
BCC_LE
(
in_buf
)
=
0
;
put_bcc_le
(
0
,
in_buf
)
;
mutex_lock
(
&
server
->
srv_mutex
);
rc
=
cifs_sign_smb
(
in_buf
,
server
,
&
mid
->
sequence_number
);
...
...
@@ -632,8 +632,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
if
(
receive_len
>=
sizeof
(
struct
smb_hdr
)
-
4
/* do not count RFC1001 header */
+
(
2
*
midQ
->
resp_buf
->
WordCount
)
+
2
/* bcc */
)
BCC
(
midQ
->
resp_buf
)
=
le16_to_cpu
(
BCC_LE
(
midQ
->
resp_buf
));
put_bcc
(
get_bcc_le
(
midQ
->
resp_buf
),
midQ
->
resp_buf
);
if
((
flags
&
CIFS_NO_RESP
)
==
0
)
midQ
->
resp_buf
=
NULL
;
/* mark it so buf will
not be freed by
...
...
@@ -776,7 +775,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
if
(
receive_len
>=
sizeof
(
struct
smb_hdr
)
-
4
/* do not count RFC1001 header */
+
(
2
*
out_buf
->
WordCount
)
+
2
/* bcc */
)
BCC
(
out_buf
)
=
le16_to_cpu
(
BCC_LE
(
out_buf
)
);
put_bcc
(
get_bcc_le
(
midQ
->
resp_buf
),
midQ
->
resp_buf
);
}
else
{
rc
=
-
EIO
;
cERROR
(
1
,
"Bad MID state?"
);
...
...
@@ -977,7 +976,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
if
(
receive_len
>=
sizeof
(
struct
smb_hdr
)
-
4
/* do not count RFC1001 header */
+
(
2
*
out_buf
->
WordCount
)
+
2
/* bcc */
)
BCC
(
out_buf
)
=
le16_to_cpu
(
BCC_LE
(
out_buf
)
);
put_bcc
(
get_bcc_le
(
out_buf
),
out_buf
);
out:
delete_mid
(
midQ
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment