Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
8383e460
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 1 年 前同步成功
通知
158
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看板
体验新版 GitCode,发现更多精彩内容 >>
提交
8383e460
编写于
7月 06, 2007
作者:
T
Trond Myklebust
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
NFSv4: Use RCU to protect delegations
Signed-off-by:
N
Trond Myklebust
<
Trond.Myklebust@netapp.com
>
上级
13437e12
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
73 addition
and
55 deletion
+73
-55
fs/nfs/delegation.c
fs/nfs/delegation.c
+63
-51
fs/nfs/delegation.h
fs/nfs/delegation.h
+10
-4
未找到文件。
fs/nfs/delegation.c
浏览文件 @
8383e460
...
...
@@ -27,6 +27,13 @@ static void nfs_free_delegation(struct nfs_delegation *delegation)
kfree
(
delegation
);
}
static
void
nfs_free_delegation_callback
(
struct
rcu_head
*
head
)
{
struct
nfs_delegation
*
delegation
=
container_of
(
head
,
struct
nfs_delegation
,
rcu
);
nfs_free_delegation
(
delegation
);
}
static
int
nfs_delegation_claim_locks
(
struct
nfs_open_context
*
ctx
,
struct
nfs4_state
*
state
)
{
struct
inode
*
inode
=
state
->
inode
;
...
...
@@ -133,10 +140,10 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
delegation
->
inode
=
inode
;
spin_lock
(
&
clp
->
cl_lock
);
if
(
nfsi
->
delegation
==
NULL
)
{
list_add
(
&
delegation
->
super_list
,
&
clp
->
cl_delegations
);
nfsi
->
delegation
=
delegation
;
if
(
rcu_dereference
(
nfsi
->
delegation
)
==
NULL
)
{
list_add_rcu
(
&
delegation
->
super_list
,
&
clp
->
cl_delegations
);
nfsi
->
delegation_state
=
delegation
->
type
;
rcu_assign_pointer
(
nfsi
->
delegation
,
delegation
);
delegation
=
NULL
;
}
else
{
if
(
memcmp
(
&
delegation
->
stateid
,
&
nfsi
->
delegation
->
stateid
,
...
...
@@ -157,7 +164,7 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *
int
res
=
0
;
res
=
nfs4_proc_delegreturn
(
inode
,
delegation
->
cred
,
&
delegation
->
stateid
);
nfs_free_delegation
(
delegation
);
call_rcu
(
&
delegation
->
rcu
,
nfs_free_delegation_callback
);
return
res
;
}
...
...
@@ -191,16 +198,16 @@ static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegat
static
struct
nfs_delegation
*
nfs_detach_delegation_locked
(
struct
nfs_inode
*
nfsi
,
const
nfs4_stateid
*
stateid
)
{
struct
nfs_delegation
*
delegation
=
nfsi
->
delegation
;
struct
nfs_delegation
*
delegation
=
rcu_dereference
(
nfsi
->
delegation
)
;
if
(
delegation
==
NULL
)
goto
nomatch
;
if
(
stateid
!=
NULL
&&
memcmp
(
delegation
->
stateid
.
data
,
stateid
->
data
,
sizeof
(
delegation
->
stateid
.
data
))
!=
0
)
goto
nomatch
;
list_del_init
(
&
delegation
->
super_list
);
nfsi
->
delegation
=
NULL
;
list_del_rcu
(
&
delegation
->
super_list
);
nfsi
->
delegation_state
=
0
;
rcu_assign_pointer
(
nfsi
->
delegation
,
NULL
);
return
delegation
;
nomatch:
return
NULL
;
...
...
@@ -213,7 +220,7 @@ int nfs_inode_return_delegation(struct inode *inode)
struct
nfs_delegation
*
delegation
;
int
err
=
0
;
if
(
nfsi
->
delegation_state
!=
0
)
{
if
(
rcu_dereference
(
nfsi
->
delegation
)
!=
NULL
)
{
spin_lock
(
&
clp
->
cl_lock
);
delegation
=
nfs_detach_delegation_locked
(
nfsi
,
NULL
);
spin_unlock
(
&
clp
->
cl_lock
);
...
...
@@ -235,20 +242,23 @@ void nfs_return_all_delegations(struct super_block *sb)
if
(
clp
==
NULL
)
return
;
restart:
spin_lock
(
&
clp
->
cl_lock
);
list_for_each_entry
(
delegation
,
&
clp
->
cl_delegations
,
super_list
)
{
rcu_read_lock
(
);
list_for_each_entry
_rcu
(
delegation
,
&
clp
->
cl_delegations
,
super_list
)
{
if
(
delegation
->
inode
->
i_sb
!=
sb
)
continue
;
inode
=
igrab
(
delegation
->
inode
);
if
(
inode
==
NULL
)
continue
;
nfs_detach_delegation_locked
(
NFS_I
(
inode
),
NULL
);
spin_lock
(
&
clp
->
cl_lock
);
delegation
=
nfs_detach_delegation_locked
(
NFS_I
(
inode
),
NULL
);
spin_unlock
(
&
clp
->
cl_lock
);
__nfs_inode_return_delegation
(
inode
,
delegation
);
rcu_read_unlock
();
if
(
delegation
!=
NULL
)
__nfs_inode_return_delegation
(
inode
,
delegation
);
iput
(
inode
);
goto
restart
;
}
spin_unlock
(
&
clp
->
cl_lock
);
rcu_read_unlock
(
);
}
static
int
nfs_do_expire_all_delegations
(
void
*
ptr
)
...
...
@@ -259,23 +269,26 @@ static int nfs_do_expire_all_delegations(void *ptr)
allow_signal
(
SIGKILL
);
restart:
spin_lock
(
&
clp
->
cl_lock
);
if
(
test_bit
(
NFS4CLNT_STATE_RECOVER
,
&
clp
->
cl_state
)
!=
0
)
goto
out
;
if
(
test_bit
(
NFS4CLNT_LEASE_EXPIRED
,
&
clp
->
cl_state
)
==
0
)
goto
out
;
list_for_each_entry
(
delegation
,
&
clp
->
cl_delegations
,
super_list
)
{
rcu_read_lock
();
list_for_each_entry_rcu
(
delegation
,
&
clp
->
cl_delegations
,
super_list
)
{
inode
=
igrab
(
delegation
->
inode
);
if
(
inode
==
NULL
)
continue
;
nfs_detach_delegation_locked
(
NFS_I
(
inode
),
NULL
);
spin_lock
(
&
clp
->
cl_lock
);
delegation
=
nfs_detach_delegation_locked
(
NFS_I
(
inode
),
NULL
);
spin_unlock
(
&
clp
->
cl_lock
);
__nfs_inode_return_delegation
(
inode
,
delegation
);
rcu_read_unlock
();
if
(
delegation
)
__nfs_inode_return_delegation
(
inode
,
delegation
);
iput
(
inode
);
goto
restart
;
}
rcu_read_unlock
();
out:
spin_unlock
(
&
clp
->
cl_lock
);
nfs_put_client
(
clp
);
module_put_and_exit
(
0
);
}
...
...
@@ -306,18 +319,21 @@ void nfs_handle_cb_pathdown(struct nfs_client *clp)
if
(
clp
==
NULL
)
return
;
restart:
spin_lock
(
&
clp
->
cl_lock
);
list_for_each_entry
(
delegation
,
&
clp
->
cl_delegations
,
super_list
)
{
rcu_read_lock
(
);
list_for_each_entry
_rcu
(
delegation
,
&
clp
->
cl_delegations
,
super_list
)
{
inode
=
igrab
(
delegation
->
inode
);
if
(
inode
==
NULL
)
continue
;
nfs_detach_delegation_locked
(
NFS_I
(
inode
),
NULL
);
spin_lock
(
&
clp
->
cl_lock
);
delegation
=
nfs_detach_delegation_locked
(
NFS_I
(
inode
),
NULL
);
spin_unlock
(
&
clp
->
cl_lock
);
__nfs_inode_return_delegation
(
inode
,
delegation
);
rcu_read_unlock
();
if
(
delegation
!=
NULL
)
__nfs_inode_return_delegation
(
inode
,
delegation
);
iput
(
inode
);
goto
restart
;
}
spin_unlock
(
&
clp
->
cl_lock
);
rcu_read_unlock
(
);
}
struct
recall_threadargs
{
...
...
@@ -391,14 +407,14 @@ struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs
{
struct
nfs_delegation
*
delegation
;
struct
inode
*
res
=
NULL
;
spin_lock
(
&
clp
->
cl_lock
);
list_for_each_entry
(
delegation
,
&
clp
->
cl_delegations
,
super_list
)
{
rcu_read_lock
(
);
list_for_each_entry
_rcu
(
delegation
,
&
clp
->
cl_delegations
,
super_list
)
{
if
(
nfs_compare_fh
(
fhandle
,
&
NFS_I
(
delegation
->
inode
)
->
fh
)
==
0
)
{
res
=
igrab
(
delegation
->
inode
);
break
;
}
}
spin_unlock
(
&
clp
->
cl_lock
);
rcu_read_unlock
(
);
return
res
;
}
...
...
@@ -408,10 +424,10 @@ struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs
void
nfs_delegation_mark_reclaim
(
struct
nfs_client
*
clp
)
{
struct
nfs_delegation
*
delegation
;
spin_lock
(
&
clp
->
cl_lock
);
list_for_each_entry
(
delegation
,
&
clp
->
cl_delegations
,
super_list
)
rcu_read_lock
(
);
list_for_each_entry
_rcu
(
delegation
,
&
clp
->
cl_delegations
,
super_list
)
delegation
->
flags
|=
NFS_DELEGATION_NEED_RECLAIM
;
spin_unlock
(
&
clp
->
cl_lock
);
rcu_read_unlock
(
);
}
/*
...
...
@@ -419,39 +435,35 @@ void nfs_delegation_mark_reclaim(struct nfs_client *clp)
*/
void
nfs_delegation_reap_unclaimed
(
struct
nfs_client
*
clp
)
{
struct
nfs_delegation
*
delegation
,
*
n
;
LIST_HEAD
(
head
);
spin_lock
(
&
clp
->
cl_lock
);
list_for_each_entry_
safe
(
delegation
,
n
,
&
clp
->
cl_delegations
,
super_list
)
{
struct
nfs_delegation
*
delegation
;
restart:
rcu_read_lock
(
);
list_for_each_entry_
rcu
(
delegatio
n
,
&
clp
->
cl_delegations
,
super_list
)
{
if
((
delegation
->
flags
&
NFS_DELEGATION_NEED_RECLAIM
)
==
0
)
continue
;
list_move
(
&
delegation
->
super_list
,
&
head
);
NFS_I
(
delegation
->
inode
)
->
delegation
=
NULL
;
NFS_I
(
delegation
->
inode
)
->
delegation_state
=
0
;
}
spin_unlock
(
&
clp
->
cl_lock
);
while
(
!
list_empty
(
&
head
))
{
delegation
=
list_entry
(
head
.
next
,
struct
nfs_delegation
,
super_list
);
list_del
(
&
delegation
->
super_list
);
nfs_free_delegation
(
delegation
);
spin_lock
(
&
clp
->
cl_lock
);
delegation
=
nfs_detach_delegation_locked
(
NFS_I
(
delegation
->
inode
),
NULL
);
spin_unlock
(
&
clp
->
cl_lock
);
rcu_read_unlock
();
if
(
delegation
!=
NULL
)
call_rcu
(
&
delegation
->
rcu
,
nfs_free_delegation_callback
);
goto
restart
;
}
rcu_read_unlock
();
}
int
nfs4_copy_delegation_stateid
(
nfs4_stateid
*
dst
,
struct
inode
*
inode
)
{
struct
nfs_client
*
clp
=
NFS_SERVER
(
inode
)
->
nfs_client
;
struct
nfs_inode
*
nfsi
=
NFS_I
(
inode
);
struct
nfs_delegation
*
delegation
;
int
re
s
=
0
;
int
re
t
=
0
;
if
(
nfsi
->
delegation_state
==
0
)
return
0
;
spin_lock
(
&
clp
->
cl_lock
);
delegation
=
nfsi
->
delegation
;
rcu_read_lock
();
delegation
=
rcu_dereference
(
nfsi
->
delegation
);
if
(
delegation
!=
NULL
)
{
memcpy
(
dst
->
data
,
delegation
->
stateid
.
data
,
sizeof
(
dst
->
data
));
re
s
=
1
;
re
t
=
1
;
}
spin_unlock
(
&
clp
->
cl_lock
);
return
re
s
;
rcu_read_unlock
(
);
return
re
t
;
}
fs/nfs/delegation.h
浏览文件 @
8383e460
...
...
@@ -22,6 +22,7 @@ struct nfs_delegation {
long
flags
;
loff_t
maxsize
;
__u64
change_attr
;
struct
rcu_head
rcu
;
};
int
nfs_inode_set_delegation
(
struct
inode
*
inode
,
struct
rpc_cred
*
cred
,
struct
nfs_openres
*
res
);
...
...
@@ -45,11 +46,16 @@ int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode);
static
inline
int
nfs_have_delegation
(
struct
inode
*
inode
,
int
flags
)
{
struct
nfs_delegation
*
delegation
;
int
ret
=
0
;
flags
&=
FMODE_READ
|
FMODE_WRITE
;
smp_rmb
();
if
((
NFS_I
(
inode
)
->
delegation_state
&
flags
)
==
flags
)
return
1
;
return
0
;
rcu_read_lock
();
delegation
=
rcu_dereference
(
NFS_I
(
inode
)
->
delegation
);
if
(
delegation
!=
NULL
&&
(
delegation
->
type
&
flags
)
==
flags
)
ret
=
1
;
rcu_read_unlock
();
return
ret
;
}
#else
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录