Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
bf67b9be
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
bf67b9be
编写于
1月 21, 2011
作者:
S
Steve French
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-next'
上级
8d99641f
84cdf74e
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
402 addition
and
237 deletion
+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
未找到文件。
fs/cifs/cifs_fs_sb.h
浏览文件 @
bf67b9be
...
@@ -40,6 +40,7 @@
...
@@ -40,6 +40,7 @@
#define CIFS_MOUNT_FSCACHE 0x8000
/* local caching enabled */
#define CIFS_MOUNT_FSCACHE 0x8000
/* local caching enabled */
#define CIFS_MOUNT_MF_SYMLINKS 0x10000
/* Minshall+French Symlinks enabled */
#define CIFS_MOUNT_MF_SYMLINKS 0x10000
/* Minshall+French Symlinks enabled */
#define CIFS_MOUNT_MULTIUSER 0x20000
/* multiuser mount */
#define CIFS_MOUNT_MULTIUSER 0x20000
/* multiuser mount */
#define CIFS_MOUNT_STRICT_IO 0x40000
/* strict cache mode */
struct
cifs_sb_info
{
struct
cifs_sb_info
{
struct
rb_root
tlink_tree
;
struct
rb_root
tlink_tree
;
...
...
fs/cifs/cifs_unicode.c
浏览文件 @
bf67b9be
...
@@ -44,10 +44,14 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes,
...
@@ -44,10 +44,14 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes,
int
charlen
,
outlen
=
0
;
int
charlen
,
outlen
=
0
;
int
maxwords
=
maxbytes
/
2
;
int
maxwords
=
maxbytes
/
2
;
char
tmp
[
NLS_MAX_CHARSET_SIZE
];
char
tmp
[
NLS_MAX_CHARSET_SIZE
];
__u16
ftmp
;
for
(
i
=
0
;
i
<
maxwords
&&
from
[
i
];
i
++
)
{
for
(
i
=
0
;
i
<
maxwords
;
i
++
)
{
charlen
=
codepage
->
uni2char
(
le16_to_cpu
(
from
[
i
]),
tmp
,
ftmp
=
get_unaligned_le16
(
&
from
[
i
]);
NLS_MAX_CHARSET_SIZE
);
if
(
ftmp
==
0
)
break
;
charlen
=
codepage
->
uni2char
(
ftmp
,
tmp
,
NLS_MAX_CHARSET_SIZE
);
if
(
charlen
>
0
)
if
(
charlen
>
0
)
outlen
+=
charlen
;
outlen
+=
charlen
;
else
else
...
@@ -58,9 +62,9 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes,
...
@@ -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
* @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
* @cp - codepage to which character should be converted
* @mapchar - should character be mapped according to mapchars mount option?
* @mapchar - should character be mapped according to mapchars mount option?
*
*
...
@@ -69,7 +73,7 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes,
...
@@ -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).
* enough to hold the result of the conversion (at least NLS_MAX_CHARSET_SIZE).
*/
*/
static
int
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
)
bool
mapchar
)
{
{
int
len
=
1
;
int
len
=
1
;
...
@@ -82,7 +86,7 @@ cifs_mapchar(char *target, const __le16 src_char, const struct nls_table *cp,
...
@@ -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
* build_path_from_dentry are modified, as they use slash as
* separator.
* separator.
*/
*/
switch
(
le16_to_cpu
(
src_char
)
)
{
switch
(
src_char
)
{
case
UNI_COLON
:
case
UNI_COLON
:
*
target
=
':'
;
*
target
=
':'
;
break
;
break
;
...
@@ -109,8 +113,7 @@ cifs_mapchar(char *target, const __le16 src_char, const struct nls_table *cp,
...
@@ -109,8 +113,7 @@ cifs_mapchar(char *target, const __le16 src_char, const struct nls_table *cp,
return
len
;
return
len
;
cp_convert:
cp_convert:
len
=
cp
->
uni2char
(
le16_to_cpu
(
src_char
),
target
,
len
=
cp
->
uni2char
(
src_char
,
target
,
NLS_MAX_CHARSET_SIZE
);
NLS_MAX_CHARSET_SIZE
);
if
(
len
<=
0
)
{
if
(
len
<=
0
)
{
*
target
=
'?'
;
*
target
=
'?'
;
len
=
1
;
len
=
1
;
...
@@ -149,6 +152,7 @@ cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
...
@@ -149,6 +152,7 @@ cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
int
nullsize
=
nls_nullsize
(
codepage
);
int
nullsize
=
nls_nullsize
(
codepage
);
int
fromwords
=
fromlen
/
2
;
int
fromwords
=
fromlen
/
2
;
char
tmp
[
NLS_MAX_CHARSET_SIZE
];
char
tmp
[
NLS_MAX_CHARSET_SIZE
];
__u16
ftmp
;
/*
/*
* because the chars can be of varying widths, we need to take care
* 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,
...
@@ -158,19 +162,23 @@ cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
*/
*/
safelen
=
tolen
-
(
NLS_MAX_CHARSET_SIZE
+
nullsize
);
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
* check to see if converting this character might make the
* conversion bleed into the null terminator
* conversion bleed into the null terminator
*/
*/
if
(
outlen
>=
safelen
)
{
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
))
if
((
outlen
+
charlen
)
>
(
tolen
-
nullsize
))
break
;
break
;
}
}
/* put converted char into 'to' buffer */
/* 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
;
outlen
+=
charlen
;
}
}
...
@@ -193,24 +201,21 @@ cifs_strtoUCS(__le16 *to, const char *from, int len,
...
@@ -193,24 +201,21 @@ cifs_strtoUCS(__le16 *to, const char *from, int len,
{
{
int
charlen
;
int
charlen
;
int
i
;
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
)
{
for
(
i
=
0
;
len
&&
*
from
;
i
++
,
from
+=
charlen
,
len
-=
charlen
)
{
charlen
=
codepage
->
char2uni
(
from
,
len
,
&
wchar_to
);
/* works for 2.4.0 kernel or later */
charlen
=
codepage
->
char2uni
(
from
,
len
,
&
wchar_to
[
i
]);
if
(
charlen
<
1
)
{
if
(
charlen
<
1
)
{
cERROR
(
1
,
"strtoUCS: char2uni of
%d
returned %d"
,
cERROR
(
1
,
"strtoUCS: char2uni of
0x%x
returned %d"
,
(
int
)
*
from
,
charlen
);
*
from
,
charlen
);
/* A question mark */
/* A question mark */
to
[
i
]
=
cpu_to_le16
(
0x003f
)
;
wchar_to
=
0x003f
;
charlen
=
1
;
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
;
return
i
;
}
}
...
@@ -252,3 +257,79 @@ cifs_strndup_from_ucs(const char *src, const int maxlen, const bool is_unicode,
...
@@ -252,3 +257,79 @@ cifs_strndup_from_ucs(const char *src, const int maxlen, const bool is_unicode,
return
dst
;
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
浏览文件 @
bf67b9be
...
@@ -733,6 +733,25 @@ const struct file_operations cifs_file_ops = {
...
@@ -733,6 +733,25 @@ const struct file_operations cifs_file_ops = {
.
setlease
=
cifs_setlease
,
.
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
=
{
const
struct
file_operations
cifs_file_direct_ops
=
{
/* no aio, no readv -
/* no aio, no readv -
BB reevaluate whether they can be done with directio, no cache */
BB reevaluate whether they can be done with directio, no cache */
...
@@ -751,6 +770,7 @@ const struct file_operations cifs_file_direct_ops = {
...
@@ -751,6 +770,7 @@ const struct file_operations cifs_file_direct_ops = {
.
llseek
=
cifs_llseek
,
.
llseek
=
cifs_llseek
,
.
setlease
=
cifs_setlease
,
.
setlease
=
cifs_setlease
,
};
};
const
struct
file_operations
cifs_file_nobrl_ops
=
{
const
struct
file_operations
cifs_file_nobrl_ops
=
{
.
read
=
do_sync_read
,
.
read
=
do_sync_read
,
.
write
=
do_sync_write
,
.
write
=
do_sync_write
,
...
@@ -769,6 +789,24 @@ const struct file_operations cifs_file_nobrl_ops = {
...
@@ -769,6 +789,24 @@ const struct file_operations cifs_file_nobrl_ops = {
.
setlease
=
cifs_setlease
,
.
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
=
{
const
struct
file_operations
cifs_file_direct_nobrl_ops
=
{
/* no mmap, no aio, no readv -
/* no mmap, no aio, no readv -
BB reevaluate whether they can be done with directio, no cache */
BB reevaluate whether they can be done with directio, no cache */
...
...
fs/cifs/cifsfs.h
浏览文件 @
bf67b9be
...
@@ -61,6 +61,7 @@ extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
...
@@ -61,6 +61,7 @@ extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
struct
dentry
*
);
struct
dentry
*
);
extern
int
cifs_revalidate_file
(
struct
file
*
filp
);
extern
int
cifs_revalidate_file
(
struct
file
*
filp
);
extern
int
cifs_revalidate_dentry
(
struct
dentry
*
);
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_getattr
(
struct
vfsmount
*
,
struct
dentry
*
,
struct
kstat
*
);
extern
int
cifs_setattr
(
struct
dentry
*
,
struct
iattr
*
);
extern
int
cifs_setattr
(
struct
dentry
*
,
struct
iattr
*
);
...
@@ -72,19 +73,25 @@ extern const struct inode_operations cifs_dfs_referral_inode_operations;
...
@@ -72,19 +73,25 @@ extern const struct inode_operations cifs_dfs_referral_inode_operations;
/* Functions related to files and directories */
/* Functions related to files and directories */
extern
const
struct
file_operations
cifs_file_ops
;
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_direct_ops
;
/* if directio mnt */
extern
const
struct
file_operations
cifs_file_nobrl_ops
;
extern
const
struct
file_operations
cifs_file_strict_ops
;
/* if strictio mnt */
extern
const
struct
file_operations
cifs_file_direct_nobrl_ops
;
/* no brlocks */
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_open
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_close
(
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
int
cifs_closedir
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
ssize_t
cifs_user_read
(
struct
file
*
file
,
char
__user
*
read_data
,
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
,
extern
ssize_t
cifs_user_write
(
struct
file
*
file
,
const
char
__user
*
write_data
,
size_t
write_size
,
loff_t
*
poffset
);
size_t
write_size
,
loff_t
*
poffset
);
extern
int
cifs_lock
(
struct
file
*
,
int
,
struct
file_lock
*
);
extern
int
cifs_lock
(
struct
file
*
,
int
,
struct
file_lock
*
);
extern
int
cifs_fsync
(
struct
file
*
,
int
);
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_flush
(
struct
file
*
,
fl_owner_t
id
);
extern
int
cifs_file_mmap
(
struct
file
*
,
struct
vm_area_struct
*
);
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
const
struct
file_operations
cifs_dir_ops
;
extern
int
cifs_dir_open
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_dir_open
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_readdir
(
struct
file
*
file
,
void
*
direntry
,
filldir_t
filldir
);
extern
int
cifs_readdir
(
struct
file
*
file
,
void
*
direntry
,
filldir_t
filldir
);
...
...
fs/cifs/cifsglob.h
浏览文件 @
bf67b9be
...
@@ -161,6 +161,7 @@ struct TCP_Server_Info {
...
@@ -161,6 +161,7 @@ struct TCP_Server_Info {
int
srv_count
;
/* reference counter */
int
srv_count
;
/* reference counter */
/* 15 character server name + 0x20 16th byte indicating type = srv */
/* 15 character server name + 0x20 16th byte indicating type = srv */
char
server_RFC1001_name
[
RFC1001_NAME_LEN_WITH_NULL
];
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 */
char
*
hostname
;
/* hostname portion of UNC string */
struct
socket
*
ssocket
;
struct
socket
*
ssocket
;
struct
sockaddr_storage
dstaddr
;
struct
sockaddr_storage
dstaddr
;
...
@@ -168,25 +169,16 @@ struct TCP_Server_Info {
...
@@ -168,25 +169,16 @@ struct TCP_Server_Info {
wait_queue_head_t
response_q
;
wait_queue_head_t
response_q
;
wait_queue_head_t
request_q
;
/* if more than maxmpx to srvr must block*/
wait_queue_head_t
request_q
;
/* if more than maxmpx to srvr must block*/
struct
list_head
pending_mid_q
;
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
noblocksnd
;
/* use blocking sendmsg */
bool
noautotune
;
/* do not autotune send buf sizes */
bool
noautotune
;
/* do not autotune send buf sizes */
bool
tcp_nodelay
;
bool
tcp_nodelay
;
atomic_t
inFlight
;
/* number of requests on the wire to server */
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
mutex
srv_mutex
;
struct
task_struct
*
tsk
;
struct
task_struct
*
tsk
;
char
server_GUID
[
16
];
char
server_GUID
[
16
];
char
secMode
;
char
secMode
;
bool
session_estab
;
/* mark when very first sess is established */
u16
dialect
;
/* dialect index that server chose */
enum
securityEnum
secType
;
enum
securityEnum
secType
;
unsigned
int
maxReq
;
/* Clients should submit no more */
unsigned
int
maxReq
;
/* Clients should submit no more */
/* than maxReq distinct unanswered SMBs to the server when using */
/* than maxReq distinct unanswered SMBs to the server when using */
...
@@ -199,8 +191,6 @@ struct TCP_Server_Info {
...
@@ -199,8 +191,6 @@ struct TCP_Server_Info {
unsigned
int
max_vcs
;
/* maximum number of smb sessions, at least
unsigned
int
max_vcs
;
/* maximum number of smb sessions, at least
those that can be specified uniquely with
those that can be specified uniquely with
vcnumbers */
vcnumbers */
char
sessid
[
4
];
/* unique token id for this session */
/* (returned on Negotiate */
int
capabilities
;
/* allow selective disabling of caps by smb sess */
int
capabilities
;
/* allow selective disabling of caps by smb sess */
int
timeAdj
;
/* Adjust for difference in server time zone in sec */
int
timeAdj
;
/* Adjust for difference in server time zone in sec */
__u16
CurrentMid
;
/* multiplex id - rotating counter */
__u16
CurrentMid
;
/* multiplex id - rotating counter */
...
@@ -210,18 +200,20 @@ struct TCP_Server_Info {
...
@@ -210,18 +200,20 @@ struct TCP_Server_Info {
__u32
sequence_number
;
/* for signing, protected by srv_mutex */
__u32
sequence_number
;
/* for signing, protected by srv_mutex */
struct
session_key
session_key
;
struct
session_key
session_key
;
unsigned
long
lstrp
;
/* when we got last response from this server */
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 */
struct
cifs_secmech
secmech
;
/* crypto sec mech functs, descriptors */
/* extended security flavors that server supports */
/* 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_kerberos
;
/* supports plain Kerberos */
bool
sec_mskerberos
;
/* supports legacy MS 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 */
struct
delayed_work
echo
;
/* echo ping workqueue job */
#ifdef CONFIG_CIFS_FSCACHE
#ifdef CONFIG_CIFS_FSCACHE
struct
fscache_cookie
*
fscache
;
/* client index cache cookie */
struct
fscache_cookie
*
fscache
;
/* client index cache cookie */
#endif
#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 {
...
@@ -447,11 +439,11 @@ struct cifsInodeInfo {
/* BB add in lists for dirty pages i.e. write caching info for oplock */
/* BB add in lists for dirty pages i.e. write caching info for oplock */
struct
list_head
openFileList
;
struct
list_head
openFileList
;
__u32
cifsAttrs
;
/* e.g. DOS archive bit, sparse, compressed, system */
__u32
cifsAttrs
;
/* e.g. DOS archive bit, sparse, compressed, system */
unsigned
long
time
;
/* jiffies of last update/check of inode
*/
bool
clientCanCacheRead
;
/* read oplock
*/
bool
clientCanCache
Read
:
1
;
/* rea
d oplock */
bool
clientCanCache
All
;
/* read and writebehin
d oplock */
bool
clientCanCacheAll
:
1
;
/* read and writebehind oplock
*/
bool
delete_pending
;
/* DELETE_ON_CLOSE is set
*/
bool
delete_pending
:
1
;
/* DELETE_ON_CLOSE is set
*/
bool
invalid_mapping
;
/* pagecache is invalid
*/
bool
invalid_mapping
:
1
;
/* pagecache is invalid
*/
unsigned
long
time
;
/* jiffies of last update of inode
*/
u64
server_eof
;
/* current file size on server */
u64
server_eof
;
/* current file size on server */
u64
uniqueid
;
/* server inode number */
u64
uniqueid
;
/* server inode number */
u64
createtime
;
/* creation time on server */
u64
createtime
;
/* creation time on server */
...
...
fs/cifs/cifspdu.h
浏览文件 @
bf67b9be
...
@@ -23,6 +23,7 @@
...
@@ -23,6 +23,7 @@
#define _CIFSPDU_H
#define _CIFSPDU_H
#include <net/sock.h>
#include <net/sock.h>
#include <asm/unaligned.h>
#include "smbfsctl.h"
#include "smbfsctl.h"
#ifdef CONFIG_CIFS_WEAK_PW_HASH
#ifdef CONFIG_CIFS_WEAK_PW_HASH
...
@@ -426,11 +427,49 @@ struct smb_hdr {
...
@@ -426,11 +427,49 @@ struct smb_hdr {
__u16
Mid
;
__u16
Mid
;
__u8
WordCount
;
__u8
WordCount
;
}
__attribute__
((
packed
));
}
__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)))
/* given a pointer to an smb_hdr retrieve a char pointer to the byte count */
#define BCC_LE(smb_var) (*(__le16 *)((char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount)))
#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 */
/* 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)
* Computer Name Length (since Netbios name was length 16 with last byte 0x20)
...
...
fs/cifs/cifssmb.c
浏览文件 @
bf67b9be
...
@@ -331,37 +331,35 @@ smb_init_no_reconnect(int smb_command, int wct, struct cifsTconInfo *tcon,
...
@@ -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
)
static
int
validate_t2
(
struct
smb_t2_rsp
*
pSMB
)
{
{
int
rc
=
-
EINVAL
;
unsigned
int
total_size
;
int
total_size
;
char
*
pBCC
;
/* 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 */
/* check for parm and data offset going beyond end of smb */
if
(
pSMB
->
hdr
.
WordCount
>=
10
)
{
if
(
get_unaligned_le16
(
&
pSMB
->
t2_rsp
.
ParameterOffset
)
>
1024
||
if
((
le16_to_cpu
(
pSMB
->
t2_rsp
.
ParameterOffset
)
<=
1024
)
&&
get_unaligned_le16
(
&
pSMB
->
t2_rsp
.
DataOffset
)
>
1024
)
(
le16_to_cpu
(
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 */
/* check that bcc is at least as big as parms + data */
total_size
=
le16_to_cpu
(
pSMB
->
t2_rsp
.
ParameterCount
);
/* check that bcc is less than negotiated smb buffer */
if
(
total_size
<
512
)
{
total_size
=
get_unaligned_le16
(
&
pSMB
->
t2_rsp
.
ParameterCount
);
total_size
+=
if
(
total_size
>=
512
)
le16_to_cpu
(
pSMB
->
t2_rsp
.
DataCount
);
goto
vt2_err
;
/* BCC le converted in SendReceive */
pBCC
=
(
pSMB
->
hdr
.
WordCount
*
2
)
+
total_size
+=
get_unaligned_le16
(
&
pSMB
->
t2_rsp
.
DataCount
);
sizeof
(
struct
smb_hdr
)
+
if
(
total_size
>
get_bcc
(
&
pSMB
->
hdr
)
||
(
char
*
)
pSMB
;
total_size
>=
CIFSMaxBufSize
+
MAX_CIFS_HDR_SIZE
)
if
((
total_size
<=
(
*
(
u16
*
)
pBCC
))
&&
goto
vt2_err
;
(
total_size
<
CIFSMaxBufSize
+
MAX_CIFS_HDR_SIZE
))
{
return
0
;
return
0
;
vt2_err:
}
}
}
}
cifs_dump_mem
(
"Invalid transact2 SMB: "
,
(
char
*
)
pSMB
,
cifs_dump_mem
(
"Invalid transact2 SMB: "
,
(
char
*
)
pSMB
,
sizeof
(
struct
smb_t2_rsp
)
+
16
);
sizeof
(
struct
smb_t2_rsp
)
+
16
);
return
rc
;
return
-
EINVAL
;
}
}
int
int
CIFSSMBNegotiate
(
unsigned
int
xid
,
struct
cifsSesInfo
*
ses
)
CIFSSMBNegotiate
(
unsigned
int
xid
,
struct
cifsSesInfo
*
ses
)
{
{
...
@@ -452,7 +450,6 @@ 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
),
server
->
maxBuf
=
min
((
__u32
)
le16_to_cpu
(
rsp
->
MaxBufSize
),
(
__u32
)
CIFSMaxBufSize
+
MAX_CIFS_HDR_SIZE
);
(
__u32
)
CIFSMaxBufSize
+
MAX_CIFS_HDR_SIZE
);
server
->
max_vcs
=
le16_to_cpu
(
rsp
->
MaxNumberVcs
);
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
/* even though we do not use raw we might as well set this
accurately, in case we ever find a need for it */
accurately, in case we ever find a need for it */
if
((
le16_to_cpu
(
rsp
->
RawMode
)
&
RAW_ENABLE
)
==
RAW_ENABLE
)
{
if
((
le16_to_cpu
(
rsp
->
RawMode
)
&
RAW_ENABLE
)
==
RAW_ENABLE
)
{
...
@@ -566,7 +563,6 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
...
@@ -566,7 +563,6 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
(
__u32
)
CIFSMaxBufSize
+
MAX_CIFS_HDR_SIZE
);
(
__u32
)
CIFSMaxBufSize
+
MAX_CIFS_HDR_SIZE
);
server
->
max_rw
=
le32_to_cpu
(
pSMBr
->
MaxRawSize
);
server
->
max_rw
=
le32_to_cpu
(
pSMBr
->
MaxRawSize
);
cFYI
(
DBG2
,
"Max buf = %d"
,
ses
->
server
->
maxBuf
);
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
->
capabilities
=
le32_to_cpu
(
pSMBr
->
Capabilities
);
server
->
timeAdj
=
(
int
)(
__s16
)
le16_to_cpu
(
pSMBr
->
ServerTimeZone
);
server
->
timeAdj
=
(
int
)(
__s16
)
le16_to_cpu
(
pSMBr
->
ServerTimeZone
);
server
->
timeAdj
*=
60
;
server
->
timeAdj
*=
60
;
...
@@ -5611,7 +5607,7 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
...
@@ -5611,7 +5607,7 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
}
}
/* make sure list_len doesn't go past end of SMB */
/* 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
)
{
if
((
char
*
)
ea_response_data
+
list_len
>
end_of_smb
)
{
cFYI
(
1
,
"EA list appears to go beyond SMB"
);
cFYI
(
1
,
"EA list appears to go beyond SMB"
);
rc
=
-
EIO
;
rc
=
-
EIO
;
...
...
fs/cifs/connect.c
浏览文件 @
bf67b9be
...
@@ -232,9 +232,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
...
@@ -232,9 +232,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
static
int
check2ndT2
(
struct
smb_hdr
*
pSMB
,
unsigned
int
maxBufSize
)
static
int
check2ndT2
(
struct
smb_hdr
*
pSMB
,
unsigned
int
maxBufSize
)
{
{
struct
smb_t2_rsp
*
pSMBt
;
struct
smb_t2_rsp
*
pSMBt
;
int
total_data_size
;
int
data_in_this_rsp
;
int
remaining
;
int
remaining
;
__u16
total_data_size
,
data_in_this_rsp
;
if
(
pSMB
->
Command
!=
SMB_COM_TRANSACTION2
)
if
(
pSMB
->
Command
!=
SMB_COM_TRANSACTION2
)
return
0
;
return
0
;
...
@@ -248,8 +247,8 @@ static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
...
@@ -248,8 +247,8 @@ static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
pSMBt
=
(
struct
smb_t2_rsp
*
)
pSMB
;
pSMBt
=
(
struct
smb_t2_rsp
*
)
pSMB
;
total_data_size
=
le16_to_cpu
(
pSMBt
->
t2_rsp
.
TotalDataCount
);
total_data_size
=
get_unaligned_le16
(
&
pSMBt
->
t2_rsp
.
TotalDataCount
);
data_in_this_rsp
=
le16_to_cpu
(
pSMBt
->
t2_rsp
.
DataCount
);
data_in_this_rsp
=
get_unaligned_le16
(
&
pSMBt
->
t2_rsp
.
DataCount
);
remaining
=
total_data_size
-
data_in_this_rsp
;
remaining
=
total_data_size
-
data_in_this_rsp
;
...
@@ -275,21 +274,18 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
...
@@ -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
*
pSMB2
=
(
struct
smb_t2_rsp
*
)
psecond
;
struct
smb_t2_rsp
*
pSMBt
=
(
struct
smb_t2_rsp
*
)
pTargetSMB
;
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_target
;
char
*
data_area_of_buf2
;
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"
);
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
;
remaining
=
total_data_size
-
total_in_buf
;
...
@@ -299,28 +295,28 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
...
@@ -299,28 +295,28 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
if
(
remaining
==
0
)
/* nothing to do, ignore */
if
(
remaining
==
0
)
/* nothing to do, ignore */
return
0
;
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
)
{
if
(
remaining
<
total_in_buf2
)
{
cFYI
(
1
,
"transact2 2nd response contains too much data"
);
cFYI
(
1
,
"transact2 2nd response contains too much data"
);
}
}
/* find end of first SMB data area */
/* find end of first SMB data area */
data_area_of_target
=
(
char
*
)
&
pSMBt
->
hdr
.
Protocol
+
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 */
/* validate target area */
data_area_of_buf2
=
(
char
*
)
&
pSMB2
->
hdr
.
Protocol
+
data_area_of_buf2
=
(
char
*
)
&
pSMB2
->
hdr
.
Protocol
+
le16_to_cpu
(
pSMB2
->
t2_rsp
.
DataOffset
);
get_unaligned_le16
(
&
pSMB2
->
t2_rsp
.
DataOffset
);
data_area_of_target
+=
total_in_buf
;
data_area_of_target
+=
total_in_buf
;
/* copy second buffer into end of first buffer */
/* copy second buffer into end of first buffer */
memcpy
(
data_area_of_target
,
data_area_of_buf2
,
total_in_buf2
);
memcpy
(
data_area_of_target
,
data_area_of_buf2
,
total_in_buf2
);
total_in_buf
+=
total_in_buf2
;
total_in_buf
+=
total_in_buf2
;
p
SMBt
->
t2_rsp
.
DataCount
=
cpu_to_le16
(
total_in_buf
);
p
ut_unaligned_le16
(
total_in_buf
,
&
pSMBt
->
t2_rsp
.
DataCount
);
byte_count
=
le16_to_cpu
(
BCC_LE
(
pTargetSMB
)
);
byte_count
=
get_bcc_le
(
pTargetSMB
);
byte_count
+=
total_in_buf2
;
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
=
pTargetSMB
->
smb_buf_length
;
byte_count
+=
total_in_buf2
;
byte_count
+=
total_in_buf2
;
...
@@ -334,7 +330,6 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
...
@@ -334,7 +330,6 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
return
0
;
/* we are done */
return
0
;
/* we are done */
}
else
/* more responses to go */
}
else
/* more responses to go */
return
1
;
return
1
;
}
}
static
void
static
void
...
@@ -2937,8 +2932,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
...
@@ -2937,8 +2932,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
TCONX_RSP
*
pSMBr
;
TCONX_RSP
*
pSMBr
;
unsigned
char
*
bcc_ptr
;
unsigned
char
*
bcc_ptr
;
int
rc
=
0
;
int
rc
=
0
;
int
length
,
bytes_left
;
int
length
;
__u16
count
;
__u16
bytes_left
,
count
;
if
(
ses
==
NULL
)
if
(
ses
==
NULL
)
return
-
EIO
;
return
-
EIO
;
...
@@ -3032,7 +3027,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
...
@@ -3032,7 +3027,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
tcon
->
need_reconnect
=
false
;
tcon
->
need_reconnect
=
false
;
tcon
->
tid
=
smb_buffer_response
->
Tid
;
tcon
->
tid
=
smb_buffer_response
->
Tid
;
bcc_ptr
=
pByteArea
(
smb_buffer_response
);
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
);
length
=
strnlen
(
bcc_ptr
,
bytes_left
-
2
);
if
(
smb_buffer
->
Flags2
&
SMBFLG2_UNICODE
)
if
(
smb_buffer
->
Flags2
&
SMBFLG2_UNICODE
)
is_unicode
=
true
;
is_unicode
=
true
;
...
...
fs/cifs/file.c
浏览文件 @
bf67b9be
...
@@ -287,6 +287,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
...
@@ -287,6 +287,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
struct
inode
*
inode
=
cifs_file
->
dentry
->
d_inode
;
struct
inode
*
inode
=
cifs_file
->
dentry
->
d_inode
;
struct
cifsTconInfo
*
tcon
=
tlink_tcon
(
cifs_file
->
tlink
);
struct
cifsTconInfo
*
tcon
=
tlink_tcon
(
cifs_file
->
tlink
);
struct
cifsInodeInfo
*
cifsi
=
CIFS_I
(
inode
);
struct
cifsInodeInfo
*
cifsi
=
CIFS_I
(
inode
);
struct
cifs_sb_info
*
cifs_sb
=
CIFS_SB
(
inode
->
i_sb
);
struct
cifsLockInfo
*
li
,
*
tmp
;
struct
cifsLockInfo
*
li
,
*
tmp
;
spin_lock
(
&
cifs_file_list_lock
);
spin_lock
(
&
cifs_file_list_lock
);
...
@@ -302,6 +303,13 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
...
@@ -302,6 +303,13 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
if
(
list_empty
(
&
cifsi
->
openFileList
))
{
if
(
list_empty
(
&
cifsi
->
openFileList
))
{
cFYI
(
1
,
"closing last open instance for inode %p"
,
cFYI
(
1
,
"closing last open instance for inode %p"
,
cifs_file
->
dentry
->
d_inode
);
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
);
cifs_set_oplock_level
(
cifsi
,
0
);
}
}
spin_unlock
(
&
cifs_file_list_lock
);
spin_unlock
(
&
cifs_file_list_lock
);
...
@@ -1520,27 +1528,47 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
...
@@ -1520,27 +1528,47 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
return
rc
;
return
rc
;
}
}
int
cifs_fsync
(
struct
file
*
file
,
int
datasync
)
int
cifs_
strict_
fsync
(
struct
file
*
file
,
int
datasync
)
{
{
int
xid
;
int
xid
;
int
rc
=
0
;
int
rc
=
0
;
struct
cifsTconInfo
*
tcon
;
struct
cifsTconInfo
*
tcon
;
struct
cifsFileInfo
*
smbfile
=
file
->
private_data
;
struct
cifsFileInfo
*
smbfile
=
file
->
private_data
;
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
struct
cifs_sb_info
*
cifs_sb
=
CIFS_SB
(
inode
->
i_sb
);
xid
=
GetXid
();
xid
=
GetXid
();
cFYI
(
1
,
"Sync file - name: %s datasync: 0x%x"
,
cFYI
(
1
,
"Sync file - name: %s datasync: 0x%x"
,
file
->
f_path
.
dentry
->
d_name
.
name
,
datasync
);
file
->
f_path
.
dentry
->
d_name
.
name
,
datasync
);
rc
=
filemap_write_and_wait
(
inode
->
i_mapping
);
if
(
!
CIFS_I
(
inode
)
->
clientCanCacheRead
)
if
(
rc
==
0
)
{
cifs_invalidate_mapping
(
inode
);
struct
cifs_sb_info
*
cifs_sb
=
CIFS_SB
(
inode
->
i_sb
);
tcon
=
tlink_tcon
(
smbfile
->
tlink
);
tcon
=
tlink_tcon
(
smbfile
->
tlink
);
if
(
!
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NOSSYNC
))
if
(
!
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NOSSYNC
))
rc
=
CIFSSMBFlush
(
xid
,
tcon
,
smbfile
->
netfid
);
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
);
FreeXid
(
xid
);
return
rc
;
return
rc
;
...
@@ -1591,42 +1619,42 @@ int cifs_flush(struct file *file, fl_owner_t id)
...
@@ -1591,42 +1619,42 @@ int cifs_flush(struct file *file, fl_owner_t id)
return
rc
;
return
rc
;
}
}
ssize_t
cifs_user_read
(
struct
file
*
file
,
char
__user
*
read_data
,
static
ssize_t
size_t
read_size
,
loff_t
*
poffset
)
cifs_iovec_read
(
struct
file
*
file
,
const
struct
iovec
*
iov
,
unsigned
long
nr_segs
,
loff_t
*
poffset
)
{
{
int
rc
=
-
EACCES
;
int
rc
;
unsigned
int
bytes_read
=
0
;
int
xid
;
unsigned
int
total_read
=
0
;
unsigned
int
total_read
,
bytes_read
=
0
;
unsigned
int
current_read_size
;
size_t
len
,
cur_len
;
int
iov_offset
=
0
;
struct
cifs_sb_info
*
cifs_sb
;
struct
cifs_sb_info
*
cifs_sb
;
struct
cifsTconInfo
*
pTcon
;
struct
cifsTconInfo
*
pTcon
;
int
xid
;
struct
cifsFileInfo
*
open_file
;
struct
cifsFileInfo
*
open_file
;
char
*
smb_read_data
;
char
__user
*
current_offset
;
struct
smb_com_read_rsp
*
pSMBr
;
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
();
xid
=
GetXid
();
cifs_sb
=
CIFS_SB
(
file
->
f_path
.
dentry
->
d_sb
);
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
;
open_file
=
file
->
private_data
;
pTcon
=
tlink_tcon
(
open_file
->
tlink
);
pTcon
=
tlink_tcon
(
open_file
->
tlink
);
if
((
file
->
f_flags
&
O_ACCMODE
)
==
O_WRONLY
)
if
((
file
->
f_flags
&
O_ACCMODE
)
==
O_WRONLY
)
cFYI
(
1
,
"attempting read on write only file instance"
);
cFYI
(
1
,
"attempting read on write only file instance"
);
for
(
total_read
=
0
,
current_offset
=
read_data
;
for
(
total_read
=
0
;
total_read
<
len
;
total_read
+=
bytes_read
)
{
read_size
>
total_read
;
cur_len
=
min_t
(
const
size_t
,
len
-
total_read
,
cifs_sb
->
rsize
);
total_read
+=
bytes_read
,
current_offset
+=
bytes_read
)
{
current_read_size
=
min_t
(
const
int
,
read_size
-
total_read
,
cifs_sb
->
rsize
);
rc
=
-
EAGAIN
;
rc
=
-
EAGAIN
;
smb_read_data
=
NULL
;
read_data
=
NULL
;
while
(
rc
==
-
EAGAIN
)
{
while
(
rc
==
-
EAGAIN
)
{
int
buf_type
=
CIFS_NO_BUFFER
;
int
buf_type
=
CIFS_NO_BUFFER
;
if
(
open_file
->
invalidHandle
)
{
if
(
open_file
->
invalidHandle
)
{
...
@@ -1634,27 +1662,25 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
...
@@ -1634,27 +1662,25 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
if
(
rc
!=
0
)
if
(
rc
!=
0
)
break
;
break
;
}
}
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
open_file
->
netfid
,
open_file
->
netfid
,
cur_len
,
*
poffset
,
&
bytes_read
,
current_read_size
,
*
poffset
,
&
read_data
,
&
buf_type
);
&
bytes_read
,
&
smb_read_data
,
pSMBr
=
(
struct
smb_com_read_rsp
*
)
read_data
;
&
buf_type
);
if
(
read_data
)
{
pSMBr
=
(
struct
smb_com_read_rsp
*
)
smb_read_data
;
char
*
data_offset
=
read_data
+
4
+
if
(
smb_read_data
)
{
le16_to_cpu
(
pSMBr
->
DataOffset
);
if
(
copy_to_user
(
current_offset
,
if
(
memcpy_toiovecend
(
iov
,
data_offset
,
smb_read_data
+
iov_offset
,
bytes_read
))
4
/* RFC1001 length field */
+
le16_to_cpu
(
pSMBr
->
DataOffset
),
bytes_read
))
rc
=
-
EFAULT
;
rc
=
-
EFAULT
;
if
(
buf_type
==
CIFS_SMALL_BUFFER
)
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
)
else
if
(
buf_type
==
CIFS_LARGE_BUFFER
)
cifs_buf_release
(
smb_read_data
);
cifs_buf_release
(
read_data
);
smb_read_data
=
NULL
;
read_data
=
NULL
;
iov_offset
+=
bytes_read
;
}
}
}
}
if
(
rc
||
(
bytes_read
==
0
))
{
if
(
rc
||
(
bytes_read
==
0
))
{
if
(
total_read
)
{
if
(
total_read
)
{
break
;
break
;
...
@@ -1667,13 +1693,57 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
...
@@ -1667,13 +1693,57 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
*
poffset
+=
bytes_read
;
*
poffset
+=
bytes_read
;
}
}
}
}
FreeXid
(
xid
);
FreeXid
(
xid
);
return
total_read
;
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
,
static
ssize_t
cifs_read
(
struct
file
*
file
,
char
*
read_data
,
size_t
read_size
,
loff_t
*
poffset
)
loff_t
*
poffset
)
{
{
int
rc
=
-
EACCES
;
int
rc
=
-
EACCES
;
unsigned
int
bytes_read
=
0
;
unsigned
int
bytes_read
=
0
;
...
@@ -1741,6 +1811,21 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
...
@@ -1741,6 +1811,21 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
return
total_read
;
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
cifs_file_mmap
(
struct
file
*
file
,
struct
vm_area_struct
*
vma
)
{
{
int
rc
,
xid
;
int
rc
,
xid
;
...
...
fs/cifs/inode.c
浏览文件 @
bf67b9be
...
@@ -44,13 +44,17 @@ static void cifs_set_ops(struct inode *inode)
...
@@ -44,13 +44,17 @@ static void cifs_set_ops(struct inode *inode)
inode
->
i_fop
=
&
cifs_file_direct_nobrl_ops
;
inode
->
i_fop
=
&
cifs_file_direct_nobrl_ops
;
else
else
inode
->
i_fop
=
&
cifs_file_direct_ops
;
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
)
}
else
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
inode
->
i_fop
=
&
cifs_file_nobrl_ops
;
inode
->
i_fop
=
&
cifs_file_nobrl_ops
;
else
{
/* not direct, send byte range locks */
else
{
/* not direct, send byte range locks */
inode
->
i_fop
=
&
cifs_file_ops
;
inode
->
i_fop
=
&
cifs_file_ops
;
}
}
/* check if server can support readpages */
/* check if server can support readpages */
if
(
cifs_sb_master_tcon
(
cifs_sb
)
->
ses
->
server
->
maxBuf
<
if
(
cifs_sb_master_tcon
(
cifs_sb
)
->
ses
->
server
->
maxBuf
<
PAGE_CACHE_SIZE
+
MAX_CIFS_HDR_SIZE
)
PAGE_CACHE_SIZE
+
MAX_CIFS_HDR_SIZE
)
...
@@ -1679,7 +1683,7 @@ cifs_inode_needs_reval(struct inode *inode)
...
@@ -1679,7 +1683,7 @@ cifs_inode_needs_reval(struct inode *inode)
/*
/*
* Zap the cache. Called when invalid_mapping flag is set.
* Zap the cache. Called when invalid_mapping flag is set.
*/
*/
static
void
void
cifs_invalidate_mapping
(
struct
inode
*
inode
)
cifs_invalidate_mapping
(
struct
inode
*
inode
)
{
{
int
rc
;
int
rc
;
...
...
fs/cifs/misc.c
浏览文件 @
bf67b9be
...
@@ -637,77 +637,6 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
...
@@ -637,77 +637,6 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
return
;
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
void
cifs_autodisable_serverino
(
struct
cifs_sb_info
*
cifs_sb
)
cifs_autodisable_serverino
(
struct
cifs_sb_info
*
cifs_sb
)
{
{
...
...
fs/cifs/netmisc.c
浏览文件 @
bf67b9be
...
@@ -916,14 +916,14 @@ unsigned int
...
@@ -916,14 +916,14 @@ unsigned int
smbCalcSize
(
struct
smb_hdr
*
ptr
)
smbCalcSize
(
struct
smb_hdr
*
ptr
)
{
{
return
(
sizeof
(
struct
smb_hdr
)
+
(
2
*
ptr
->
WordCount
)
+
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
unsigned
int
smbCalcSize_LE
(
struct
smb_hdr
*
ptr
)
smbCalcSize_LE
(
struct
smb_hdr
*
ptr
)
{
{
return
(
sizeof
(
struct
smb_hdr
)
+
(
2
*
ptr
->
WordCount
)
+
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 */
/* The following are taken from fs/ntfs/util.c */
...
...
fs/cifs/sess.c
浏览文件 @
bf67b9be
...
@@ -277,7 +277,7 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
...
@@ -277,7 +277,7 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
}
}
static
void
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
)
const
struct
nls_table
*
nls_cp
)
{
{
int
len
;
int
len
;
...
@@ -323,7 +323,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
...
@@ -323,7 +323,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
return
;
return
;
}
}
static
int
decode_ascii_ssetup
(
char
**
pbcc_area
,
int
bleft
,
static
int
decode_ascii_ssetup
(
char
**
pbcc_area
,
__u16
bleft
,
struct
cifsSesInfo
*
ses
,
struct
cifsSesInfo
*
ses
,
const
struct
nls_table
*
nls_cp
)
const
struct
nls_table
*
nls_cp
)
{
{
...
@@ -575,12 +575,11 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
...
@@ -575,12 +575,11 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
char
*
str_area
;
char
*
str_area
;
SESSION_SETUP_ANDX
*
pSMB
;
SESSION_SETUP_ANDX
*
pSMB
;
__u32
capabilities
;
__u32
capabilities
;
int
count
;
__u16
count
;
int
resp_buf_type
;
int
resp_buf_type
;
struct
kvec
iov
[
3
];
struct
kvec
iov
[
3
];
enum
securityEnum
type
;
enum
securityEnum
type
;
__u16
action
;
__u16
action
,
bytes_remaining
;
int
bytes_remaining
;
struct
key
*
spnego_key
=
NULL
;
struct
key
*
spnego_key
=
NULL
;
__le32
phase
=
NtLmNegotiate
;
/* NTLMSSP, if needed, is multistage */
__le32
phase
=
NtLmNegotiate
;
/* NTLMSSP, if needed, is multistage */
u16
blob_len
;
u16
blob_len
;
...
@@ -876,7 +875,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
...
@@ -876,7 +875,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
count
=
iov
[
1
].
iov_len
+
iov
[
2
].
iov_len
;
count
=
iov
[
1
].
iov_len
+
iov
[
2
].
iov_len
;
smb_buf
->
smb_buf_length
+=
count
;
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
,
rc
=
SendReceive2
(
xid
,
ses
,
iov
,
3
/* num_iovecs */
,
&
resp_buf_type
,
CIFS_LOG_ERROR
);
CIFS_LOG_ERROR
);
...
@@ -910,7 +909,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
...
@@ -910,7 +909,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
cFYI
(
1
,
"UID = %d "
,
ses
->
Suid
);
cFYI
(
1
,
"UID = %d "
,
ses
->
Suid
);
/* response can have either 3 or 4 word count - Samba sends 3 */
/* response can have either 3 or 4 word count - Samba sends 3 */
/* and lanman response is 3 */
/* and lanman response is 3 */
bytes_remaining
=
BCC
(
smb_buf
);
bytes_remaining
=
get_bcc
(
smb_buf
);
bcc_ptr
=
pByteArea
(
smb_buf
);
bcc_ptr
=
pByteArea
(
smb_buf
);
if
(
smb_buf
->
WordCount
==
4
)
{
if
(
smb_buf
->
WordCount
==
4
)
{
...
...
fs/cifs/transport.c
浏览文件 @
bf67b9be
...
@@ -484,7 +484,7 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
...
@@ -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
->
smb_buf_length
=
sizeof
(
struct
smb_hdr
)
-
4
+
2
;
in_buf
->
Command
=
SMB_COM_NT_CANCEL
;
in_buf
->
Command
=
SMB_COM_NT_CANCEL
;
in_buf
->
WordCount
=
0
;
in_buf
->
WordCount
=
0
;
BCC_LE
(
in_buf
)
=
0
;
put_bcc_le
(
0
,
in_buf
)
;
mutex_lock
(
&
server
->
srv_mutex
);
mutex_lock
(
&
server
->
srv_mutex
);
rc
=
cifs_sign_smb
(
in_buf
,
server
,
&
mid
->
sequence_number
);
rc
=
cifs_sign_smb
(
in_buf
,
server
,
&
mid
->
sequence_number
);
...
@@ -632,8 +632,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
...
@@ -632,8 +632,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
if
(
receive_len
>=
sizeof
(
struct
smb_hdr
)
-
4
if
(
receive_len
>=
sizeof
(
struct
smb_hdr
)
-
4
/* do not count RFC1001 header */
+
/* do not count RFC1001 header */
+
(
2
*
midQ
->
resp_buf
->
WordCount
)
+
2
/* bcc */
)
(
2
*
midQ
->
resp_buf
->
WordCount
)
+
2
/* bcc */
)
BCC
(
midQ
->
resp_buf
)
=
put_bcc
(
get_bcc_le
(
midQ
->
resp_buf
),
midQ
->
resp_buf
);
le16_to_cpu
(
BCC_LE
(
midQ
->
resp_buf
));
if
((
flags
&
CIFS_NO_RESP
)
==
0
)
if
((
flags
&
CIFS_NO_RESP
)
==
0
)
midQ
->
resp_buf
=
NULL
;
/* mark it so buf will
midQ
->
resp_buf
=
NULL
;
/* mark it so buf will
not be freed by
not be freed by
...
@@ -776,7 +775,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
...
@@ -776,7 +775,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
if
(
receive_len
>=
sizeof
(
struct
smb_hdr
)
-
4
if
(
receive_len
>=
sizeof
(
struct
smb_hdr
)
-
4
/* do not count RFC1001 header */
+
/* do not count RFC1001 header */
+
(
2
*
out_buf
->
WordCount
)
+
2
/* bcc */
)
(
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
{
}
else
{
rc
=
-
EIO
;
rc
=
-
EIO
;
cERROR
(
1
,
"Bad MID state?"
);
cERROR
(
1
,
"Bad MID state?"
);
...
@@ -977,7 +976,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
...
@@ -977,7 +976,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
if
(
receive_len
>=
sizeof
(
struct
smb_hdr
)
-
4
if
(
receive_len
>=
sizeof
(
struct
smb_hdr
)
-
4
/* do not count RFC1001 header */
+
/* do not count RFC1001 header */
+
(
2
*
out_buf
->
WordCount
)
+
2
/* bcc */
)
(
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:
out:
delete_mid
(
midQ
);
delete_mid
(
midQ
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录