Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
ec637e3f
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
ec637e3f
编写于
12月 12, 2005
作者:
S
Steve French
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[CIFS] Avoid extra large buffer allocation (and memcpy) in cifs_readpages
Signed-off-by:
N
Steve French
<
sfrench@us.ibm.com
>
上级
c89a86bb
变更
11
显示空白变更内容
内联
并排
Showing
11 changed file
with
156 addition
and
108 deletion
+156
-108
fs/cifs/cifs_debug.c
fs/cifs/cifs_debug.c
+19
-20
fs/cifs/cifsfs.c
fs/cifs/cifsfs.c
+3
-2
fs/cifs/cifsglob.h
fs/cifs/cifsglob.h
+7
-1
fs/cifs/cifspdu.h
fs/cifs/cifspdu.h
+5
-1
fs/cifs/cifsproto.h
fs/cifs/cifsproto.h
+8
-6
fs/cifs/cifssmb.c
fs/cifs/cifssmb.c
+58
-35
fs/cifs/connect.c
fs/cifs/connect.c
+1
-1
fs/cifs/file.c
fs/cifs/file.c
+32
-20
fs/cifs/inode.c
fs/cifs/inode.c
+3
-2
fs/cifs/misc.c
fs/cifs/misc.c
+1
-1
fs/cifs/transport.c
fs/cifs/transport.c
+19
-19
未找到文件。
fs/cifs/cifs_debug.c
浏览文件 @
ec637e3f
...
@@ -401,8 +401,8 @@ static read_proc_t ntlmv2_enabled_read;
...
@@ -401,8 +401,8 @@ static read_proc_t ntlmv2_enabled_read;
static
write_proc_t
ntlmv2_enabled_write
;
static
write_proc_t
ntlmv2_enabled_write
;
static
read_proc_t
packet_signing_enabled_read
;
static
read_proc_t
packet_signing_enabled_read
;
static
write_proc_t
packet_signing_enabled_write
;
static
write_proc_t
packet_signing_enabled_write
;
static
read_proc_t
quota
Enabled_read
;
static
read_proc_t
experim
Enabled_read
;
static
write_proc_t
quota
Enabled_write
;
static
write_proc_t
experim
Enabled_write
;
static
read_proc_t
linuxExtensionsEnabled_read
;
static
read_proc_t
linuxExtensionsEnabled_read
;
static
write_proc_t
linuxExtensionsEnabled_write
;
static
write_proc_t
linuxExtensionsEnabled_write
;
...
@@ -442,9 +442,9 @@ cifs_proc_init(void)
...
@@ -442,9 +442,9 @@ cifs_proc_init(void)
pde
->
write_proc
=
oplockEnabled_write
;
pde
->
write_proc
=
oplockEnabled_write
;
pde
=
create_proc_read_entry
(
"Experimental"
,
0
,
proc_fs_cifs
,
pde
=
create_proc_read_entry
(
"Experimental"
,
0
,
proc_fs_cifs
,
quota
Enabled_read
,
NULL
);
experim
Enabled_read
,
NULL
);
if
(
pde
)
if
(
pde
)
pde
->
write_proc
=
quota
Enabled_write
;
pde
->
write_proc
=
experim
Enabled_write
;
pde
=
create_proc_read_entry
(
"LinuxExtensionsEnabled"
,
0
,
proc_fs_cifs
,
pde
=
create_proc_read_entry
(
"LinuxExtensionsEnabled"
,
0
,
proc_fs_cifs
,
linuxExtensionsEnabled_read
,
NULL
);
linuxExtensionsEnabled_read
,
NULL
);
...
@@ -586,14 +586,13 @@ oplockEnabled_write(struct file *file, const char __user *buffer,
...
@@ -586,14 +586,13 @@ oplockEnabled_write(struct file *file, const char __user *buffer,
}
}
static
int
static
int
quota
Enabled_read
(
char
*
page
,
char
**
start
,
off_t
off
,
experim
Enabled_read
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
int
count
,
int
*
eof
,
void
*
data
)
{
{
int
len
;
int
len
;
len
=
sprintf
(
page
,
"%d
\n
"
,
experimEnabled
);
len
=
sprintf
(
page
,
"%d
\n
"
,
experimEnabled
);
/* could also check if quotas are enabled in kernel
as a whole first */
len
-=
off
;
len
-=
off
;
*
start
=
page
+
off
;
*
start
=
page
+
off
;
...
@@ -608,7 +607,7 @@ quotaEnabled_read(char *page, char **start, off_t off,
...
@@ -608,7 +607,7 @@ quotaEnabled_read(char *page, char **start, off_t off,
return
len
;
return
len
;
}
}
static
int
static
int
quota
Enabled_write
(
struct
file
*
file
,
const
char
__user
*
buffer
,
experim
Enabled_write
(
struct
file
*
file
,
const
char
__user
*
buffer
,
unsigned
long
count
,
void
*
data
)
unsigned
long
count
,
void
*
data
)
{
{
char
c
;
char
c
;
...
@@ -621,6 +620,8 @@ quotaEnabled_write(struct file *file, const char __user *buffer,
...
@@ -621,6 +620,8 @@ quotaEnabled_write(struct file *file, const char __user *buffer,
experimEnabled
=
0
;
experimEnabled
=
0
;
else
if
(
c
==
'1'
||
c
==
'y'
||
c
==
'Y'
)
else
if
(
c
==
'1'
||
c
==
'y'
||
c
==
'Y'
)
experimEnabled
=
1
;
experimEnabled
=
1
;
else
if
(
c
==
'2'
)
experimEnabled
=
2
;
return
count
;
return
count
;
}
}
...
@@ -632,8 +633,6 @@ linuxExtensionsEnabled_read(char *page, char **start, off_t off,
...
@@ -632,8 +633,6 @@ linuxExtensionsEnabled_read(char *page, char **start, off_t off,
int
len
;
int
len
;
len
=
sprintf
(
page
,
"%d
\n
"
,
linuxExtEnabled
);
len
=
sprintf
(
page
,
"%d
\n
"
,
linuxExtEnabled
);
/* could also check if quotas are enabled in kernel
as a whole first */
len
-=
off
;
len
-=
off
;
*
start
=
page
+
off
;
*
start
=
page
+
off
;
...
...
fs/cifs/cifsfs.c
浏览文件 @
ec637e3f
...
@@ -733,7 +733,7 @@ cifs_init_request_bufs(void)
...
@@ -733,7 +733,7 @@ cifs_init_request_bufs(void)
kmem_cache_destroy
(
cifs_req_cachep
);
kmem_cache_destroy
(
cifs_req_cachep
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
/*
256 (MAX_CIFS_HD
R_SIZE bytes is enough for most SMB responses and
/*
MAX_CIFS_SMALL_BUFFE
R_SIZE bytes is enough for most SMB responses and
almost all handle based requests (but not write response, nor is it
almost all handle based requests (but not write response, nor is it
sufficient for path based requests). A smaller size would have
sufficient for path based requests). A smaller size would have
been more efficient (compacting multiple slab items on one 4k page)
been more efficient (compacting multiple slab items on one 4k page)
...
@@ -742,7 +742,8 @@ cifs_init_request_bufs(void)
...
@@ -742,7 +742,8 @@ cifs_init_request_bufs(void)
efficient to alloc 1 per page off the slab compared to 17K (5page)
efficient to alloc 1 per page off the slab compared to 17K (5page)
alloc of large cifs buffers even when page debugging is on */
alloc of large cifs buffers even when page debugging is on */
cifs_sm_req_cachep
=
kmem_cache_create
(
"cifs_small_rq"
,
cifs_sm_req_cachep
=
kmem_cache_create
(
"cifs_small_rq"
,
MAX_CIFS_HDR_SIZE
,
0
,
SLAB_HWCACHE_ALIGN
,
NULL
,
NULL
);
MAX_CIFS_SMALL_BUFFER_SIZE
,
0
,
SLAB_HWCACHE_ALIGN
,
NULL
,
NULL
);
if
(
cifs_sm_req_cachep
==
NULL
)
{
if
(
cifs_sm_req_cachep
==
NULL
)
{
mempool_destroy
(
cifs_req_poolp
);
mempool_destroy
(
cifs_req_poolp
);
kmem_cache_destroy
(
cifs_req_cachep
);
kmem_cache_destroy
(
cifs_req_cachep
);
...
...
fs/cifs/cifsglob.h
浏览文件 @
ec637e3f
...
@@ -285,6 +285,7 @@ struct cifs_search_info {
...
@@ -285,6 +285,7 @@ struct cifs_search_info {
unsigned
endOfSearch
:
1
;
unsigned
endOfSearch
:
1
;
unsigned
emptyDir
:
1
;
unsigned
emptyDir
:
1
;
unsigned
unicode
:
1
;
unsigned
unicode
:
1
;
unsigned
smallBuf
:
1
;
/* so we know which buf_release function to call */
};
};
struct
cifsFileInfo
{
struct
cifsFileInfo
{
...
@@ -420,7 +421,12 @@ struct dir_notify_req {
...
@@ -420,7 +421,12 @@ struct dir_notify_req {
#define MID_RESPONSE_RECEIVED 4
#define MID_RESPONSE_RECEIVED 4
#define MID_RETRY_NEEDED 8
/* session closed while this request out */
#define MID_RETRY_NEEDED 8
/* session closed while this request out */
#define MID_NO_RESP_NEEDED 0x10
#define MID_NO_RESP_NEEDED 0x10
#define MID_SMALL_BUFFER 0x20
/* 112 byte response buffer instead of 4K */
/* Types of response buffer returned from SendReceive2 */
#define CIFS_NO_BUFFER 0
/* Response buffer not returned */
#define CIFS_SMALL_BUFFER 1
#define CIFS_LARGE_BUFFER 2
#define CIFS_IOVEC 4
/* array of response buffers */
/*
/*
*****************************************************************
*****************************************************************
...
...
fs/cifs/cifspdu.h
浏览文件 @
ec637e3f
...
@@ -80,7 +80,11 @@
...
@@ -80,7 +80,11 @@
#define NT_TRANSACT_GET_USER_QUOTA 0x07
#define NT_TRANSACT_GET_USER_QUOTA 0x07
#define NT_TRANSACT_SET_USER_QUOTA 0x08
#define NT_TRANSACT_SET_USER_QUOTA 0x08
#define MAX_CIFS_HDR_SIZE 256
/* is future chained NTCreateXReadX bigger? */
#define MAX_CIFS_SMALL_BUFFER_SIZE 448
/* big enough for most */
/* future chained NTCreateXReadX bigger, but for time being NTCreateX biggest */
/* among the requests (NTCreateX response is bigger with wct of 34) */
#define MAX_CIFS_HDR_SIZE 0x58
/* 4 len + 32 hdr + (2*24 wct) + 2 bct + 2 pad */
#define CIFS_SMALL_PATH 120
/* allows for (448-88)/3 */
/* internal cifs vfs structures */
/* internal cifs vfs structures */
/*****************************************************************
/*****************************************************************
...
...
fs/cifs/cifsproto.h
浏览文件 @
ec637e3f
...
@@ -49,7 +49,7 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
...
@@ -49,7 +49,7 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
int
*
/* bytes returned */
,
const
int
long_op
);
int
*
/* bytes returned */
,
const
int
long_op
);
extern
int
SendReceive2
(
const
unsigned
int
/* xid */
,
struct
cifsSesInfo
*
,
extern
int
SendReceive2
(
const
unsigned
int
/* xid */
,
struct
cifsSesInfo
*
,
struct
kvec
*
,
int
/* nvec to send */
,
struct
kvec
*
,
int
/* nvec to send */
,
int
*
/*
bytes
returned */
,
const
int
long_op
);
int
*
/*
type of buf
returned */
,
const
int
long_op
);
extern
int
checkSMBhdr
(
struct
smb_hdr
*
smb
,
__u16
mid
);
extern
int
checkSMBhdr
(
struct
smb_hdr
*
smb
,
__u16
mid
);
extern
int
checkSMB
(
struct
smb_hdr
*
smb
,
__u16
mid
,
int
length
);
extern
int
checkSMB
(
struct
smb_hdr
*
smb
,
__u16
mid
,
int
length
);
extern
int
is_valid_oplock_break
(
struct
smb_hdr
*
smb
);
extern
int
is_valid_oplock_break
(
struct
smb_hdr
*
smb
);
...
@@ -94,7 +94,8 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
...
@@ -94,7 +94,8 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
extern
int
CIFSFindFirst
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
extern
int
CIFSFindFirst
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
char
*
searchName
,
const
struct
nls_table
*
nls_codepage
,
const
char
*
searchName
,
const
struct
nls_table
*
nls_codepage
,
__u16
*
searchHandle
,
struct
cifs_search_info
*
psrch_inf
,
int
map
,
const
char
dirsep
);
__u16
*
searchHandle
,
struct
cifs_search_info
*
psrch_inf
,
int
map
,
const
char
dirsep
);
extern
int
CIFSFindNext
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
extern
int
CIFSFindNext
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
__u16
searchHandle
,
struct
cifs_search_info
*
psrch_inf
);
__u16
searchHandle
,
struct
cifs_search_info
*
psrch_inf
);
...
@@ -231,7 +232,8 @@ extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
...
@@ -231,7 +232,8 @@ extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
extern
int
CIFSSMBRead
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
extern
int
CIFSSMBRead
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
int
netfid
,
unsigned
int
count
,
const
int
netfid
,
unsigned
int
count
,
const
__u64
lseek
,
unsigned
int
*
nbytes
,
char
**
buf
);
const
__u64
lseek
,
unsigned
int
*
nbytes
,
char
**
buf
,
int
*
return_buf_type
);
extern
int
CIFSSMBWrite
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
extern
int
CIFSSMBWrite
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
int
netfid
,
const
unsigned
int
count
,
const
int
netfid
,
const
unsigned
int
count
,
const
__u64
lseek
,
unsigned
int
*
nbytes
,
const
__u64
lseek
,
unsigned
int
*
nbytes
,
...
...
fs/cifs/cifssmb.c
浏览文件 @
ec637e3f
...
@@ -958,21 +958,19 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
...
@@ -958,21 +958,19 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
return
rc
;
return
rc
;
}
}
/* If no buffer passed in, then caller wants to do the copy
as in the case of readpages so the SMB buffer must be
freed by the caller */
int
int
CIFSSMBRead
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
CIFSSMBRead
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
int
netfid
,
const
unsigned
int
count
,
const
int
netfid
,
const
unsigned
int
count
,
const
__u64
lseek
,
unsigned
int
*
nbytes
,
char
**
buf
)
const
__u64
lseek
,
unsigned
int
*
nbytes
,
char
**
buf
,
int
*
pbuf_type
)
{
{
int
rc
=
-
EACCES
;
int
rc
=
-
EACCES
;
READ_REQ
*
pSMB
=
NULL
;
READ_REQ
*
pSMB
=
NULL
;
READ_RSP
*
pSMBr
=
NULL
;
READ_RSP
*
pSMBr
=
NULL
;
char
*
pReadData
=
NULL
;
char
*
pReadData
=
NULL
;
int
bytes_returned
;
int
wct
;
int
wct
;
int
resp_buf_type
=
0
;
struct
kvec
iov
[
1
];
cFYI
(
1
,(
"Reading %d bytes on fid %d"
,
count
,
netfid
));
cFYI
(
1
,(
"Reading %d bytes on fid %d"
,
count
,
netfid
));
if
(
tcon
->
ses
->
capabilities
&
CAP_LARGE_FILES
)
if
(
tcon
->
ses
->
capabilities
&
CAP_LARGE_FILES
)
...
@@ -981,8 +979,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
...
@@ -981,8 +979,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
wct
=
10
;
/* old style read */
wct
=
10
;
/* old style read */
*
nbytes
=
0
;
*
nbytes
=
0
;
rc
=
smb_init
(
SMB_COM_READ_ANDX
,
wct
,
tcon
,
(
void
**
)
&
pSMB
,
rc
=
small_smb_init
(
SMB_COM_READ_ANDX
,
wct
,
tcon
,
(
void
**
)
&
pSMB
);
(
void
**
)
&
pSMBr
);
if
(
rc
)
if
(
rc
)
return
rc
;
return
rc
;
...
@@ -1010,9 +1007,13 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
...
@@ -1010,9 +1007,13 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
pSMBW
->
ByteCount
=
0
;
pSMBW
->
ByteCount
=
0
;
}
}
rc
=
SendReceive
(
xid
,
tcon
->
ses
,
(
struct
smb_hdr
*
)
pSMB
,
iov
[
0
].
iov_base
=
(
char
*
)
pSMB
;
(
struct
smb_hdr
*
)
pSMBr
,
&
bytes_returned
,
0
);
iov
[
0
].
iov_len
=
pSMB
->
hdr
.
smb_buf_length
+
4
;
rc
=
SendReceive2
(
xid
,
tcon
->
ses
,
iov
,
1
/* num iovecs */
,
&
resp_buf_type
,
0
);
cifs_stats_inc
(
&
tcon
->
num_reads
);
cifs_stats_inc
(
&
tcon
->
num_reads
);
pSMBr
=
(
READ_RSP
*
)
iov
[
0
].
iov_base
;
if
(
rc
)
{
if
(
rc
)
{
cERROR
(
1
,
(
"Send error in read = %d"
,
rc
));
cERROR
(
1
,
(
"Send error in read = %d"
,
rc
));
}
else
{
}
else
{
...
@@ -1028,8 +1029,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
...
@@ -1028,8 +1029,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
rc
=
-
EIO
;
rc
=
-
EIO
;
*
nbytes
=
0
;
*
nbytes
=
0
;
}
else
{
}
else
{
pReadData
=
pReadData
=
(
char
*
)
(
&
pSMBr
->
hdr
.
Protocol
)
+
(
char
*
)
(
&
pSMBr
->
hdr
.
Protocol
)
+
le16_to_cpu
(
pSMBr
->
DataOffset
);
le16_to_cpu
(
pSMBr
->
DataOffset
);
/* if(rc = copy_to_user(buf, pReadData, data_length)) {
/* if(rc = copy_to_user(buf, pReadData, data_length)) {
cERROR(1,("Faulting on read rc = %d",rc));
cERROR(1,("Faulting on read rc = %d",rc));
...
@@ -1039,16 +1039,27 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
...
@@ -1039,16 +1039,27 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
memcpy
(
*
buf
,
pReadData
,
data_length
);
memcpy
(
*
buf
,
pReadData
,
data_length
);
}
}
}
}
if
(
*
buf
)
cifs_buf_release
(
pSMB
);
cifs_small_buf_release
(
pSMB
);
else
if
(
*
buf
)
{
*
buf
=
(
char
*
)
pSMB
;
if
(
resp_buf_type
==
CIFS_SMALL_BUFFER
)
cifs_small_buf_release
(
iov
[
0
].
iov_base
);
else
if
(
resp_buf_type
==
CIFS_LARGE_BUFFER
)
cifs_buf_release
(
iov
[
0
].
iov_base
);
}
else
/* return buffer to caller to free */
/* BB FIXME how do we tell caller if it is not a large buffer */
{
*
buf
=
iov
[
0
].
iov_base
;
if
(
resp_buf_type
==
CIFS_SMALL_BUFFER
)
*
pbuf_type
=
CIFS_SMALL_BUFFER
;
else
if
(
resp_buf_type
==
CIFS_LARGE_BUFFER
)
*
pbuf_type
=
CIFS_LARGE_BUFFER
;
}
/* Note: On -EAGAIN error only caller can retry on handle based calls
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
since file handle passed in no longer valid */
return
rc
;
return
rc
;
}
}
int
int
CIFSSMBWrite
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
CIFSSMBWrite
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
int
netfid
,
const
unsigned
int
count
,
const
int
netfid
,
const
unsigned
int
count
,
...
@@ -1163,10 +1174,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
...
@@ -1163,10 +1174,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
{
{
int
rc
=
-
EACCES
;
int
rc
=
-
EACCES
;
WRITE_REQ
*
pSMB
=
NULL
;
WRITE_REQ
*
pSMB
=
NULL
;
int
bytes_returned
,
wct
;
int
wct
;
int
smb_hdr_len
;
int
smb_hdr_len
;
int
resp_buf_type
=
0
;
/* BB removeme BB */
cFYI
(
1
,(
"write2 at %lld %d bytes"
,
(
long
long
)
offset
,
count
));
cFYI
(
1
,(
"write2 at %lld %d bytes"
,
(
long
long
)
offset
,
count
));
if
(
tcon
->
ses
->
capabilities
&
CAP_LARGE_FILES
)
if
(
tcon
->
ses
->
capabilities
&
CAP_LARGE_FILES
)
...
@@ -1209,22 +1220,34 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
...
@@ -1209,22 +1220,34 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
pSMBW
->
ByteCount
=
cpu_to_le16
(
count
+
5
);
pSMBW
->
ByteCount
=
cpu_to_le16
(
count
+
5
);
}
}
iov
[
0
].
iov_base
=
pSMB
;
iov
[
0
].
iov_base
=
pSMB
;
if
(
wct
==
14
)
iov
[
0
].
iov_len
=
smb_hdr_len
+
4
;
iov
[
0
].
iov_len
=
smb_hdr_len
+
4
;
else
/* wct == 12 pad bigger by four bytes */
iov
[
0
].
iov_len
=
smb_hdr_len
+
8
;
rc
=
SendReceive2
(
xid
,
tcon
->
ses
,
iov
,
n_vec
+
1
,
&
bytes_returned
,
rc
=
SendReceive2
(
xid
,
tcon
->
ses
,
iov
,
n_vec
+
1
,
&
resp_buf_type
,
long_op
);
long_op
);
cifs_stats_inc
(
&
tcon
->
num_writes
);
cifs_stats_inc
(
&
tcon
->
num_writes
);
if
(
rc
)
{
if
(
rc
)
{
cFYI
(
1
,
(
"Send error Write2 = %d"
,
rc
));
cFYI
(
1
,
(
"Send error Write2 = %d"
,
rc
));
*
nbytes
=
0
;
*
nbytes
=
0
;
}
else
if
(
resp_buf_type
==
0
)
{
/* presumably this can not happen, but best to be safe */
rc
=
-
EIO
;
*
nbytes
=
0
;
}
else
{
}
else
{
WRITE_RSP
*
pSMBr
=
(
WRITE_RSP
*
)
pSMB
;
WRITE_RSP
*
pSMBr
=
(
WRITE_RSP
*
)
iov
[
0
].
iov_base
;
*
nbytes
=
le16_to_cpu
(
pSMBr
->
CountHigh
);
*
nbytes
=
le16_to_cpu
(
pSMBr
->
CountHigh
);
*
nbytes
=
(
*
nbytes
)
<<
16
;
*
nbytes
=
(
*
nbytes
)
<<
16
;
*
nbytes
+=
le16_to_cpu
(
pSMBr
->
Count
);
*
nbytes
+=
le16_to_cpu
(
pSMBr
->
Count
);
}
}
cifs_small_buf_release
(
pSMB
);
cifs_small_buf_release
(
pSMB
);
if
(
resp_buf_type
==
CIFS_SMALL_BUFFER
)
cifs_small_buf_release
(
iov
[
0
].
iov_base
);
else
if
(
resp_buf_type
==
CIFS_LARGE_BUFFER
)
cifs_buf_release
(
iov
[
0
].
iov_base
);
/* Note: On -EAGAIN error only caller can retry on handle based calls
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
since file handle passed in no longer valid */
...
...
fs/cifs/connect.c
浏览文件 @
ec637e3f
...
@@ -514,7 +514,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
...
@@ -514,7 +514,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
/* else length ok */
/* else length ok */
reconnect
=
0
;
reconnect
=
0
;
if
(
pdu_length
>
MAX_CIFS_
HD
R_SIZE
-
4
)
{
if
(
pdu_length
>
MAX_CIFS_
SMALL_BUFFE
R_SIZE
-
4
)
{
isLargeBuf
=
TRUE
;
isLargeBuf
=
TRUE
;
memcpy
(
bigbuf
,
smallbuf
,
4
);
memcpy
(
bigbuf
,
smallbuf
,
4
);
smb_buffer
=
bigbuf
;
smb_buffer
=
bigbuf
;
...
...
fs/cifs/file.c
浏览文件 @
ec637e3f
...
@@ -555,13 +555,13 @@ int cifs_closedir(struct inode *inode, struct file *file)
...
@@ -555,13 +555,13 @@ int cifs_closedir(struct inode *inode, struct file *file)
}
}
ptmp
=
pCFileStruct
->
srch_inf
.
ntwrk_buf_start
;
ptmp
=
pCFileStruct
->
srch_inf
.
ntwrk_buf_start
;
if
(
ptmp
)
{
if
(
ptmp
)
{
/* BB removeme BB */
cFYI
(
1
,
(
"freeing smb buf in srch struct in closedir
"
));
cFYI
(
1
,
(
"closedir free smb buf in srch struct
"
));
pCFileStruct
->
srch_inf
.
ntwrk_buf_start
=
NULL
;
pCFileStruct
->
srch_inf
.
ntwrk_buf_start
=
NULL
;
cifs_buf_release
(
ptmp
);
cifs_buf_release
(
ptmp
);
}
}
ptmp
=
pCFileStruct
->
search_resume_name
;
ptmp
=
pCFileStruct
->
search_resume_name
;
if
(
ptmp
)
{
if
(
ptmp
)
{
/* BB removeme BB */
cFYI
(
1
,
(
"freeing resume name in closedir
"
));
cFYI
(
1
,
(
"closedir free resume name
"
));
pCFileStruct
->
search_resume_name
=
NULL
;
pCFileStruct
->
search_resume_name
=
NULL
;
kfree
(
ptmp
);
kfree
(
ptmp
);
}
}
...
@@ -871,8 +871,8 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
...
@@ -871,8 +871,8 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
break
;
break
;
}
}
/* BB FIXME We can not sign across two buffers yet */
/* BB FIXME We can not sign across two buffers yet */
if
((
experimEnabled
)
&&
((
pTcon
->
ses
->
server
->
secMode
&
if
((
pTcon
->
ses
->
server
->
secMode
&
(
SECMODE_SIGN_REQUIRED
|
SECMODE_SIGN_ENABLED
))
==
0
)
)
{
(
SECMODE_SIGN_REQUIRED
|
SECMODE_SIGN_ENABLED
))
==
0
)
{
struct
kvec
iov
[
2
];
struct
kvec
iov
[
2
];
unsigned
int
len
;
unsigned
int
len
;
...
@@ -1424,6 +1424,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
...
@@ -1424,6 +1424,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
rc
=
-
EAGAIN
;
rc
=
-
EAGAIN
;
smb_read_data
=
NULL
;
smb_read_data
=
NULL
;
while
(
rc
==
-
EAGAIN
)
{
while
(
rc
==
-
EAGAIN
)
{
int
buf_type
=
CIFS_NO_BUFFER
;
if
((
open_file
->
invalidHandle
)
&&
if
((
open_file
->
invalidHandle
)
&&
(
!
open_file
->
closePend
))
{
(
!
open_file
->
closePend
))
{
rc
=
cifs_reopen_file
(
file
->
f_dentry
->
d_inode
,
rc
=
cifs_reopen_file
(
file
->
f_dentry
->
d_inode
,
...
@@ -1434,17 +1435,19 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
...
@@ -1434,17 +1435,19 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
open_file
->
netfid
,
open_file
->
netfid
,
current_read_size
,
*
poffset
,
current_read_size
,
*
poffset
,
&
bytes_read
,
&
smb_read_data
);
&
bytes_read
,
&
smb_read_data
,
&
buf_type
);
pSMBr
=
(
struct
smb_com_read_rsp
*
)
smb_read_data
;
pSMBr
=
(
struct
smb_com_read_rsp
*
)
smb_read_data
;
if
(
copy_to_user
(
current_offset
,
if
(
copy_to_user
(
current_offset
,
smb_read_data
+
4
/* RFC1001 hdr */
smb_read_data
+
4
/* RFC1001 hdr */
+
le16_to_cpu
(
pSMBr
->
DataOffset
),
+
le16_to_cpu
(
pSMBr
->
DataOffset
),
bytes_read
))
{
bytes_read
))
{
rc
=
-
EFAULT
;
rc
=
-
EFAULT
;
FreeXid
(
xid
);
return
rc
;
}
}
if
(
smb_read_data
)
{
if
(
smb_read_data
)
{
if
(
buf_type
==
CIFS_SMALL_BUFFER
)
cifs_small_buf_release
(
smb_read_data
);
else
if
(
buf_type
==
CIFS_LARGE_BUFFER
)
cifs_buf_release
(
smb_read_data
);
cifs_buf_release
(
smb_read_data
);
smb_read_data
=
NULL
;
smb_read_data
=
NULL
;
}
}
...
@@ -1478,6 +1481,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
...
@@ -1478,6 +1481,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
int
xid
;
int
xid
;
char
*
current_offset
;
char
*
current_offset
;
struct
cifsFileInfo
*
open_file
;
struct
cifsFileInfo
*
open_file
;
int
buf_type
=
CIFS_NO_BUFFER
;
xid
=
GetXid
();
xid
=
GetXid
();
cifs_sb
=
CIFS_SB
(
file
->
f_dentry
->
d_sb
);
cifs_sb
=
CIFS_SB
(
file
->
f_dentry
->
d_sb
);
...
@@ -1516,7 +1520,8 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
...
@@ -1516,7 +1520,8 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
open_file
->
netfid
,
open_file
->
netfid
,
current_read_size
,
*
poffset
,
current_read_size
,
*
poffset
,
&
bytes_read
,
&
current_offset
);
&
bytes_read
,
&
current_offset
,
&
buf_type
);
}
}
if
(
rc
||
(
bytes_read
==
0
))
{
if
(
rc
||
(
bytes_read
==
0
))
{
if
(
total_read
)
{
if
(
total_read
)
{
...
@@ -1614,6 +1619,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
...
@@ -1614,6 +1619,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
struct
smb_com_read_rsp
*
pSMBr
;
struct
smb_com_read_rsp
*
pSMBr
;
struct
pagevec
lru_pvec
;
struct
pagevec
lru_pvec
;
struct
cifsFileInfo
*
open_file
;
struct
cifsFileInfo
*
open_file
;
int
buf_type
=
CIFS_NO_BUFFER
;
xid
=
GetXid
();
xid
=
GetXid
();
if
(
file
->
private_data
==
NULL
)
{
if
(
file
->
private_data
==
NULL
)
{
...
@@ -1672,11 +1678,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
...
@@ -1672,11 +1678,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
open_file
->
netfid
,
open_file
->
netfid
,
read_size
,
offset
,
read_size
,
offset
,
&
bytes_read
,
&
smb_read_data
);
&
bytes_read
,
&
smb_read_data
,
&
buf_type
);
/* BB more RC checks ? */
/* BB more RC checks ? */
if
(
rc
==
-
EAGAIN
)
{
if
(
rc
==
-
EAGAIN
)
{
if
(
smb_read_data
)
{
if
(
smb_read_data
)
{
if
(
buf_type
==
CIFS_SMALL_BUFFER
)
cifs_small_buf_release
(
smb_read_data
);
else
if
(
buf_type
==
CIFS_LARGE_BUFFER
)
cifs_buf_release
(
smb_read_data
);
cifs_buf_release
(
smb_read_data
);
smb_read_data
=
NULL
;
smb_read_data
=
NULL
;
}
}
...
@@ -1734,6 +1743,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
...
@@ -1734,6 +1743,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
break
;
break
;
}
}
if
(
smb_read_data
)
{
if
(
smb_read_data
)
{
if
(
buf_type
==
CIFS_SMALL_BUFFER
)
cifs_small_buf_release
(
smb_read_data
);
else
if
(
buf_type
==
CIFS_LARGE_BUFFER
)
cifs_buf_release
(
smb_read_data
);
cifs_buf_release
(
smb_read_data
);
smb_read_data
=
NULL
;
smb_read_data
=
NULL
;
}
}
...
...
fs/cifs/inode.c
浏览文件 @
ec637e3f
...
@@ -229,11 +229,12 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
...
@@ -229,11 +229,12 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
cifs_sb
->
mnt_cifs_flags
&
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_MAP_SPECIAL_CHR
);
CIFS_MOUNT_MAP_SPECIAL_CHR
);
if
(
rc
==
0
)
{
if
(
rc
==
0
)
{
int
buf_type
=
CIFS_NO_BUFFER
;
/* Read header */
/* Read header */
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
netfid
,
netfid
,
24
/* length */
,
0
/* offset */
,
24
/* length */
,
0
/* offset */
,
&
bytes_read
,
&
pbuf
);
&
bytes_read
,
&
pbuf
,
&
buf_type
);
if
((
rc
==
0
)
&&
(
bytes_read
>=
8
))
{
if
((
rc
==
0
)
&&
(
bytes_read
>=
8
))
{
if
(
memcmp
(
"IntxBLK"
,
pbuf
,
8
)
==
0
)
{
if
(
memcmp
(
"IntxBLK"
,
pbuf
,
8
)
==
0
)
{
cFYI
(
1
,(
"Block device"
));
cFYI
(
1
,(
"Block device"
));
...
...
fs/cifs/misc.c
浏览文件 @
ec637e3f
...
@@ -299,7 +299,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
...
@@ -299,7 +299,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
struct
cifsSesInfo
*
ses
;
struct
cifsSesInfo
*
ses
;
char
*
temp
=
(
char
*
)
buffer
;
char
*
temp
=
(
char
*
)
buffer
;
memset
(
temp
,
0
,
MAX_CIFS_HDR_SIZE
);
memset
(
temp
,
0
,
256
);
/* bigger than MAX_CIFS_HDR_SIZE */
buffer
->
smb_buf_length
=
buffer
->
smb_buf_length
=
(
2
*
word_count
)
+
sizeof
(
struct
smb_hdr
)
-
(
2
*
word_count
)
+
sizeof
(
struct
smb_hdr
)
-
...
...
fs/cifs/transport.c
浏览文件 @
ec637e3f
...
@@ -298,7 +298,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
...
@@ -298,7 +298,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
int
int
SendReceive2
(
const
unsigned
int
xid
,
struct
cifsSesInfo
*
ses
,
SendReceive2
(
const
unsigned
int
xid
,
struct
cifsSesInfo
*
ses
,
struct
kvec
*
iov
,
int
n_vec
,
int
*
pbytes_returned
,
struct
kvec
*
iov
,
int
n_vec
,
int
*
pRespBufType
/* ret */
,
const
int
long_op
)
const
int
long_op
)
{
{
int
rc
=
0
;
int
rc
=
0
;
...
@@ -307,6 +307,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
...
@@ -307,6 +307,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
struct
mid_q_entry
*
midQ
;
struct
mid_q_entry
*
midQ
;
struct
smb_hdr
*
in_buf
=
iov
[
0
].
iov_base
;
struct
smb_hdr
*
in_buf
=
iov
[
0
].
iov_base
;
*
pRespBufType
=
CIFS_NO_BUFFER
;
/* no response buf yet */
if
(
ses
==
NULL
)
{
if
(
ses
==
NULL
)
{
cERROR
(
1
,(
"Null smb session"
));
cERROR
(
1
,(
"Null smb session"
));
return
-
EIO
;
return
-
EIO
;
...
@@ -491,23 +493,20 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
...
@@ -491,23 +493,20 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
if
(
midQ
->
resp_buf
&&
if
(
midQ
->
resp_buf
&&
(
midQ
->
midState
==
MID_RESPONSE_RECEIVED
))
{
(
midQ
->
midState
==
MID_RESPONSE_RECEIVED
))
{
in_buf
->
smb_buf_length
=
receive_len
;
iov
[
0
].
iov_base
=
(
char
*
)
midQ
->
resp_buf
;
if
(
receive_len
>
500
)
{
if
(
midQ
->
largeBuf
)
/* use multiple buffers on way out */
*
pRespBufType
=
CIFS_LARGE_BUFFER
;
}
else
{
else
memcpy
((
char
*
)
in_buf
+
4
,
*
pRespBufType
=
CIFS_SMALL_BUFFER
;
(
char
*
)
midQ
->
resp_buf
+
4
,
receive_len
);
iov
[
0
].
iov_len
=
receive_len
+
4
;
iov
[
0
].
iov_len
=
receive_len
+
4
;
iov
[
1
].
iov_len
=
0
;
iov
[
1
].
iov_len
=
0
;
}
dump_smb
(
in
_buf
,
80
);
dump_smb
(
midQ
->
resp
_buf
,
80
);
/* convert the length into a more usable form */
/* convert the length into a more usable form */
if
((
receive_len
>
24
)
&&
if
((
receive_len
>
24
)
&&
(
ses
->
server
->
secMode
&
(
SECMODE_SIGN_REQUIRED
|
(
ses
->
server
->
secMode
&
(
SECMODE_SIGN_REQUIRED
|
SECMODE_SIGN_ENABLED
)))
{
SECMODE_SIGN_ENABLED
)))
{
rc
=
cifs_verify_signature
(
in
_buf
,
rc
=
cifs_verify_signature
(
midQ
->
resp
_buf
,
ses
->
server
->
mac_signing_key
,
ses
->
server
->
mac_signing_key
,
midQ
->
sequence_number
+
1
);
midQ
->
sequence_number
+
1
);
if
(
rc
)
{
if
(
rc
)
{
...
@@ -516,18 +515,19 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
...
@@ -516,18 +515,19 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
}
}
}
}
*
pbytes_returned
=
in_buf
->
smb_buf_length
;
/* BB special case reconnect tid and uid here? */
/* BB special case reconnect tid and uid here? */
/* BB special case Errbadpassword and pwdexpired here */
/* BB special case Errbadpassword and pwdexpired here */
rc
=
map_smb_to_linux_error
(
in
_buf
);
rc
=
map_smb_to_linux_error
(
midQ
->
resp
_buf
);
/* convert ByteCount if necessary */
/* convert ByteCount if necessary */
if
(
receive_len
>=
if
(
receive_len
>=
sizeof
(
struct
smb_hdr
)
-
sizeof
(
struct
smb_hdr
)
-
4
/* do not count RFC1001 header */
+
4
/* do not count RFC1001 header */
+
(
2
*
in_buf
->
WordCount
)
+
2
/* bcc */
)
(
2
*
midQ
->
resp_buf
->
WordCount
)
+
2
/* bcc */
)
BCC
(
in_buf
)
=
le16_to_cpu
(
BCC_LE
(
in_buf
));
BCC
(
midQ
->
resp_buf
)
=
le16_to_cpu
(
BCC_LE
(
midQ
->
resp_buf
));
midQ
->
resp_buf
=
NULL
;
/* mark it so will not be freed
by DeleteMidQEntry */
}
else
{
}
else
{
rc
=
-
EIO
;
rc
=
-
EIO
;
cFYI
(
1
,(
"Bad MID state?"
));
cFYI
(
1
,(
"Bad MID state?"
));
...
@@ -793,7 +793,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
...
@@ -793,7 +793,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
BCC
(
out_buf
)
=
le16_to_cpu
(
BCC_LE
(
out_buf
));
BCC
(
out_buf
)
=
le16_to_cpu
(
BCC_LE
(
out_buf
));
}
else
{
}
else
{
rc
=
-
EIO
;
rc
=
-
EIO
;
cERROR
(
1
,(
"Bad MID state?
"
));
cERROR
(
1
,(
"Bad MID state?"
));
}
}
}
}
cifs_no_response_exit:
cifs_no_response_exit:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录