Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
1b91dbdd
cloud-kernel
项目概览
openanolis
/
cloud-kernel
接近 2 年 前同步成功
通知
169
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看板
提交
1b91dbdd
编写于
7月 27, 2016
作者:
M
Miklos Szeredi
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'd_real' into overlayfs-next
上级
523d939e
0cac643c
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
80 addition
and
78 deletion
+80
-78
Documentation/filesystems/Locking
Documentation/filesystems/Locking
+3
-2
Documentation/filesystems/vfs.txt
Documentation/filesystems/vfs.txt
+26
-14
fs/dcache.c
fs/dcache.c
+0
-3
fs/namei.c
fs/namei.c
+1
-1
fs/open.c
fs/open.c
+4
-4
fs/overlayfs/inode.c
fs/overlayfs/inode.c
+10
-21
fs/overlayfs/overlayfs.h
fs/overlayfs/overlayfs.h
+1
-1
fs/overlayfs/super.c
fs/overlayfs/super.c
+14
-6
include/linux/dcache.h
include/linux/dcache.h
+20
-20
include/linux/fs.h
include/linux/fs.h
+1
-6
未找到文件。
Documentation/filesystems/Locking
浏览文件 @
1b91dbdd
...
...
@@ -20,6 +20,8 @@ prototypes:
char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
struct vfsmount *(*d_automount)(struct path *path);
int (*d_manage)(struct dentry *, bool);
struct dentry *(*d_real)(struct dentry *, const struct inode *,
unsigned int);
locking rules:
rename_lock ->d_lock may block rcu-walk
...
...
@@ -34,6 +36,7 @@ d_iput: no no yes no
d_dname: no no no no
d_automount: no no yes no
d_manage: no no yes (ref-walk) maybe
d_real no no yes no
--------------------------- inode_operations ---------------------------
prototypes:
...
...
@@ -66,7 +69,6 @@ prototypes:
struct file *, unsigned open_flag,
umode_t create_mode, int *opened);
int (*tmpfile) (struct inode *, struct dentry *, umode_t);
int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
locking rules:
all may block
...
...
@@ -95,7 +97,6 @@ fiemap: no
update_time: no
atomic_open: yes
tmpfile: no
dentry_open: no
Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
victim.
...
...
Documentation/filesystems/vfs.txt
浏览文件 @
1b91dbdd
...
...
@@ -364,7 +364,6 @@ struct inode_operations {
int (*atomic_open)(struct inode *, struct dentry *, struct file *,
unsigned open_flag, umode_t create_mode, int *opened);
int (*tmpfile) (struct inode *, struct dentry *, umode_t);
int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
};
Again, all methods are called without any locks being held, unless
...
...
@@ -696,13 +695,6 @@ struct address_space_operations {
but instead uses bmap to find out where the blocks in the file
are and uses those addresses directly.
dentry_open: *WARNING: probably going away soon, do not use!* This is an
alternative to f_op->open(), the difference is that this method may open
a file not necessarily originating from the same filesystem as the one
i_op->open() was called on. It may be useful for stacking filesystems
which want to allow native I/O directly on underlying files.
invalidatepage: If a page has PagePrivate set, then invalidatepage
will be called when part or all of the page is to be removed
from the address space. This generally corresponds to either a
...
...
@@ -938,6 +930,8 @@ struct dentry_operations {
char *(*d_dname)(struct dentry *, char *, int);
struct vfsmount *(*d_automount)(struct path *);
int (*d_manage)(struct dentry *, bool);
struct dentry *(*d_real)(struct dentry *, const struct inode *,
unsigned int);
};
d_revalidate: called when the VFS needs to revalidate a dentry. This
...
...
@@ -1022,6 +1016,14 @@ struct dentry_operations {
at the end of the buffer, and returns a pointer to the first char.
dynamic_dname() helper function is provided to take care of this.
Example :
static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen)
{
return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
dentry->d_inode->i_ino);
}
d_automount: called when an automount dentry is to be traversed (optional).
This should create a new VFS mount record and return the record to the
caller. The caller is supplied with a path parameter giving the
...
...
@@ -1060,13 +1062,23 @@ struct dentry_operations {
This function is only used if DCACHE_MANAGE_TRANSIT is set on the
dentry being transited from.
Example :
d_real: overlay/union type filesystems implement this method to return one of
the underlying dentries hidden by the overlay. It is used in three
different modes:
static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen)
{
return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
dentry->d_inode->i_ino);
}
Called from open it may need to copy-up the file depending on the
supplied open flags. This mode is selected with a non-zero flags
argument. In this mode the d_real method can return an error.
Called from file_dentry() it returns the real dentry matching the inode
argument. The real dentry may be from a lower layer already copied up,
but still referenced from the file. This mode is selected with a
non-NULL inode argument. This will always succeed.
With NULL inode and zero flags the topmost real underlying dentry is
returned. This will always succeed.
This method is never called with both non-NULL inode and non-zero flags.
Each dentry has a pointer to its parent dentry, as well as a hash list
of child dentries. Child dentries are basically like files in a
...
...
fs/dcache.c
浏览文件 @
1b91dbdd
...
...
@@ -1729,7 +1729,6 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
DCACHE_OP_REVALIDATE
|
DCACHE_OP_WEAK_REVALIDATE
|
DCACHE_OP_DELETE
|
DCACHE_OP_SELECT_INODE
|
DCACHE_OP_REAL
));
dentry
->
d_op
=
op
;
if
(
!
op
)
...
...
@@ -1746,8 +1745,6 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
dentry
->
d_flags
|=
DCACHE_OP_DELETE
;
if
(
op
->
d_prune
)
dentry
->
d_flags
|=
DCACHE_OP_PRUNE
;
if
(
op
->
d_select_inode
)
dentry
->
d_flags
|=
DCACHE_OP_SELECT_INODE
;
if
(
op
->
d_real
)
dentry
->
d_flags
|=
DCACHE_OP_REAL
;
...
...
fs/namei.c
浏览文件 @
1b91dbdd
...
...
@@ -4328,7 +4328,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
* Check source == target.
* On overlayfs need to look at underlying inodes.
*/
if
(
vfs_select_inode
(
old_dentry
,
0
)
==
vfs_select_inode
(
new_dentry
,
0
))
if
(
d_real_inode
(
old_dentry
)
==
d_real_inode
(
new_dentry
))
return
0
;
error
=
may_delete
(
old_dir
,
old_dentry
,
is_dir
);
...
...
fs/open.c
浏览文件 @
1b91dbdd
...
...
@@ -840,13 +840,13 @@ EXPORT_SYMBOL(file_path);
int
vfs_open
(
const
struct
path
*
path
,
struct
file
*
file
,
const
struct
cred
*
cred
)
{
struct
inode
*
inode
=
vfs_select_inode
(
path
->
dentry
,
file
->
f_flags
);
struct
dentry
*
dentry
=
d_real
(
path
->
dentry
,
NULL
,
file
->
f_flags
);
if
(
IS_ERR
(
inode
))
return
PTR_ERR
(
inode
);
if
(
IS_ERR
(
dentry
))
return
PTR_ERR
(
dentry
);
file
->
f_path
=
*
path
;
return
do_dentry_open
(
file
,
inode
,
NULL
,
cred
);
return
do_dentry_open
(
file
,
d_backing_inode
(
dentry
)
,
NULL
,
cred
);
}
struct
file
*
dentry_open
(
const
struct
path
*
path
,
int
flags
,
...
...
fs/overlayfs/inode.c
浏览文件 @
1b91dbdd
...
...
@@ -351,36 +351,25 @@ static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type,
return
true
;
}
struct
inode
*
ovl_d_select_inode
(
struct
dentry
*
dentry
,
unsigned
file_flags
)
int
ovl_open_maybe_copy_up
(
struct
dentry
*
dentry
,
unsigned
int
file_flags
)
{
int
err
;
int
err
=
0
;
struct
path
realpath
;
enum
ovl_path_type
type
;
if
(
d_is_dir
(
dentry
))
return
d_backing_inode
(
dentry
);
type
=
ovl_path_real
(
dentry
,
&
realpath
);
if
(
ovl_open_need_copy_up
(
file_flags
,
type
,
realpath
.
dentry
))
{
err
=
ovl_want_write
(
dentry
);
if
(
err
)
return
ERR_PTR
(
err
);
if
(
file_flags
&
O_TRUNC
)
err
=
ovl_copy_up_truncate
(
dentry
);
else
err
=
ovl_copy_up
(
dentry
);
ovl_drop_write
(
dentry
);
if
(
err
)
return
ERR_PTR
(
err
);
ovl_path_upper
(
dentry
,
&
realpath
);
if
(
!
err
)
{
if
(
file_flags
&
O_TRUNC
)
err
=
ovl_copy_up_truncate
(
dentry
);
else
err
=
ovl_copy_up
(
dentry
);
ovl_drop_write
(
dentry
);
}
}
if
(
realpath
.
dentry
->
d_flags
&
DCACHE_OP_SELECT_INODE
)
return
realpath
.
dentry
->
d_op
->
d_select_inode
(
realpath
.
dentry
,
file_flags
);
return
d_backing_inode
(
realpath
.
dentry
);
return
err
;
}
static
const
struct
inode_operations
ovl_file_inode_operations
=
{
...
...
fs/overlayfs/overlayfs.h
浏览文件 @
1b91dbdd
...
...
@@ -179,7 +179,7 @@ ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode,
const
char
*
name
,
void
*
value
,
size_t
size
);
ssize_t
ovl_listxattr
(
struct
dentry
*
dentry
,
char
*
list
,
size_t
size
);
int
ovl_removexattr
(
struct
dentry
*
dentry
,
const
char
*
name
);
struct
inode
*
ovl_d_select_inode
(
struct
dentry
*
dentry
,
unsigned
file_flags
);
int
ovl_open_maybe_copy_up
(
struct
dentry
*
dentry
,
unsigned
int
file_flags
);
struct
inode
*
ovl_new_inode
(
struct
super_block
*
sb
,
umode_t
mode
,
struct
ovl_entry
*
oe
);
...
...
fs/overlayfs/super.c
浏览文件 @
1b91dbdd
...
...
@@ -304,7 +304,9 @@ static void ovl_dentry_release(struct dentry *dentry)
}
}
static
struct
dentry
*
ovl_d_real
(
struct
dentry
*
dentry
,
struct
inode
*
inode
)
static
struct
dentry
*
ovl_d_real
(
struct
dentry
*
dentry
,
const
struct
inode
*
inode
,
unsigned
int
open_flags
)
{
struct
dentry
*
real
;
...
...
@@ -314,6 +316,16 @@ static struct dentry *ovl_d_real(struct dentry *dentry, struct inode *inode)
goto
bug
;
}
if
(
d_is_negative
(
dentry
))
return
dentry
;
if
(
open_flags
)
{
int
err
=
ovl_open_maybe_copy_up
(
dentry
,
open_flags
);
if
(
err
)
return
ERR_PTR
(
err
);
}
real
=
ovl_dentry_upper
(
dentry
);
if
(
real
&&
(
!
inode
||
inode
==
d_inode
(
real
)))
return
real
;
...
...
@@ -326,9 +338,7 @@ static struct dentry *ovl_d_real(struct dentry *dentry, struct inode *inode)
return
real
;
/* Handle recursion */
if
(
real
->
d_flags
&
DCACHE_OP_REAL
)
return
real
->
d_op
->
d_real
(
real
,
inode
);
return
d_real
(
real
,
inode
,
open_flags
);
bug:
WARN
(
1
,
"ovl_d_real(%pd4, %s:%lu
\n
): real dentry not found
\n
"
,
dentry
,
inode
?
inode
->
i_sb
->
s_id
:
"NULL"
,
inode
?
inode
->
i_ino
:
0
);
...
...
@@ -378,13 +388,11 @@ static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags)
static
const
struct
dentry_operations
ovl_dentry_operations
=
{
.
d_release
=
ovl_dentry_release
,
.
d_select_inode
=
ovl_d_select_inode
,
.
d_real
=
ovl_d_real
,
};
static
const
struct
dentry_operations
ovl_reval_dentry_operations
=
{
.
d_release
=
ovl_dentry_release
,
.
d_select_inode
=
ovl_d_select_inode
,
.
d_real
=
ovl_d_real
,
.
d_revalidate
=
ovl_dentry_revalidate
,
.
d_weak_revalidate
=
ovl_dentry_weak_revalidate
,
...
...
include/linux/dcache.h
浏览文件 @
1b91dbdd
...
...
@@ -139,8 +139,8 @@ struct dentry_operations {
char
*
(
*
d_dname
)(
struct
dentry
*
,
char
*
,
int
);
struct
vfsmount
*
(
*
d_automount
)(
struct
path
*
);
int
(
*
d_manage
)(
struct
dentry
*
,
bool
);
struct
inode
*
(
*
d_select_inode
)(
struct
dentry
*
,
unsigned
);
struct
dentry
*
(
*
d_real
)(
struct
dentry
*
,
struct
inode
*
);
struct
dentry
*
(
*
d_real
)(
struct
dentry
*
,
const
struct
inode
*
,
unsigned
int
);
}
____cacheline_aligned
;
/*
...
...
@@ -206,10 +206,8 @@ struct dentry_operations {
#define DCACHE_MAY_FREE 0x00800000
#define DCACHE_FALLTHRU 0x01000000
/* Fall through to lower layer */
#define DCACHE_OP_SELECT_INODE 0x02000000
/* Unioned entry: dcache op selects inode */
#define DCACHE_ENCRYPTED_WITH_KEY 0x04000000
/* dir is encrypted with a valid key */
#define DCACHE_OP_REAL 0x08000000
#define DCACHE_ENCRYPTED_WITH_KEY 0x02000000
/* dir is encrypted with a valid key */
#define DCACHE_OP_REAL 0x04000000
#define DCACHE_PAR_LOOKUP 0x10000000
/* being looked up (with parent locked shared) */
#define DCACHE_DENTRY_CURSOR 0x20000000
...
...
@@ -557,25 +555,27 @@ static inline struct dentry *d_backing_dentry(struct dentry *upper)
return
upper
;
}
static
inline
struct
dentry
*
d_real
(
struct
dentry
*
dentry
)
/**
* d_real - Return the real dentry
* @dentry: the dentry to query
* @inode: inode to select the dentry from multiple layers (can be NULL)
* @flags: open flags to control copy-up behavior
*
* If dentry is on an union/overlay, then return the underlying, real dentry.
* Otherwise return the dentry itself.
*
* See also: Documentation/filesystems/vfs.txt
*/
static
inline
struct
dentry
*
d_real
(
struct
dentry
*
dentry
,
const
struct
inode
*
inode
,
unsigned
int
flags
)
{
if
(
unlikely
(
dentry
->
d_flags
&
DCACHE_OP_REAL
))
return
dentry
->
d_op
->
d_real
(
dentry
,
NULL
);
return
dentry
->
d_op
->
d_real
(
dentry
,
inode
,
flags
);
else
return
dentry
;
}
static
inline
struct
inode
*
vfs_select_inode
(
struct
dentry
*
dentry
,
unsigned
open_flags
)
{
struct
inode
*
inode
=
d_inode
(
dentry
);
if
(
inode
&&
unlikely
(
dentry
->
d_flags
&
DCACHE_OP_SELECT_INODE
))
inode
=
dentry
->
d_op
->
d_select_inode
(
dentry
,
open_flags
);
return
inode
;
}
/**
* d_real_inode - Return the real inode
* @dentry: The dentry to query
...
...
@@ -585,7 +585,7 @@ static inline struct inode *vfs_select_inode(struct dentry *dentry,
*/
static
inline
struct
inode
*
d_real_inode
(
struct
dentry
*
dentry
)
{
return
d_backing_inode
(
d_real
(
dentry
));
return
d_backing_inode
(
d_real
(
dentry
,
NULL
,
0
));
}
...
...
include/linux/fs.h
浏览文件 @
1b91dbdd
...
...
@@ -1272,12 +1272,7 @@ static inline struct inode *file_inode(const struct file *f)
static
inline
struct
dentry
*
file_dentry
(
const
struct
file
*
file
)
{
struct
dentry
*
dentry
=
file
->
f_path
.
dentry
;
if
(
unlikely
(
dentry
->
d_flags
&
DCACHE_OP_REAL
))
return
dentry
->
d_op
->
d_real
(
dentry
,
file_inode
(
file
));
else
return
dentry
;
return
d_real
(
file
->
f_path
.
dentry
,
file_inode
(
file
),
0
);
}
static
inline
int
locks_lock_file_wait
(
struct
file
*
filp
,
struct
file_lock
*
fl
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录