Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiphi1978
linux
提交
2127d82a
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,发现更多精彩内容 >>
提交
2127d82a
编写于
8月 26, 2013
作者:
T
Trond Myklebust
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
NFSv4: Convert idmapper to use the new framework for pipefs dentries
Signed-off-by:
N
Trond Myklebust
<
Trond.Myklebust@netapp.com
>
上级
5f42b016
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
34 addition
and
150 deletion
+34
-150
fs/nfs/idmap.c
fs/nfs/idmap.c
+34
-150
未找到文件。
fs/nfs/idmap.c
浏览文件 @
2127d82a
...
...
@@ -64,6 +64,7 @@ struct idmap_legacy_upcalldata {
};
struct
idmap
{
struct
rpc_pipe_dir_object
idmap_pdo
;
struct
rpc_pipe
*
idmap_pipe
;
struct
idmap_legacy_upcalldata
*
idmap_upcall_data
;
struct
mutex
idmap_mutex
;
...
...
@@ -402,18 +403,23 @@ static struct key_type key_type_id_resolver_legacy = {
.
request_key
=
nfs_idmap_legacy_upcall
,
};
static
void
__nfs_idmap_unregister
(
struct
rpc_pipe
*
pipe
)
static
void
nfs_idmap_pipe_destroy
(
struct
dentry
*
dir
,
struct
rpc_pipe_dir_object
*
pdo
)
{
struct
idmap
*
idmap
=
pdo
->
pdo_data
;
struct
rpc_pipe
*
pipe
=
idmap
->
idmap_pipe
;
if
(
pipe
->
dentry
)
{
rpc_unlink
(
pipe
->
dentry
);
pipe
->
dentry
=
NULL
;
}
}
static
int
__nfs_idmap_register
(
struct
dentry
*
dir
,
struct
idmap
*
idmap
,
struct
rpc_pipe
*
pipe
)
static
int
nfs_idmap_pipe_create
(
struct
dentry
*
dir
,
struct
rpc_pipe_dir_object
*
pdo
)
{
struct
idmap
*
idmap
=
pdo
->
pdo_data
;
struct
rpc_pipe
*
pipe
=
idmap
->
idmap_pipe
;
struct
dentry
*
dentry
;
dentry
=
rpc_mkpipe_dentry
(
dir
,
"idmap"
,
idmap
,
pipe
);
...
...
@@ -423,36 +429,10 @@ static int __nfs_idmap_register(struct dentry *dir,
return
0
;
}
static
void
nfs_idmap_unregister
(
struct
nfs_client
*
clp
,
struct
rpc_pipe
*
pipe
)
{
struct
net
*
net
=
clp
->
cl_net
;
struct
super_block
*
pipefs_sb
;
pipefs_sb
=
rpc_get_sb_net
(
net
);
if
(
pipefs_sb
)
{
__nfs_idmap_unregister
(
pipe
);
rpc_put_sb_net
(
net
);
}
}
static
int
nfs_idmap_register
(
struct
nfs_client
*
clp
,
struct
idmap
*
idmap
,
struct
rpc_pipe
*
pipe
)
{
struct
net
*
net
=
clp
->
cl_net
;
struct
super_block
*
pipefs_sb
;
int
err
=
0
;
pipefs_sb
=
rpc_get_sb_net
(
net
);
if
(
pipefs_sb
)
{
if
(
clp
->
cl_rpcclient
->
cl_dentry
)
err
=
__nfs_idmap_register
(
clp
->
cl_rpcclient
->
cl_dentry
,
idmap
,
pipe
);
rpc_put_sb_net
(
net
);
}
return
err
;
}
static
const
struct
rpc_pipe_dir_object_ops
nfs_idmap_pipe_dir_object_ops
=
{
.
create
=
nfs_idmap_pipe_create
,
.
destroy
=
nfs_idmap_pipe_destroy
,
};
int
nfs_idmap_new
(
struct
nfs_client
*
clp
)
...
...
@@ -465,23 +445,31 @@ nfs_idmap_new(struct nfs_client *clp)
if
(
idmap
==
NULL
)
return
-
ENOMEM
;
rpc_init_pipe_dir_object
(
&
idmap
->
idmap_pdo
,
&
nfs_idmap_pipe_dir_object_ops
,
idmap
);
pipe
=
rpc_mkpipe_data
(
&
idmap_upcall_ops
,
0
);
if
(
IS_ERR
(
pipe
))
{
error
=
PTR_ERR
(
pipe
);
kfree
(
idmap
);
return
error
;
}
error
=
nfs_idmap_register
(
clp
,
idmap
,
pipe
);
if
(
error
)
{
rpc_destroy_pipe_data
(
pipe
);
kfree
(
idmap
);
return
error
;
goto
err
;
}
idmap
->
idmap_pipe
=
pipe
;
mutex_init
(
&
idmap
->
idmap_mutex
);
error
=
rpc_add_pipe_dir_object
(
clp
->
cl_net
,
&
clp
->
cl_rpcclient
->
cl_pipedir_objects
,
&
idmap
->
idmap_pdo
);
if
(
error
)
goto
err_destroy_pipe
;
clp
->
cl_idmap
=
idmap
;
return
0
;
err_destroy_pipe:
rpc_destroy_pipe_data
(
idmap
->
idmap_pipe
);
err:
kfree
(
idmap
);
return
error
;
}
void
...
...
@@ -491,130 +479,26 @@ nfs_idmap_delete(struct nfs_client *clp)
if
(
!
idmap
)
return
;
nfs_idmap_unregister
(
clp
,
idmap
->
idmap_pipe
);
rpc_destroy_pipe_data
(
idmap
->
idmap_pipe
);
clp
->
cl_idmap
=
NULL
;
rpc_remove_pipe_dir_object
(
clp
->
cl_net
,
&
clp
->
cl_rpcclient
->
cl_pipedir_objects
,
&
idmap
->
idmap_pdo
);
rpc_destroy_pipe_data
(
idmap
->
idmap_pipe
);
kfree
(
idmap
);
}
static
int
__rpc_pipefs_event
(
struct
nfs_client
*
clp
,
unsigned
long
event
,
struct
super_block
*
sb
)
{
int
err
=
0
;
switch
(
event
)
{
case
RPC_PIPEFS_MOUNT
:
err
=
__nfs_idmap_register
(
clp
->
cl_rpcclient
->
cl_dentry
,
clp
->
cl_idmap
,
clp
->
cl_idmap
->
idmap_pipe
);
break
;
case
RPC_PIPEFS_UMOUNT
:
if
(
clp
->
cl_idmap
->
idmap_pipe
)
{
struct
dentry
*
parent
;
parent
=
clp
->
cl_idmap
->
idmap_pipe
->
dentry
->
d_parent
;
__nfs_idmap_unregister
(
clp
->
cl_idmap
->
idmap_pipe
);
/*
* Note: This is a dirty hack. SUNRPC hook has been
* called already but simple_rmdir() call for the
* directory returned with error because of idmap pipe
* inside. Thus now we have to remove this directory
* here.
*/
if
(
rpc_rmdir
(
parent
))
printk
(
KERN_ERR
"NFS: %s: failed to remove "
"clnt dir!
\n
"
,
__func__
);
}
break
;
default:
printk
(
KERN_ERR
"NFS: %s: unknown event: %ld
\n
"
,
__func__
,
event
);
return
-
ENOTSUPP
;
}
return
err
;
}
static
struct
nfs_client
*
nfs_get_client_for_event
(
struct
net
*
net
,
int
event
)
{
struct
nfs_net
*
nn
=
net_generic
(
net
,
nfs_net_id
);
struct
dentry
*
cl_dentry
;
struct
nfs_client
*
clp
;
int
err
;
restart:
spin_lock
(
&
nn
->
nfs_client_lock
);
list_for_each_entry
(
clp
,
&
nn
->
nfs_client_list
,
cl_share_link
)
{
/* Wait for initialisation to finish */
if
(
clp
->
cl_cons_state
==
NFS_CS_INITING
)
{
atomic_inc
(
&
clp
->
cl_count
);
spin_unlock
(
&
nn
->
nfs_client_lock
);
err
=
nfs_wait_client_init_complete
(
clp
);
nfs_put_client
(
clp
);
if
(
err
)
return
NULL
;
goto
restart
;
}
/* Skip nfs_clients that failed to initialise */
if
(
clp
->
cl_cons_state
<
0
)
continue
;
smp_rmb
();
if
(
clp
->
rpc_ops
!=
&
nfs_v4_clientops
)
continue
;
cl_dentry
=
clp
->
cl_idmap
->
idmap_pipe
->
dentry
;
if
(((
event
==
RPC_PIPEFS_MOUNT
)
&&
cl_dentry
)
||
((
event
==
RPC_PIPEFS_UMOUNT
)
&&
!
cl_dentry
))
continue
;
atomic_inc
(
&
clp
->
cl_count
);
spin_unlock
(
&
nn
->
nfs_client_lock
);
return
clp
;
}
spin_unlock
(
&
nn
->
nfs_client_lock
);
return
NULL
;
}
static
int
rpc_pipefs_event
(
struct
notifier_block
*
nb
,
unsigned
long
event
,
void
*
ptr
)
{
struct
super_block
*
sb
=
ptr
;
struct
nfs_client
*
clp
;
int
error
=
0
;
if
(
!
try_module_get
(
THIS_MODULE
))
return
0
;
while
((
clp
=
nfs_get_client_for_event
(
sb
->
s_fs_info
,
event
)))
{
error
=
__rpc_pipefs_event
(
clp
,
event
,
sb
);
nfs_put_client
(
clp
);
if
(
error
)
break
;
}
module_put
(
THIS_MODULE
);
return
error
;
}
#define PIPEFS_NFS_PRIO 1
static
struct
notifier_block
nfs_idmap_block
=
{
.
notifier_call
=
rpc_pipefs_event
,
.
priority
=
SUNRPC_PIPEFS_NFS_PRIO
,
};
int
nfs_idmap_init
(
void
)
{
int
ret
;
ret
=
nfs_idmap_init_keyring
();
if
(
ret
!=
0
)
goto
out
;
ret
=
rpc_pipefs_notifier_register
(
&
nfs_idmap_block
);
if
(
ret
!=
0
)
nfs_idmap_quit_keyring
();
out:
return
ret
;
}
void
nfs_idmap_quit
(
void
)
{
rpc_pipefs_notifier_unregister
(
&
nfs_idmap_block
);
nfs_idmap_quit_keyring
();
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录