Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
0b4aae7a
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,发现更多精彩内容 >>
提交
0b4aae7a
编写于
6月 20, 2008
作者:
T
Trond Myklebust
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
NFS: Reduce the stack usage in NFSv3 create operations
Signed-off-by:
N
Trond Myklebust
<
Trond.Myklebust@netapp.com
>
上级
57dc9a57
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
142 addition
and
129 deletion
+142
-129
fs/nfs/nfs3proc.c
fs/nfs/nfs3proc.c
+142
-129
未找到文件。
fs/nfs/nfs3proc.c
浏览文件 @
0b4aae7a
...
...
@@ -248,6 +248,53 @@ static int nfs3_proc_readlink(struct inode *inode, struct page *page,
return
status
;
}
struct
nfs3_createdata
{
struct
rpc_message
msg
;
union
{
struct
nfs3_createargs
create
;
struct
nfs3_mkdirargs
mkdir
;
struct
nfs3_symlinkargs
symlink
;
struct
nfs3_mknodargs
mknod
;
}
arg
;
struct
nfs3_diropres
res
;
struct
nfs_fh
fh
;
struct
nfs_fattr
fattr
;
struct
nfs_fattr
dir_attr
;
};
static
struct
nfs3_createdata
*
nfs3_alloc_createdata
(
void
)
{
struct
nfs3_createdata
*
data
;
data
=
kzalloc
(
sizeof
(
*
data
),
GFP_KERNEL
);
if
(
data
!=
NULL
)
{
data
->
msg
.
rpc_argp
=
&
data
->
arg
;
data
->
msg
.
rpc_resp
=
&
data
->
res
;
data
->
res
.
fh
=
&
data
->
fh
;
data
->
res
.
fattr
=
&
data
->
fattr
;
data
->
res
.
dir_attr
=
&
data
->
dir_attr
;
nfs_fattr_init
(
data
->
res
.
fattr
);
nfs_fattr_init
(
data
->
res
.
dir_attr
);
}
return
data
;
}
static
int
nfs3_do_create
(
struct
inode
*
dir
,
struct
dentry
*
dentry
,
struct
nfs3_createdata
*
data
)
{
int
status
;
status
=
rpc_call_sync
(
NFS_CLIENT
(
dir
),
&
data
->
msg
,
0
);
nfs_post_op_update_inode
(
dir
,
data
->
res
.
dir_attr
);
if
(
status
==
0
)
status
=
nfs_instantiate
(
dentry
,
data
->
res
.
fh
,
data
->
res
.
fattr
);
return
status
;
}
static
void
nfs3_free_createdata
(
struct
nfs3_createdata
*
data
)
{
kfree
(
data
);
}
/*
* Create a regular file.
* For now, we don't implement O_EXCL.
...
...
@@ -256,70 +303,60 @@ static int
nfs3_proc_create
(
struct
inode
*
dir
,
struct
dentry
*
dentry
,
struct
iattr
*
sattr
,
int
flags
,
struct
nameidata
*
nd
)
{
struct
nfs_fh
fhandle
;
struct
nfs_fattr
fattr
;
struct
nfs_fattr
dir_attr
;
struct
nfs3_createargs
arg
=
{
.
fh
=
NFS_FH
(
dir
),
.
name
=
dentry
->
d_name
.
name
,
.
len
=
dentry
->
d_name
.
len
,
.
sattr
=
sattr
,
};
struct
nfs3_diropres
res
=
{
.
dir_attr
=
&
dir_attr
,
.
fh
=
&
fhandle
,
.
fattr
=
&
fattr
};
struct
rpc_message
msg
=
{
.
rpc_proc
=
&
nfs3_procedures
[
NFS3PROC_CREATE
],
.
rpc_argp
=
&
arg
,
.
rpc_resp
=
&
res
,
};
struct
nfs3_createdata
*
data
;
mode_t
mode
=
sattr
->
ia_mode
;
int
status
;
int
status
=
-
ENOMEM
;
dprintk
(
"NFS call create %s
\n
"
,
dentry
->
d_name
.
name
);
arg
.
createmode
=
NFS3_CREATE_UNCHECKED
;
data
=
nfs3_alloc_createdata
();
if
(
data
==
NULL
)
goto
out
;
data
->
msg
.
rpc_proc
=
&
nfs3_procedures
[
NFS3PROC_CREATE
];
data
->
arg
.
create
.
fh
=
NFS_FH
(
dir
);
data
->
arg
.
create
.
name
=
dentry
->
d_name
.
name
;
data
->
arg
.
create
.
len
=
dentry
->
d_name
.
len
;
data
->
arg
.
create
.
sattr
=
sattr
;
data
->
arg
.
create
.
createmode
=
NFS3_CREATE_UNCHECKED
;
if
(
flags
&
O_EXCL
)
{
arg
.
createmode
=
NFS3_CREATE_EXCLUSIVE
;
arg
.
verifier
[
0
]
=
jiffies
;
arg
.
verifier
[
1
]
=
current
->
pid
;
data
->
arg
.
create
.
createmode
=
NFS3_CREATE_EXCLUSIVE
;
data
->
arg
.
create
.
verifier
[
0
]
=
jiffies
;
data
->
arg
.
create
.
verifier
[
1
]
=
current
->
pid
;
}
sattr
->
ia_mode
&=
~
current
->
fs
->
umask
;
again:
nfs_fattr_init
(
&
dir_attr
);
nfs_fattr_init
(
&
fattr
);
status
=
rpc_call_sync
(
NFS_CLIENT
(
dir
),
&
msg
,
0
);
nfs_refresh_inode
(
dir
,
&
dir_attr
);
for
(;;)
{
status
=
nfs3_do_create
(
dir
,
dentry
,
data
);
/* If the server doesn't support the exclusive creation semantics,
* try again with simple 'guarded' mode. */
if
(
status
==
-
ENOTSUPP
)
{
switch
(
arg
.
createmode
)
{
if
(
status
!=
-
ENOTSUPP
)
break
;
/* If the server doesn't support the exclusive creation
* semantics, try again with simple 'guarded' mode. */
switch
(
data
->
arg
.
create
.
createmode
)
{
case
NFS3_CREATE_EXCLUSIVE
:
arg
.
createmode
=
NFS3_CREATE_GUARDED
;
data
->
arg
.
create
.
createmode
=
NFS3_CREATE_GUARDED
;
break
;
case
NFS3_CREATE_GUARDED
:
arg
.
createmode
=
NFS3_CREATE_UNCHECKED
;
data
->
arg
.
create
.
createmode
=
NFS3_CREATE_UNCHECKED
;
break
;
case
NFS3_CREATE_UNCHECKED
:
goto
out
;
}
goto
again
;
nfs_fattr_init
(
data
->
res
.
dir_attr
);
nfs_fattr_init
(
data
->
res
.
fattr
);
}
if
(
status
==
0
)
status
=
nfs_instantiate
(
dentry
,
&
fhandle
,
&
fattr
);
if
(
status
!=
0
)
goto
out
;
/* When we created the file with exclusive semantics, make
* sure we set the attributes afterwards. */
if
(
arg
.
createmode
==
NFS3_CREATE_EXCLUSIVE
)
{
if
(
data
->
arg
.
create
.
createmode
==
NFS3_CREATE_EXCLUSIVE
)
{
dprintk
(
"NFS call setattr (post-create)
\n
"
);
if
(
!
(
sattr
->
ia_valid
&
ATTR_ATIME_SET
))
...
...
@@ -330,14 +367,15 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
/* Note: we could use a guarded setattr here, but I'm
* not sure this buys us anything (and I'd have
* to revamp the NFSv3 XDR code) */
status
=
nfs3_proc_setattr
(
dentry
,
&
fattr
,
sattr
);
nfs_post_op_update_inode
(
dentry
->
d_inode
,
&
fattr
);
status
=
nfs3_proc_setattr
(
dentry
,
data
->
res
.
fattr
,
sattr
);
nfs_post_op_update_inode
(
dentry
->
d_inode
,
data
->
res
.
fattr
);
dprintk
(
"NFS reply setattr (post-create): %d
\n
"
,
status
);
}
if
(
status
!=
0
)
goto
out
;
}
status
=
nfs3_proc_set_default_acl
(
dir
,
dentry
->
d_inode
,
mode
);
out:
nfs3_free_createdata
(
data
);
dprintk
(
"NFS reply create: %d
\n
"
,
status
);
return
status
;
}
...
...
@@ -452,40 +490,28 @@ static int
nfs3_proc_symlink
(
struct
inode
*
dir
,
struct
dentry
*
dentry
,
struct
page
*
page
,
unsigned
int
len
,
struct
iattr
*
sattr
)
{
struct
nfs_fh
fhandle
;
struct
nfs_fattr
fattr
,
dir_attr
;
struct
nfs3_symlinkargs
arg
=
{
.
fromfh
=
NFS_FH
(
dir
),
.
fromname
=
dentry
->
d_name
.
name
,
.
fromlen
=
dentry
->
d_name
.
len
,
.
pages
=
&
page
,
.
pathlen
=
len
,
.
sattr
=
sattr
};
struct
nfs3_diropres
res
=
{
.
dir_attr
=
&
dir_attr
,
.
fh
=
&
fhandle
,
.
fattr
=
&
fattr
};
struct
rpc_message
msg
=
{
.
rpc_proc
=
&
nfs3_procedures
[
NFS3PROC_SYMLINK
],
.
rpc_argp
=
&
arg
,
.
rpc_resp
=
&
res
,
};
int
status
;
struct
nfs3_createdata
*
data
;
int
status
=
-
ENOMEM
;
if
(
len
>
NFS3_MAXPATHLEN
)
return
-
ENAMETOOLONG
;
dprintk
(
"NFS call symlink %s
\n
"
,
dentry
->
d_name
.
name
);
nfs_fattr_init
(
&
dir_attr
);
nfs_fattr_init
(
&
fattr
);
status
=
rpc_call_sync
(
NFS_CLIENT
(
dir
),
&
msg
,
0
);
nfs_post_op_update_inode
(
dir
,
&
dir_attr
);
if
(
status
!=
0
)
data
=
nfs3_alloc_createdata
();
if
(
data
==
NULL
)
goto
out
;
status
=
nfs_instantiate
(
dentry
,
&
fhandle
,
&
fattr
);
data
->
msg
.
rpc_proc
=
&
nfs3_procedures
[
NFS3PROC_SYMLINK
];
data
->
arg
.
symlink
.
fromfh
=
NFS_FH
(
dir
);
data
->
arg
.
symlink
.
fromname
=
dentry
->
d_name
.
name
;
data
->
arg
.
symlink
.
fromlen
=
dentry
->
d_name
.
len
;
data
->
arg
.
symlink
.
pages
=
&
page
;
data
->
arg
.
symlink
.
pathlen
=
len
;
data
->
arg
.
symlink
.
sattr
=
sattr
;
status
=
nfs3_do_create
(
dir
,
dentry
,
data
);
nfs3_free_createdata
(
data
);
out:
dprintk
(
"NFS reply symlink: %d
\n
"
,
status
);
return
status
;
...
...
@@ -494,42 +520,31 @@ nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
static
int
nfs3_proc_mkdir
(
struct
inode
*
dir
,
struct
dentry
*
dentry
,
struct
iattr
*
sattr
)
{
struct
nfs_fh
fhandle
;
struct
nfs_fattr
fattr
,
dir_attr
;
struct
nfs3_mkdirargs
arg
=
{
.
fh
=
NFS_FH
(
dir
),
.
name
=
dentry
->
d_name
.
name
,
.
len
=
dentry
->
d_name
.
len
,
.
sattr
=
sattr
};
struct
nfs3_diropres
res
=
{
.
dir_attr
=
&
dir_attr
,
.
fh
=
&
fhandle
,
.
fattr
=
&
fattr
};
struct
rpc_message
msg
=
{
.
rpc_proc
=
&
nfs3_procedures
[
NFS3PROC_MKDIR
],
.
rpc_argp
=
&
arg
,
.
rpc_resp
=
&
res
,
};
struct
nfs3_createdata
*
data
;
int
mode
=
sattr
->
ia_mode
;
int
status
;
int
status
=
-
ENOMEM
;
dprintk
(
"NFS call mkdir %s
\n
"
,
dentry
->
d_name
.
name
);
sattr
->
ia_mode
&=
~
current
->
fs
->
umask
;
nfs_fattr_init
(
&
dir_attr
);
nfs_fattr_init
(
&
fattr
);
status
=
rpc_call_sync
(
NFS_CLIENT
(
dir
),
&
msg
,
0
);
nfs_post_op_update_inode
(
dir
,
&
dir_attr
);
if
(
status
!=
0
)
data
=
nfs3_alloc_createdata
();
if
(
data
==
NULL
)
goto
out
;
status
=
nfs_instantiate
(
dentry
,
&
fhandle
,
&
fattr
);
data
->
msg
.
rpc_proc
=
&
nfs3_procedures
[
NFS3PROC_MKDIR
];
data
->
arg
.
mkdir
.
fh
=
NFS_FH
(
dir
);
data
->
arg
.
mkdir
.
name
=
dentry
->
d_name
.
name
;
data
->
arg
.
mkdir
.
len
=
dentry
->
d_name
.
len
;
data
->
arg
.
mkdir
.
sattr
=
sattr
;
status
=
nfs3_do_create
(
dir
,
dentry
,
data
);
if
(
status
!=
0
)
goto
out
;
status
=
nfs3_proc_set_default_acl
(
dir
,
dentry
->
d_inode
,
mode
);
out:
nfs3_free_createdata
(
data
);
dprintk
(
"NFS reply mkdir: %d
\n
"
,
status
);
return
status
;
}
...
...
@@ -615,52 +630,50 @@ static int
nfs3_proc_mknod
(
struct
inode
*
dir
,
struct
dentry
*
dentry
,
struct
iattr
*
sattr
,
dev_t
rdev
)
{
struct
nfs_fh
fh
;
struct
nfs_fattr
fattr
,
dir_attr
;
struct
nfs3_mknodargs
arg
=
{
.
fh
=
NFS_FH
(
dir
),
.
name
=
dentry
->
d_name
.
name
,
.
len
=
dentry
->
d_name
.
len
,
.
sattr
=
sattr
,
.
rdev
=
rdev
};
struct
nfs3_diropres
res
=
{
.
dir_attr
=
&
dir_attr
,
.
fh
=
&
fh
,
.
fattr
=
&
fattr
};
struct
rpc_message
msg
=
{
.
rpc_proc
=
&
nfs3_procedures
[
NFS3PROC_MKNOD
],
.
rpc_argp
=
&
arg
,
.
rpc_resp
=
&
res
,
};
struct
nfs3_createdata
*
data
;
mode_t
mode
=
sattr
->
ia_mode
;
int
status
;
switch
(
sattr
->
ia_mode
&
S_IFMT
)
{
case
S_IFBLK
:
arg
.
type
=
NF3BLK
;
break
;
case
S_IFCHR
:
arg
.
type
=
NF3CHR
;
break
;
case
S_IFIFO
:
arg
.
type
=
NF3FIFO
;
break
;
case
S_IFSOCK
:
arg
.
type
=
NF3SOCK
;
break
;
default:
return
-
EINVAL
;
}
int
status
=
-
ENOMEM
;
dprintk
(
"NFS call mknod %s %u:%u
\n
"
,
dentry
->
d_name
.
name
,
MAJOR
(
rdev
),
MINOR
(
rdev
));
sattr
->
ia_mode
&=
~
current
->
fs
->
umask
;
nfs_fattr_init
(
&
dir_attr
);
nfs_fattr_init
(
&
fattr
);
status
=
rpc_call_sync
(
NFS_CLIENT
(
dir
),
&
msg
,
0
);
nfs_post_op_update_inode
(
dir
,
&
dir_attr
);
if
(
status
!=
0
)
data
=
nfs3_alloc_createdata
();
if
(
data
==
NULL
)
goto
out
;
data
->
msg
.
rpc_proc
=
&
nfs3_procedures
[
NFS3PROC_MKNOD
];
data
->
arg
.
mknod
.
fh
=
NFS_FH
(
dir
);
data
->
arg
.
mknod
.
name
=
dentry
->
d_name
.
name
;
data
->
arg
.
mknod
.
len
=
dentry
->
d_name
.
len
;
data
->
arg
.
mknod
.
sattr
=
sattr
;
data
->
arg
.
mknod
.
rdev
=
rdev
;
switch
(
sattr
->
ia_mode
&
S_IFMT
)
{
case
S_IFBLK
:
data
->
arg
.
mknod
.
type
=
NF3BLK
;
break
;
case
S_IFCHR
:
data
->
arg
.
mknod
.
type
=
NF3CHR
;
break
;
case
S_IFIFO
:
data
->
arg
.
mknod
.
type
=
NF3FIFO
;
break
;
case
S_IFSOCK
:
data
->
arg
.
mknod
.
type
=
NF3SOCK
;
break
;
default:
status
=
-
EINVAL
;
goto
out
;
status
=
nfs_instantiate
(
dentry
,
&
fh
,
&
fattr
);
}
status
=
nfs3_do_create
(
dir
,
dentry
,
data
);
if
(
status
!=
0
)
goto
out
;
status
=
nfs3_proc_set_default_acl
(
dir
,
dentry
->
d_inode
,
mode
);
out:
nfs3_free_createdata
(
data
);
dprintk
(
"NFS reply mknod: %d
\n
"
,
status
);
return
status
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录