Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
affbc19a
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
affbc19a
编写于
5月 05, 2015
作者:
Y
Yan, Zheng
提交者:
Ilya Dryomov
6月 25, 2015
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ceph: make sure syncfs flushes all cap snaps
Signed-off-by:
N
Yan, Zheng
<
zyan@redhat.com
>
上级
622f3e25
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
76 addition
and
31 deletion
+76
-31
fs/ceph/caps.c
fs/ceph/caps.c
+11
-7
fs/ceph/mds_client.c
fs/ceph/mds_client.c
+62
-24
fs/ceph/mds_client.h
fs/ceph/mds_client.h
+1
-0
fs/ceph/snap.c
fs/ceph/snap.c
+2
-0
未找到文件。
fs/ceph/caps.c
浏览文件 @
affbc19a
...
...
@@ -1259,14 +1259,14 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
* asynchronously back to the MDS once sync writes complete and dirty
* data is written out.
*
* Unless @
again
is true, skip cap_snaps that were already sent to
* Unless @
kick
is true, skip cap_snaps that were already sent to
* the MDS (i.e., during this session).
*
* Called under i_ceph_lock. Takes s_mutex as needed.
*/
void
__ceph_flush_snaps
(
struct
ceph_inode_info
*
ci
,
struct
ceph_mds_session
**
psession
,
int
again
)
int
kick
)
__releases
(
ci
->
i_ceph_lock
)
__acquires
(
ci
->
i_ceph_lock
)
{
...
...
@@ -1307,7 +1307,7 @@ void __ceph_flush_snaps(struct ceph_inode_info *ci,
}
/* only flush each capsnap once */
if
(
!
again
&&
!
list_empty
(
&
capsnap
->
flushing_item
))
{
if
(
!
kick
&&
!
list_empty
(
&
capsnap
->
flushing_item
))
{
dout
(
"already flushed %p, skipping
\n
"
,
capsnap
);
continue
;
}
...
...
@@ -1317,6 +1317,9 @@ void __ceph_flush_snaps(struct ceph_inode_info *ci,
if
(
session
&&
session
->
s_mds
!=
mds
)
{
dout
(
"oops, wrong session %p mutex
\n
"
,
session
);
if
(
kick
)
goto
out
;
mutex_unlock
(
&
session
->
s_mutex
);
ceph_put_mds_session
(
session
);
session
=
NULL
;
...
...
@@ -1342,10 +1345,9 @@ void __ceph_flush_snaps(struct ceph_inode_info *ci,
capsnap
->
flush_tid
=
++
ci
->
i_cap_flush_last_tid
;
atomic_inc
(
&
capsnap
->
nref
);
if
(
!
list_empty
(
&
capsnap
->
flushing_item
))
list_del_init
(
&
capsnap
->
flushing_item
);
list_add_tail
(
&
capsnap
->
flushing_item
,
&
session
->
s_cap_snaps_flushing
);
if
(
list_empty
(
&
capsnap
->
flushing_item
))
list_add_tail
(
&
capsnap
->
flushing_item
,
&
session
->
s_cap_snaps_flushing
);
spin_unlock
(
&
ci
->
i_ceph_lock
);
dout
(
"flush_snaps %p cap_snap %p follows %lld tid %llu
\n
"
,
...
...
@@ -2876,6 +2878,7 @@ static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid,
struct
ceph_mds_session
*
session
)
{
struct
ceph_inode_info
*
ci
=
ceph_inode
(
inode
);
struct
ceph_mds_client
*
mdsc
=
ceph_sb_to_client
(
inode
->
i_sb
)
->
mdsc
;
u64
follows
=
le64_to_cpu
(
m
->
snap_follows
);
struct
ceph_cap_snap
*
capsnap
;
int
drop
=
0
;
...
...
@@ -2899,6 +2902,7 @@ static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid,
list_del
(
&
capsnap
->
ci_item
);
list_del
(
&
capsnap
->
flushing_item
);
ceph_put_cap_snap
(
capsnap
);
wake_up_all
(
&
mdsc
->
cap_flushing_wq
);
drop
=
1
;
break
;
}
else
{
...
...
fs/ceph/mds_client.c
浏览文件 @
affbc19a
...
...
@@ -1488,17 +1488,22 @@ int ceph_add_cap_releases(struct ceph_mds_client *mdsc,
return
err
;
}
static
int
check_cap_flush
(
struct
inode
*
inode
,
u64
want_flush_seq
)
static
int
check_cap_flush
(
struct
ceph_inode_info
*
ci
,
u64
want_flush_seq
,
u64
want_snap_seq
)
{
struct
ceph_inode_info
*
ci
=
ceph_inode
(
inode
);
int
ret
;
int
ret1
=
1
,
ret2
=
1
;
spin_lock
(
&
ci
->
i_ceph_lock
);
if
(
ci
->
i_flushing_caps
)
ret
=
ci
->
i_cap_flush_seq
>=
want_flush_seq
;
else
ret
=
1
;
if
(
want_flush_seq
>
0
&&
ci
->
i_flushing_caps
)
ret1
=
ci
->
i_cap_flush_seq
>=
want_flush_seq
;
if
(
want_snap_seq
>
0
&&
!
list_empty
(
&
ci
->
i_cap_snaps
))
{
struct
ceph_cap_snap
*
capsnap
=
list_first_entry
(
&
ci
->
i_cap_snaps
,
struct
ceph_cap_snap
,
ci_item
);
ret2
=
capsnap
->
follows
>=
want_snap_seq
;
}
spin_unlock
(
&
ci
->
i_ceph_lock
);
return
ret
;
return
ret
1
&&
ret2
;
}
/*
...
...
@@ -1506,45 +1511,72 @@ static int check_cap_flush(struct inode *inode, u64 want_flush_seq)
*
* returns true if we've flushed through want_flush_seq
*/
static
void
wait_caps_flush
(
struct
ceph_mds_client
*
mdsc
,
u64
want_flush_seq
)
static
void
wait_caps_flush
(
struct
ceph_mds_client
*
mdsc
,
u64
want_flush_seq
,
u64
want_snap_seq
)
{
int
mds
;
dout
(
"check_cap_flush want %lld
\n
"
,
want_flush_seq
);
mutex_lock
(
&
mdsc
->
mutex
);
for
(
mds
=
0
;
mds
<
mdsc
->
max_sessions
;
mds
++
)
{
for
(
mds
=
0
;
mds
<
mdsc
->
max_sessions
;
)
{
struct
ceph_mds_session
*
session
=
mdsc
->
sessions
[
mds
];
struct
inode
*
inode
=
NULL
;
struct
inode
*
inode
1
=
NULL
,
*
inode2
=
NULL
;
if
(
!
session
)
if
(
!
session
)
{
mds
++
;
continue
;
}
get_session
(
session
);
mutex_unlock
(
&
mdsc
->
mutex
);
mutex_lock
(
&
session
->
s_mutex
);
if
(
!
list_empty
(
&
session
->
s_cap_flushing
))
{
struct
ceph_inode_info
*
ci
=
list_
entry
(
session
->
s_cap_flushing
.
next
,
struct
ceph_inode_info
,
i_flushing_item
);
list_
first_entry
(
&
session
->
s_cap_flushing
,
struct
ceph_inode_info
,
i_flushing_item
);
if
(
!
check_cap_flush
(
&
ci
->
vfs_inode
,
want_flush_seq
))
{
if
(
!
check_cap_flush
(
ci
,
want_flush_seq
,
0
))
{
dout
(
"check_cap_flush still flushing %p "
"seq %lld <= %lld to mds%d
\n
"
,
&
ci
->
vfs_inode
,
ci
->
i_cap_flush_seq
,
want_flush_seq
,
session
->
s_mds
);
inode
=
igrab
(
&
ci
->
vfs_inode
);
want_flush_seq
,
mds
);
inode1
=
igrab
(
&
ci
->
vfs_inode
);
}
}
if
(
!
list_empty
(
&
session
->
s_cap_snaps_flushing
))
{
struct
ceph_cap_snap
*
capsnap
=
list_first_entry
(
&
session
->
s_cap_snaps_flushing
,
struct
ceph_cap_snap
,
flushing_item
);
struct
ceph_inode_info
*
ci
=
capsnap
->
ci
;
if
(
!
check_cap_flush
(
ci
,
0
,
want_snap_seq
))
{
dout
(
"check_cap_flush still flushing snap %p "
"follows %lld <= %lld to mds%d
\n
"
,
&
ci
->
vfs_inode
,
capsnap
->
follows
,
want_snap_seq
,
mds
);
inode2
=
igrab
(
&
ci
->
vfs_inode
);
}
}
mutex_unlock
(
&
session
->
s_mutex
);
ceph_put_mds_session
(
session
);
if
(
inode
)
{
if
(
inode
1
)
{
wait_event
(
mdsc
->
cap_flushing_wq
,
check_cap_flush
(
inode
,
want_flush_seq
));
iput
(
inode
);
check_cap_flush
(
ceph_inode
(
inode1
),
want_flush_seq
,
0
));
iput
(
inode1
);
}
if
(
inode2
)
{
wait_event
(
mdsc
->
cap_flushing_wq
,
check_cap_flush
(
ceph_inode
(
inode2
),
0
,
want_snap_seq
));
iput
(
inode2
);
}
if
(
!
inode1
&&
!
inode2
)
mds
++
;
mutex_lock
(
&
mdsc
->
mutex
);
}
...
...
@@ -3391,6 +3423,7 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
atomic_set
(
&
mdsc
->
num_sessions
,
0
);
mdsc
->
max_sessions
=
0
;
mdsc
->
stopping
=
0
;
mdsc
->
last_snap_seq
=
0
;
init_rwsem
(
&
mdsc
->
snap_rwsem
);
mdsc
->
snap_realms
=
RB_ROOT
;
INIT_LIST_HEAD
(
&
mdsc
->
snap_empty
);
...
...
@@ -3517,7 +3550,7 @@ static void wait_unsafe_requests(struct ceph_mds_client *mdsc, u64 want_tid)
void
ceph_mdsc_sync
(
struct
ceph_mds_client
*
mdsc
)
{
u64
want_tid
,
want_flush
;
u64
want_tid
,
want_flush
,
want_snap
;
if
(
mdsc
->
fsc
->
mount_state
==
CEPH_MOUNT_SHUTDOWN
)
return
;
...
...
@@ -3532,10 +3565,15 @@ void ceph_mdsc_sync(struct ceph_mds_client *mdsc)
want_flush
=
mdsc
->
cap_flush_seq
;
spin_unlock
(
&
mdsc
->
cap_dirty_lock
);
dout
(
"sync want tid %lld flush_seq %lld
\n
"
,
want_tid
,
want_flush
);
down_read
(
&
mdsc
->
snap_rwsem
);
want_snap
=
mdsc
->
last_snap_seq
;
up_read
(
&
mdsc
->
snap_rwsem
);
dout
(
"sync want tid %lld flush_seq %lld snap_seq %lld
\n
"
,
want_tid
,
want_flush
,
want_snap
);
wait_unsafe_requests
(
mdsc
,
want_tid
);
wait_caps_flush
(
mdsc
,
want_flush
);
wait_caps_flush
(
mdsc
,
want_flush
,
want_snap
);
}
/*
...
...
fs/ceph/mds_client.h
浏览文件 @
affbc19a
...
...
@@ -290,6 +290,7 @@ struct ceph_mds_client {
* references (implying they contain no inodes with caps) that
* should be destroyed.
*/
u64
last_snap_seq
;
struct
rw_semaphore
snap_rwsem
;
struct
rb_root
snap_realms
;
struct
list_head
snap_empty
;
...
...
fs/ceph/snap.c
浏览文件 @
affbc19a
...
...
@@ -730,6 +730,8 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
/* queue realm for cap_snap creation */
list_add
(
&
realm
->
dirty_item
,
&
dirty_realms
);
if
(
realm
->
seq
>
mdsc
->
last_snap_seq
)
mdsc
->
last_snap_seq
=
realm
->
seq
;
invalidate
=
1
;
}
else
if
(
!
realm
->
cached_context
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录