aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2013-11-22 00:50:45 -0500
committerYan, Zheng <zheng.z.yan@intel.com>2014-01-21 00:29:32 -0500
commit9563f88c1fa01341d125e396edc654a8dbcab2d2 (patch)
tree421b041c32cd218720bc1369b0abe1ce353d4547
parentd1b87809fba3e07a261080837d1ae58d790b51a6 (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.c2
-rw-r--r--fs/ceph/inode.c8
-rw-r--r--fs/ceph/super.h2
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 1496out:
1494 if (check) 1497 if (check)
1495 ceph_check_caps(ci, 0, NULL); 1498 ceph_check_caps(ci, 0, NULL);
1496out:
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}
529extern int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask); 529extern int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask);
530 530
531extern int __ceph_caps_revoking_other(struct ceph_inode_info *ci,
532 struct ceph_cap *ocap, int mask);
531extern int ceph_caps_revoking(struct ceph_inode_info *ci, int mask); 533extern int ceph_caps_revoking(struct ceph_inode_info *ci, int mask);
532extern int __ceph_caps_used(struct ceph_inode_info *ci); 534extern int __ceph_caps_used(struct ceph_inode_info *ci);
533 535