diff options
author | Sage Weil <sage@newdream.net> | 2009-11-09 15:05:48 -0500 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2009-11-09 15:06:07 -0500 |
commit | 685f9a5d14194fc35db73e5e7370740ccc14b64a (patch) | |
tree | 4c34ac2348149d91ad5e08cd105207810f0afdc9 /fs/ceph/caps.c | |
parent | fb690390e305ea51e1883b105c7d3c52d7100ba5 (diff) |
ceph: do not confuse stale and dead (unreconnected) caps
We were using the cap_gen to track both stale caps (caps that timed out
due to temporarily losing touch with the mds) and dead caps that did not
reconnect after an MDS failure. Introduce a recon_gen counter to track
reconnections to restarted MDSs and kill dead caps based on that instead.
Rename gen to cap_gen while we're at it to make it more clear which is
which.
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r-- | fs/ceph/caps.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 8b863dbec70c..775e6f6fc970 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -609,7 +609,8 @@ retry: | |||
609 | cap->seq = seq; | 609 | cap->seq = seq; |
610 | cap->issue_seq = seq; | 610 | cap->issue_seq = seq; |
611 | cap->mseq = mseq; | 611 | cap->mseq = mseq; |
612 | cap->gen = session->s_cap_gen; | 612 | cap->cap_gen = session->s_cap_gen; |
613 | cap->recon_gen = session->s_recon_gen; | ||
613 | 614 | ||
614 | if (fmode >= 0) | 615 | if (fmode >= 0) |
615 | __ceph_get_fmode(ci, fmode); | 616 | __ceph_get_fmode(ci, fmode); |
@@ -626,17 +627,25 @@ retry: | |||
626 | static int __cap_is_valid(struct ceph_cap *cap) | 627 | static int __cap_is_valid(struct ceph_cap *cap) |
627 | { | 628 | { |
628 | unsigned long ttl; | 629 | unsigned long ttl; |
629 | u32 gen; | 630 | u32 gen, recon_gen; |
630 | 631 | ||
631 | spin_lock(&cap->session->s_cap_lock); | 632 | spin_lock(&cap->session->s_cap_lock); |
632 | gen = cap->session->s_cap_gen; | 633 | gen = cap->session->s_cap_gen; |
634 | recon_gen = cap->session->s_recon_gen; | ||
633 | ttl = cap->session->s_cap_ttl; | 635 | ttl = cap->session->s_cap_ttl; |
634 | spin_unlock(&cap->session->s_cap_lock); | 636 | spin_unlock(&cap->session->s_cap_lock); |
635 | 637 | ||
636 | if (cap->gen < gen || time_after_eq(jiffies, ttl)) { | 638 | if (cap->recon_gen != recon_gen) { |
639 | dout("__cap_is_valid %p cap %p issued %s " | ||
640 | "but DEAD (recon_gen %u vs %u)\n", &cap->ci->vfs_inode, | ||
641 | cap, ceph_cap_string(cap->issued), cap->recon_gen, | ||
642 | recon_gen); | ||
643 | return 0; | ||
644 | } | ||
645 | if (cap->cap_gen < gen || time_after_eq(jiffies, ttl)) { | ||
637 | dout("__cap_is_valid %p cap %p issued %s " | 646 | dout("__cap_is_valid %p cap %p issued %s " |
638 | "but STALE (gen %u vs %u)\n", &cap->ci->vfs_inode, | 647 | "but STALE (gen %u vs %u)\n", &cap->ci->vfs_inode, |
639 | cap, ceph_cap_string(cap->issued), cap->gen, gen); | 648 | cap, ceph_cap_string(cap->issued), cap->cap_gen, gen); |
640 | return 0; | 649 | return 0; |
641 | } | 650 | } |
642 | 651 | ||
@@ -2203,7 +2212,8 @@ restart: | |||
2203 | issued = __ceph_caps_issued(ci, &implemented); | 2212 | issued = __ceph_caps_issued(ci, &implemented); |
2204 | issued |= implemented | __ceph_caps_dirty(ci); | 2213 | issued |= implemented | __ceph_caps_dirty(ci); |
2205 | 2214 | ||
2206 | cap->gen = session->s_cap_gen; | 2215 | cap->cap_gen = session->s_cap_gen; |
2216 | cap->recon_gen = session->s_recon_gen; | ||
2207 | 2217 | ||
2208 | __check_cap_issue(ci, cap, newcaps); | 2218 | __check_cap_issue(ci, cap, newcaps); |
2209 | 2219 | ||