diff options
author | Yan, Zheng <zheng.z.yan@intel.com> | 2013-11-22 00:50:45 -0500 |
---|---|---|
committer | Yan, Zheng <zheng.z.yan@intel.com> | 2014-01-21 00:29:32 -0500 |
commit | 9563f88c1fa01341d125e396edc654a8dbcab2d2 (patch) | |
tree | 421b041c32cd218720bc1369b0abe1ce353d4547 | |
parent | d1b87809fba3e07a261080837d1ae58d790b51a6 (diff) |
ceph: fix cache revoke race
handle following sequence of events:
- non-auth MDS revokes Fc cap. queue invalidate work
- auth MDS issues Fc cap through request reply. i_rdcache_gen gets
increased.
- invalidate work runs. it finds i_rdcache_revoking != i_rdcache_gen,
so it does nothing.
Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
-rw-r--r-- | fs/ceph/caps.c | 2 | ||||
-rw-r--r-- | fs/ceph/inode.c | 8 | ||||
-rw-r--r-- | fs/ceph/super.h | 2 |
3 files changed, 8 insertions, 4 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 2c39d9fe18d7..d2154d63f671 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -816,7 +816,7 @@ int __ceph_caps_revoking_other(struct ceph_inode_info *ci, | |||
816 | 816 | ||
817 | for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { | 817 | for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { |
818 | cap = rb_entry(p, struct ceph_cap, ci_node); | 818 | cap = rb_entry(p, struct ceph_cap, ci_node); |
819 | if (cap != ocap && __cap_is_valid(cap) && | 819 | if (cap != ocap && |
820 | (cap->implemented & ~cap->issued & mask)) | 820 | (cap->implemented & ~cap->issued & mask)) |
821 | return 1; | 821 | return 1; |
822 | } | 822 | } |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index a808bfb8d8d8..3db97ba15a06 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -1466,7 +1466,8 @@ static void ceph_invalidate_work(struct work_struct *work) | |||
1466 | dout("invalidate_pages %p gen %d revoking %d\n", inode, | 1466 | dout("invalidate_pages %p gen %d revoking %d\n", inode, |
1467 | ci->i_rdcache_gen, ci->i_rdcache_revoking); | 1467 | ci->i_rdcache_gen, ci->i_rdcache_revoking); |
1468 | if (ci->i_rdcache_revoking != ci->i_rdcache_gen) { | 1468 | if (ci->i_rdcache_revoking != ci->i_rdcache_gen) { |
1469 | /* nevermind! */ | 1469 | if (__ceph_caps_revoking_other(ci, NULL, CEPH_CAP_FILE_CACHE)) |
1470 | check = 1; | ||
1470 | spin_unlock(&ci->i_ceph_lock); | 1471 | spin_unlock(&ci->i_ceph_lock); |
1471 | mutex_unlock(&ci->i_truncate_mutex); | 1472 | mutex_unlock(&ci->i_truncate_mutex); |
1472 | goto out; | 1473 | goto out; |
@@ -1487,13 +1488,14 @@ static void ceph_invalidate_work(struct work_struct *work) | |||
1487 | dout("invalidate_pages %p gen %d raced, now %d revoking %d\n", | 1488 | dout("invalidate_pages %p gen %d raced, now %d revoking %d\n", |
1488 | inode, orig_gen, ci->i_rdcache_gen, | 1489 | inode, orig_gen, ci->i_rdcache_gen, |
1489 | ci->i_rdcache_revoking); | 1490 | ci->i_rdcache_revoking); |
1491 | if (__ceph_caps_revoking_other(ci, NULL, CEPH_CAP_FILE_CACHE)) | ||
1492 | check = 1; | ||
1490 | } | 1493 | } |
1491 | spin_unlock(&ci->i_ceph_lock); | 1494 | spin_unlock(&ci->i_ceph_lock); |
1492 | mutex_unlock(&ci->i_truncate_mutex); | 1495 | mutex_unlock(&ci->i_truncate_mutex); |
1493 | 1496 | out: | |
1494 | if (check) | 1497 | if (check) |
1495 | ceph_check_caps(ci, 0, NULL); | 1498 | ceph_check_caps(ci, 0, NULL); |
1496 | out: | ||
1497 | iput(inode); | 1499 | iput(inode); |
1498 | } | 1500 | } |
1499 | 1501 | ||
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 7fa78a7c8894..891cda8c72aa 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -528,6 +528,8 @@ static inline int __ceph_caps_dirty(struct ceph_inode_info *ci) | |||
528 | } | 528 | } |
529 | extern int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask); | 529 | extern int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask); |
530 | 530 | ||
531 | extern int __ceph_caps_revoking_other(struct ceph_inode_info *ci, | ||
532 | struct ceph_cap *ocap, int mask); | ||
531 | extern int ceph_caps_revoking(struct ceph_inode_info *ci, int mask); | 533 | extern int ceph_caps_revoking(struct ceph_inode_info *ci, int mask); |
532 | extern int __ceph_caps_used(struct ceph_inode_info *ci); | 534 | extern int __ceph_caps_used(struct ceph_inode_info *ci); |
533 | 535 | ||