Skip to content

Commit

Permalink
ceph: always re-send cap flushes when MDS recovers
Browse files Browse the repository at this point in the history
commit e548e9b makes the kclient
only re-send cap flush once during MDS failover. If the kclient sends
a cap flush after MDS enters reconnect stage but before MDS recovers.
The kclient will skip re-sending the same cap flush when MDS recovers.

This causes problem for newly created inode. The MDS handles cap
flushes before replaying unsafe requests, so it's possible that MDS
find corresponding inode is missing when handling cap flush. The fix
is reverting to old behaviour: always re-send when MDS recovers

Signed-off-by: Yan, Zheng <zyan@redhat.com>
  • Loading branch information
ukernel committed Jul 20, 2015
1 parent eec6412 commit d2ca589
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 18 deletions.
22 changes: 5 additions & 17 deletions fs/ceph/caps.c
Expand Up @@ -1506,7 +1506,6 @@ static int __mark_caps_flushing(struct inode *inode,

swap(cf, ci->i_prealloc_cap_flush);
cf->caps = flushing;
cf->kick = false;

spin_lock(&mdsc->cap_dirty_lock);
list_del_init(&ci->i_dirty_item);
Expand Down Expand Up @@ -2123,8 +2122,7 @@ static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc,

static int __kick_flushing_caps(struct ceph_mds_client *mdsc,
struct ceph_mds_session *session,
struct ceph_inode_info *ci,
bool kick_all)
struct ceph_inode_info *ci)
{
struct inode *inode = &ci->vfs_inode;
struct ceph_cap *cap;
Expand All @@ -2150,9 +2148,7 @@ static int __kick_flushing_caps(struct ceph_mds_client *mdsc,

for (n = rb_first(&ci->i_cap_flush_tree); n; n = rb_next(n)) {
cf = rb_entry(n, struct ceph_cap_flush, i_node);
if (cf->tid < first_tid)
continue;
if (kick_all || cf->kick)
if (cf->tid >= first_tid)
break;
}
if (!n) {
Expand All @@ -2161,7 +2157,6 @@ static int __kick_flushing_caps(struct ceph_mds_client *mdsc,
}

cf = rb_entry(n, struct ceph_cap_flush, i_node);
cf->kick = false;

first_tid = cf->tid + 1;

Expand All @@ -2181,8 +2176,6 @@ void ceph_early_kick_flushing_caps(struct ceph_mds_client *mdsc,
{
struct ceph_inode_info *ci;
struct ceph_cap *cap;
struct ceph_cap_flush *cf;
struct rb_node *n;

dout("early_kick_flushing_caps mds%d\n", session->s_mds);
list_for_each_entry(ci, &session->s_cap_flushing, i_flushing_item) {
Expand All @@ -2205,16 +2198,11 @@ void ceph_early_kick_flushing_caps(struct ceph_mds_client *mdsc,
if ((cap->issued & ci->i_flushing_caps) !=
ci->i_flushing_caps) {
spin_unlock(&ci->i_ceph_lock);
if (!__kick_flushing_caps(mdsc, session, ci, true))
if (!__kick_flushing_caps(mdsc, session, ci))
continue;
spin_lock(&ci->i_ceph_lock);
}

for (n = rb_first(&ci->i_cap_flush_tree); n; n = rb_next(n)) {
cf = rb_entry(n, struct ceph_cap_flush, i_node);
cf->kick = true;
}

spin_unlock(&ci->i_ceph_lock);
}
}
Expand All @@ -2228,7 +2216,7 @@ void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,

dout("kick_flushing_caps mds%d\n", session->s_mds);
list_for_each_entry(ci, &session->s_cap_flushing, i_flushing_item) {
int delayed = __kick_flushing_caps(mdsc, session, ci, false);
int delayed = __kick_flushing_caps(mdsc, session, ci);
if (delayed) {
spin_lock(&ci->i_ceph_lock);
__cap_delay_requeue(mdsc, ci);
Expand Down Expand Up @@ -2261,7 +2249,7 @@ static void kick_flushing_inode_caps(struct ceph_mds_client *mdsc,

spin_unlock(&ci->i_ceph_lock);

delayed = __kick_flushing_caps(mdsc, session, ci, true);
delayed = __kick_flushing_caps(mdsc, session, ci);
if (delayed) {
spin_lock(&ci->i_ceph_lock);
__cap_delay_requeue(mdsc, ci);
Expand Down
1 change: 0 additions & 1 deletion fs/ceph/super.h
Expand Up @@ -189,7 +189,6 @@ static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap)
struct ceph_cap_flush {
u64 tid;
int caps;
bool kick;
struct rb_node g_node; // global
union {
struct rb_node i_node; // inode
Expand Down

0 comments on commit d2ca589

Please sign in to comment.