Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiphi1978
linux
提交
f7ba7fe6
L
linux
项目概览
xiphi1978
/
linux
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
f7ba7fe6
编写于
9月 19, 2012
作者:
P
Pavel Shilovsky
提交者:
Steve French
9月 24, 2012
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
CIFS: Add brlock support for SMB2
Signed-off-by:
N
Pavel Shilovsky
<
pshilovsky@etersoft.ru
>
上级
027e8eec
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
210 addition
and
5 deletion
+210
-5
fs/cifs/cifsproto.h
fs/cifs/cifsproto.h
+4
-0
fs/cifs/file.c
fs/cifs/file.c
+3
-5
fs/cifs/smb2file.c
fs/cifs/smb2file.c
+97
-0
fs/cifs/smb2ops.c
fs/cifs/smb2ops.c
+13
-0
fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.c
+59
-0
fs/cifs/smb2pdu.h
fs/cifs/smb2pdu.h
+24
-0
fs/cifs/smb2proto.h
fs/cifs/smb2proto.h
+10
-0
未找到文件。
fs/cifs/cifsproto.h
浏览文件 @
f7ba7fe6
...
@@ -190,6 +190,10 @@ extern void cifs_dfs_release_automount_timer(void);
...
@@ -190,6 +190,10 @@ extern void cifs_dfs_release_automount_timer(void);
void
cifs_proc_init
(
void
);
void
cifs_proc_init
(
void
);
void
cifs_proc_clean
(
void
);
void
cifs_proc_clean
(
void
);
extern
void
cifs_move_llist
(
struct
list_head
*
source
,
struct
list_head
*
dest
);
extern
void
cifs_free_llist
(
struct
list_head
*
llist
);
extern
void
cifs_del_lock_waiters
(
struct
cifsLockInfo
*
lock
);
extern
int
cifs_negotiate_protocol
(
const
unsigned
int
xid
,
extern
int
cifs_negotiate_protocol
(
const
unsigned
int
xid
,
struct
cifs_ses
*
ses
);
struct
cifs_ses
*
ses
);
extern
int
cifs_setup_session
(
const
unsigned
int
xid
,
struct
cifs_ses
*
ses
,
extern
int
cifs_setup_session
(
const
unsigned
int
xid
,
struct
cifs_ses
*
ses
,
...
...
fs/cifs/file.c
浏览文件 @
f7ba7fe6
...
@@ -288,8 +288,6 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
...
@@ -288,8 +288,6 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
return
cfile
;
return
cfile
;
}
}
static
void
cifs_del_lock_waiters
(
struct
cifsLockInfo
*
lock
);
struct
cifsFileInfo
*
struct
cifsFileInfo
*
cifsFileInfo_get
(
struct
cifsFileInfo
*
cifs_file
)
cifsFileInfo_get
(
struct
cifsFileInfo
*
cifs_file
)
{
{
...
@@ -696,7 +694,7 @@ cifs_lock_init(__u64 offset, __u64 length, __u8 type)
...
@@ -696,7 +694,7 @@ cifs_lock_init(__u64 offset, __u64 length, __u8 type)
return
lock
;
return
lock
;
}
}
static
void
void
cifs_del_lock_waiters
(
struct
cifsLockInfo
*
lock
)
cifs_del_lock_waiters
(
struct
cifsLockInfo
*
lock
)
{
{
struct
cifsLockInfo
*
li
,
*
tmp
;
struct
cifsLockInfo
*
li
,
*
tmp
;
...
@@ -1229,7 +1227,7 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u32 type,
...
@@ -1229,7 +1227,7 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u32 type,
return
0
;
return
0
;
}
}
static
void
void
cifs_move_llist
(
struct
list_head
*
source
,
struct
list_head
*
dest
)
cifs_move_llist
(
struct
list_head
*
source
,
struct
list_head
*
dest
)
{
{
struct
list_head
*
li
,
*
tmp
;
struct
list_head
*
li
,
*
tmp
;
...
@@ -1237,7 +1235,7 @@ cifs_move_llist(struct list_head *source, struct list_head *dest)
...
@@ -1237,7 +1235,7 @@ cifs_move_llist(struct list_head *source, struct list_head *dest)
list_move
(
li
,
dest
);
list_move
(
li
,
dest
);
}
}
static
void
void
cifs_free_llist
(
struct
list_head
*
llist
)
cifs_free_llist
(
struct
list_head
*
llist
)
{
{
struct
cifsLockInfo
*
li
,
*
tmp
;
struct
cifsLockInfo
*
li
,
*
tmp
;
...
...
fs/cifs/smb2file.c
浏览文件 @
f7ba7fe6
...
@@ -104,3 +104,100 @@ smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path,
...
@@ -104,3 +104,100 @@ smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path,
kfree
(
smb2_path
);
kfree
(
smb2_path
);
return
rc
;
return
rc
;
}
}
int
smb2_unlock_range
(
struct
cifsFileInfo
*
cfile
,
struct
file_lock
*
flock
,
const
unsigned
int
xid
)
{
int
rc
=
0
,
stored_rc
;
unsigned
int
max_num
,
num
=
0
,
max_buf
;
struct
smb2_lock_element
*
buf
,
*
cur
;
struct
cifs_tcon
*
tcon
=
tlink_tcon
(
cfile
->
tlink
);
struct
cifsInodeInfo
*
cinode
=
CIFS_I
(
cfile
->
dentry
->
d_inode
);
struct
cifsLockInfo
*
li
,
*
tmp
;
__u64
length
=
1
+
flock
->
fl_end
-
flock
->
fl_start
;
struct
list_head
tmp_llist
;
INIT_LIST_HEAD
(
&
tmp_llist
);
/*
* Accessing maxBuf is racy with cifs_reconnect - need to store value
* and check it for zero before using.
*/
max_buf
=
tcon
->
ses
->
server
->
maxBuf
;
if
(
!
max_buf
)
return
-
EINVAL
;
max_num
=
max_buf
/
sizeof
(
struct
smb2_lock_element
);
buf
=
kzalloc
(
max_num
*
sizeof
(
struct
smb2_lock_element
),
GFP_KERNEL
);
if
(
!
buf
)
return
-
ENOMEM
;
cur
=
buf
;
mutex_lock
(
&
cinode
->
lock_mutex
);
list_for_each_entry_safe
(
li
,
tmp
,
&
cfile
->
llist
->
locks
,
llist
)
{
if
(
flock
->
fl_start
>
li
->
offset
||
(
flock
->
fl_start
+
length
)
<
(
li
->
offset
+
li
->
length
))
continue
;
if
(
current
->
tgid
!=
li
->
pid
)
continue
;
if
(
cinode
->
can_cache_brlcks
)
{
/*
* We can cache brlock requests - simply remove a lock
* from the file's list.
*/
list_del
(
&
li
->
llist
);
cifs_del_lock_waiters
(
li
);
kfree
(
li
);
continue
;
}
cur
->
Length
=
cpu_to_le64
(
li
->
length
);
cur
->
Offset
=
cpu_to_le64
(
li
->
offset
);
cur
->
Flags
=
cpu_to_le32
(
SMB2_LOCKFLAG_UNLOCK
);
/*
* We need to save a lock here to let us add it again to the
* file's list if the unlock range request fails on the server.
*/
list_move
(
&
li
->
llist
,
&
tmp_llist
);
if
(
++
num
==
max_num
)
{
stored_rc
=
smb2_lockv
(
xid
,
tcon
,
cfile
->
fid
.
persistent_fid
,
cfile
->
fid
.
volatile_fid
,
current
->
tgid
,
num
,
buf
);
if
(
stored_rc
)
{
/*
* We failed on the unlock range request - add
* all locks from the tmp list to the head of
* the file's list.
*/
cifs_move_llist
(
&
tmp_llist
,
&
cfile
->
llist
->
locks
);
rc
=
stored_rc
;
}
else
/*
* The unlock range request succeed - free the
* tmp list.
*/
cifs_free_llist
(
&
tmp_llist
);
cur
=
buf
;
num
=
0
;
}
else
cur
++
;
}
if
(
num
)
{
stored_rc
=
smb2_lockv
(
xid
,
tcon
,
cfile
->
fid
.
persistent_fid
,
cfile
->
fid
.
volatile_fid
,
current
->
tgid
,
num
,
buf
);
if
(
stored_rc
)
{
cifs_move_llist
(
&
tmp_llist
,
&
cfile
->
llist
->
locks
);
rc
=
stored_rc
;
}
else
cifs_free_llist
(
&
tmp_llist
);
}
mutex_unlock
(
&
cinode
->
lock_mutex
);
kfree
(
buf
);
return
rc
;
}
fs/cifs/smb2ops.c
浏览文件 @
f7ba7fe6
...
@@ -544,6 +544,17 @@ smb2_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2)
...
@@ -544,6 +544,17 @@ smb2_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2)
ob1
->
fid
.
volatile_fid
==
ob2
->
fid
.
volatile_fid
;
ob1
->
fid
.
volatile_fid
==
ob2
->
fid
.
volatile_fid
;
}
}
static
int
smb2_mand_lock
(
const
unsigned
int
xid
,
struct
cifsFileInfo
*
cfile
,
__u64
offset
,
__u64
length
,
__u32
type
,
int
lock
,
int
unlock
,
bool
wait
)
{
if
(
unlock
&&
!
lock
)
type
=
SMB2_LOCKFLAG_UNLOCK
;
return
SMB2_lock
(
xid
,
tlink_tcon
(
cfile
->
tlink
),
cfile
->
fid
.
persistent_fid
,
cfile
->
fid
.
volatile_fid
,
current
->
tgid
,
length
,
offset
,
type
,
wait
);
}
struct
smb_version_operations
smb21_operations
=
{
struct
smb_version_operations
smb21_operations
=
{
.
compare_fids
=
smb2_compare_fids
,
.
compare_fids
=
smb2_compare_fids
,
.
setup_request
=
smb2_setup_request
,
.
setup_request
=
smb2_setup_request
,
...
@@ -602,6 +613,8 @@ struct smb_version_operations smb21_operations = {
...
@@ -602,6 +613,8 @@ struct smb_version_operations smb21_operations = {
.
is_status_pending
=
smb2_is_status_pending
,
.
is_status_pending
=
smb2_is_status_pending
,
.
oplock_response
=
smb2_oplock_response
,
.
oplock_response
=
smb2_oplock_response
,
.
queryfs
=
smb2_queryfs
,
.
queryfs
=
smb2_queryfs
,
.
mand_lock
=
smb2_mand_lock
,
.
mand_unlock_range
=
smb2_unlock_range
,
};
};
struct
smb_version_values
smb21_values
=
{
struct
smb_version_values
smb21_values
=
{
...
...
fs/cifs/smb2pdu.c
浏览文件 @
f7ba7fe6
...
@@ -2047,3 +2047,62 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
...
@@ -2047,3 +2047,62 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
free_rsp_buf
(
resp_buftype
,
iov
.
iov_base
);
free_rsp_buf
(
resp_buftype
,
iov
.
iov_base
);
return
rc
;
return
rc
;
}
}
int
smb2_lockv
(
const
unsigned
int
xid
,
struct
cifs_tcon
*
tcon
,
const
__u64
persist_fid
,
const
__u64
volatile_fid
,
const
__u32
pid
,
const
__u32
num_lock
,
struct
smb2_lock_element
*
buf
)
{
int
rc
=
0
;
struct
smb2_lock_req
*
req
=
NULL
;
struct
kvec
iov
[
2
];
int
resp_buf_type
;
unsigned
int
count
;
cFYI
(
1
,
"smb2_lockv num lock %d"
,
num_lock
);
rc
=
small_smb2_init
(
SMB2_LOCK
,
tcon
,
(
void
**
)
&
req
);
if
(
rc
)
return
rc
;
req
->
hdr
.
ProcessId
=
cpu_to_le32
(
pid
);
req
->
LockCount
=
cpu_to_le16
(
num_lock
);
req
->
PersistentFileId
=
persist_fid
;
req
->
VolatileFileId
=
volatile_fid
;
count
=
num_lock
*
sizeof
(
struct
smb2_lock_element
);
inc_rfc1001_len
(
req
,
count
-
sizeof
(
struct
smb2_lock_element
));
iov
[
0
].
iov_base
=
(
char
*
)
req
;
/* 4 for rfc1002 length field and count for all locks */
iov
[
0
].
iov_len
=
get_rfc1002_length
(
req
)
+
4
-
count
;
iov
[
1
].
iov_base
=
(
char
*
)
buf
;
iov
[
1
].
iov_len
=
count
;
cifs_stats_inc
(
&
tcon
->
stats
.
cifs_stats
.
num_locks
);
rc
=
SendReceive2
(
xid
,
tcon
->
ses
,
iov
,
2
,
&
resp_buf_type
,
CIFS_NO_RESP
);
if
(
rc
)
{
cFYI
(
1
,
"Send error in smb2_lockv = %d"
,
rc
);
cifs_stats_fail_inc
(
tcon
,
SMB2_LOCK_HE
);
}
return
rc
;
}
int
SMB2_lock
(
const
unsigned
int
xid
,
struct
cifs_tcon
*
tcon
,
const
__u64
persist_fid
,
const
__u64
volatile_fid
,
const
__u32
pid
,
const
__u64
length
,
const
__u64
offset
,
const
__u32
lock_flags
,
const
bool
wait
)
{
struct
smb2_lock_element
lock
;
lock
.
Offset
=
cpu_to_le64
(
offset
);
lock
.
Length
=
cpu_to_le64
(
length
);
lock
.
Flags
=
cpu_to_le32
(
lock_flags
);
if
(
!
wait
&&
lock_flags
!=
SMB2_LOCKFLAG_UNLOCK
)
lock
.
Flags
|=
cpu_to_le32
(
SMB2_LOCKFLAG_FAIL_IMMEDIATELY
);
return
smb2_lockv
(
xid
,
tcon
,
persist_fid
,
volatile_fid
,
pid
,
1
,
&
lock
);
}
fs/cifs/smb2pdu.h
浏览文件 @
f7ba7fe6
...
@@ -531,6 +531,30 @@ struct smb2_write_rsp {
...
@@ -531,6 +531,30 @@ struct smb2_write_rsp {
#define SMB2_LOCKFLAG_UNLOCK 0x0004
#define SMB2_LOCKFLAG_UNLOCK 0x0004
#define SMB2_LOCKFLAG_FAIL_IMMEDIATELY 0x0010
#define SMB2_LOCKFLAG_FAIL_IMMEDIATELY 0x0010
struct
smb2_lock_element
{
__le64
Offset
;
__le64
Length
;
__le32
Flags
;
__le32
Reserved
;
}
__packed
;
struct
smb2_lock_req
{
struct
smb2_hdr
hdr
;
__le16
StructureSize
;
/* Must be 48 */
__le16
LockCount
;
__le32
Reserved
;
__u64
PersistentFileId
;
/* opaque endianness */
__u64
VolatileFileId
;
/* opaque endianness */
/* Followed by at least one */
struct
smb2_lock_element
locks
[
1
];
}
__packed
;
struct
smb2_lock_rsp
{
struct
smb2_hdr
hdr
;
__le16
StructureSize
;
/* Must be 4 */
__le16
Reserved
;
}
__packed
;
struct
smb2_echo_req
{
struct
smb2_echo_req
{
struct
smb2_hdr
hdr
;
struct
smb2_hdr
hdr
;
__le16
StructureSize
;
/* Must be 4 */
__le16
StructureSize
;
/* Must be 4 */
...
...
fs/cifs/smb2proto.h
浏览文件 @
f7ba7fe6
...
@@ -84,6 +84,8 @@ extern int smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon,
...
@@ -84,6 +84,8 @@ extern int smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon,
struct
cifs_fid
*
fid
,
__u32
*
oplock
,
struct
cifs_fid
*
fid
,
__u32
*
oplock
,
FILE_ALL_INFO
*
buf
,
struct
cifs_sb_info
*
cifs_sb
);
FILE_ALL_INFO
*
buf
,
struct
cifs_sb_info
*
cifs_sb
);
extern
void
smb2_set_oplock_level
(
struct
cifsInodeInfo
*
cinode
,
__u32
oplock
);
extern
void
smb2_set_oplock_level
(
struct
cifsInodeInfo
*
cinode
,
__u32
oplock
);
extern
int
smb2_unlock_range
(
struct
cifsFileInfo
*
cfile
,
struct
file_lock
*
flock
,
const
unsigned
int
xid
);
/*
/*
* SMB2 Worker functions - most of protocol specific implementation details
* SMB2 Worker functions - most of protocol specific implementation details
...
@@ -140,5 +142,13 @@ extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
...
@@ -140,5 +142,13 @@ extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
extern
int
SMB2_QFS_info
(
const
unsigned
int
xid
,
struct
cifs_tcon
*
tcon
,
extern
int
SMB2_QFS_info
(
const
unsigned
int
xid
,
struct
cifs_tcon
*
tcon
,
u64
persistent_file_id
,
u64
volatile_file_id
,
u64
persistent_file_id
,
u64
volatile_file_id
,
struct
kstatfs
*
FSData
);
struct
kstatfs
*
FSData
);
extern
int
SMB2_lock
(
const
unsigned
int
xid
,
struct
cifs_tcon
*
tcon
,
const
__u64
persist_fid
,
const
__u64
volatile_fid
,
const
__u32
pid
,
const
__u64
length
,
const
__u64
offset
,
const
__u32
lockFlags
,
const
bool
wait
);
extern
int
smb2_lockv
(
const
unsigned
int
xid
,
struct
cifs_tcon
*
tcon
,
const
__u64
persist_fid
,
const
__u64
volatile_fid
,
const
__u32
pid
,
const
__u32
num_lock
,
struct
smb2_lock_element
*
buf
);
#endif
/* _SMB2PROTO_H */
#endif
/* _SMB2PROTO_H */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录