Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
1643b43f
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
163
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看板
提交
1643b43f
编写于
4月 27, 2016
作者:
A
Al Viro
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
lookup_open(): lift the "fallback to !O_CREAT" logics from atomic_open()
Signed-off-by:
N
Al Viro
<
viro@zeniv.linux.org.uk
>
上级
b3d58eaf
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
55 addition
and
89 deletion
+55
-89
fs/namei.c
fs/namei.c
+55
-89
未找到文件。
fs/namei.c
浏览文件 @
1643b43f
...
...
@@ -2824,63 +2824,19 @@ static int may_o_create(struct path *dir, struct dentry *dentry, umode_t mode)
static
int
atomic_open
(
struct
nameidata
*
nd
,
struct
dentry
*
dentry
,
struct
path
*
path
,
struct
file
*
file
,
const
struct
open_flags
*
op
,
bool
got_write
,
bool
need_lookup
,
int
open_flag
,
umode_t
mode
,
int
*
opened
)
{
struct
inode
*
dir
=
nd
->
path
.
dentry
->
d_inode
;
unsigned
open_flag
=
op
->
open_flag
;
umode_t
mode
;
int
error
;
int
acc_mode
;
int
create_error
=
0
;
struct
dentry
*
const
DENTRY_NOT_SET
=
(
void
*
)
-
1UL
;
bool
excl
;
BUG_ON
(
dentry
->
d_inode
);
mode
=
op
->
mode
;
if
((
open_flag
&
O_CREAT
)
&&
!
IS_POSIXACL
(
dir
))
mode
&=
~
current_umask
();
excl
=
(
open_flag
&
(
O_EXCL
|
O_CREAT
))
==
(
O_EXCL
|
O_CREAT
);
if
(
excl
)
open_flag
&=
~
O_TRUNC
;
/*
* Checking write permission is tricky, bacuse we don't know if we are
* going to actually need it: O_CREAT opens should work as long as the
* file exists. But checking existence breaks atomicity. The trick is
* to check access and if not granted clear O_CREAT from the flags.
*
* Another problem is returing the "right" error value (e.g. for an
* O_EXCL open we want to return EEXIST not EROFS).
*/
if
(
open_flag
&
O_CREAT
)
{
if
(
unlikely
(
!
got_write
))
{
create_error
=
-
EROFS
;
if
(
open_flag
&
(
O_EXCL
|
O_TRUNC
))
{
/* Fall back and fail with the right error */
goto
no_open
;
}
/* No side effects, safe to clear O_CREAT */
open_flag
&=
~
O_CREAT
;
}
else
{
create_error
=
may_o_create
(
&
nd
->
path
,
dentry
,
mode
);
if
(
create_error
)
{
if
(
open_flag
&
O_EXCL
)
goto
no_open
;
open_flag
&=
~
O_CREAT
;
}
}
}
else
if
((
open_flag
&
(
O_TRUNC
|
O_WRONLY
|
O_RDWR
))
&&
unlikely
(
!
got_write
))
{
/*
* No O_CREATE -> atomicity not a requirement -> fall
* back to lookup + open
*/
goto
no_open
;
}
if
(
nd
->
flags
&
LOOKUP_DIRECTORY
)
open_flag
|=
O_DIRECTORY
;
...
...
@@ -2889,11 +2845,8 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
error
=
dir
->
i_op
->
atomic_open
(
dir
,
dentry
,
file
,
open_to_namei_flags
(
open_flag
),
mode
,
opened
);
if
(
error
<
0
)
{
if
(
create_error
&&
error
==
-
ENOENT
)
error
=
create_error
;
if
(
error
<
0
)
goto
out
;
}
if
(
error
)
{
/* returned 1, that is */
if
(
WARN_ON
(
file
->
f_path
.
dentry
==
DENTRY_NOT_SET
))
{
...
...
@@ -2906,7 +2859,9 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
}
if
(
*
opened
&
FILE_CREATED
)
fsnotify_create
(
dir
,
dentry
);
goto
looked_up
;
path
->
dentry
=
dentry
;
path
->
mnt
=
nd
->
path
.
mnt
;
return
1
;
}
/*
...
...
@@ -2925,21 +2880,6 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
out:
dput
(
dentry
);
return
error
;
no_open:
if
(
need_lookup
)
{
dentry
=
lookup_real
(
dir
,
dentry
,
nd
->
flags
);
if
(
IS_ERR
(
dentry
))
return
PTR_ERR
(
dentry
);
}
looked_up:
if
(
create_error
&&
!
dentry
->
d_inode
)
{
error
=
create_error
;
goto
out
;
}
path
->
dentry
=
dentry
;
path
->
mnt
=
nd
->
path
.
mnt
;
return
1
;
}
/*
...
...
@@ -2967,9 +2907,11 @@ static int lookup_open(struct nameidata *nd, struct path *path,
{
struct
dentry
*
dir
=
nd
->
path
.
dentry
;
struct
inode
*
dir_inode
=
dir
->
d_inode
;
int
open_flag
=
op
->
open_flag
;
struct
dentry
*
dentry
;
int
error
;
int
error
,
create_error
=
0
;
bool
need_lookup
=
false
;
umode_t
mode
=
op
->
mode
;
if
(
unlikely
(
IS_DEADDIR
(
dir_inode
)))
return
-
ENOENT
;
...
...
@@ -2989,50 +2931,74 @@ static int lookup_open(struct nameidata *nd, struct path *path,
goto
out_no_open
;
}
/*
* Checking write permission is tricky, bacuse we don't know if we are
* going to actually need it: O_CREAT opens should work as long as the
* file exists. But checking existence breaks atomicity. The trick is
* to check access and if not granted clear O_CREAT from the flags.
*
* Another problem is returing the "right" error value (e.g. for an
* O_EXCL open we want to return EEXIST not EROFS).
*/
if
(
open_flag
&
O_CREAT
)
{
if
(
!
IS_POSIXACL
(
dir
->
d_inode
))
mode
&=
~
current_umask
();
if
(
unlikely
(
!
got_write
))
{
create_error
=
-
EROFS
;
open_flag
&=
~
O_CREAT
;
if
(
open_flag
&
(
O_EXCL
|
O_TRUNC
))
goto
no_open
;
/* No side effects, safe to clear O_CREAT */
}
else
{
create_error
=
may_o_create
(
&
nd
->
path
,
dentry
,
mode
);
if
(
create_error
)
{
open_flag
&=
~
O_CREAT
;
if
(
open_flag
&
O_EXCL
)
goto
no_open
;
}
}
}
else
if
((
open_flag
&
(
O_TRUNC
|
O_WRONLY
|
O_RDWR
))
&&
unlikely
(
!
got_write
))
{
/*
* No O_CREATE -> atomicity not a requirement -> fall
* back to lookup + open
*/
goto
no_open
;
}
if
(
dir_inode
->
i_op
->
atomic_open
)
{
return
atomic_open
(
nd
,
dentry
,
path
,
file
,
op
,
got_write
,
need_lookup
,
opened
);
error
=
atomic_open
(
nd
,
dentry
,
path
,
file
,
op
,
open_flag
,
mode
,
opened
);
if
(
unlikely
(
error
==
-
ENOENT
)
&&
create_error
)
error
=
create_error
;
return
error
;
}
no_open:
if
(
need_lookup
)
{
BUG_ON
(
dentry
->
d_inode
);
dentry
=
lookup_real
(
dir_inode
,
dentry
,
nd
->
flags
);
if
(
IS_ERR
(
dentry
))
return
PTR_ERR
(
dentry
);
}
/* Negative dentry, just create the file */
if
(
!
dentry
->
d_inode
&&
(
op
->
open_flag
&
O_CREAT
))
{
umode_t
mode
=
op
->
mode
;
if
(
!
IS_POSIXACL
(
dir
->
d_inode
))
mode
&=
~
current_umask
();
/*
* This write is needed to ensure that a
* rw->ro transition does not occur between
* the time when the file is created and when
* a permanent write count is taken through
* the 'struct file' in finish_open().
*/
if
(
!
got_write
)
{
error
=
-
EROFS
;
goto
out_dput
;
}
if
(
!
dentry
->
d_inode
&&
(
open_flag
&
O_CREAT
))
{
*
opened
|=
FILE_CREATED
;
audit_inode_child
(
dir_inode
,
dentry
,
AUDIT_TYPE_CHILD_CREATE
);
error
=
may_o_create
(
&
nd
->
path
,
dentry
,
mode
);
if
(
error
)
goto
out_dput
;
if
(
!
dir_inode
->
i_op
->
create
)
{
error
=
-
EACCES
;
goto
out_dput
;
}
error
=
dir_inode
->
i_op
->
create
(
dir_inode
,
dentry
,
mode
,
op
->
op
en_flag
&
O_EXCL
);
open_flag
&
O_EXCL
);
if
(
error
)
goto
out_dput
;
fsnotify_create
(
dir_inode
,
dentry
);
}
if
(
unlikely
(
create_error
)
&&
!
dentry
->
d_inode
)
{
error
=
create_error
;
goto
out_dput
;
}
out_no_open:
path
->
dentry
=
dentry
;
path
->
mnt
=
nd
->
path
.
mnt
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录