diff options
author | Yan, Zheng <zyan@redhat.com> | 2017-01-29 09:15:47 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2017-02-20 06:16:07 -0500 |
commit | c1944fedd8c492ce1c1a99ca9064dcc7bafa80e9 (patch) | |
tree | 391d043097c793dacc36aae7c9c9e354d80553bb /fs/ceph | |
parent | 00f06cba53f53f3f7be8ac4f9ba2c2f6a94bca6f (diff) |
ceph: avoid calling ceph_renew_caps() infinitely
__ceph_caps_mds_wanted() ignores caps from stale session. So the
return value of __ceph_caps_mds_wanted() can keep the same across
ceph_renew_caps(). This causes try_get_cap_refs() to keep calling
ceph_renew_caps(). The fix is ignore the session valid check for
the try_get_cap_refs() case. If session is stale, just let the
caps requester sleep.
Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/caps.c | 6 | ||||
-rw-r--r-- | fs/ceph/file.c | 2 | ||||
-rw-r--r-- | fs/ceph/super.h | 2 |
3 files changed, 5 insertions, 5 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index ed8c7addce91..3c2dfd72e5b2 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -867,7 +867,7 @@ int __ceph_caps_file_wanted(struct ceph_inode_info *ci) | |||
867 | /* | 867 | /* |
868 | * Return caps we have registered with the MDS(s) as 'wanted'. | 868 | * Return caps we have registered with the MDS(s) as 'wanted'. |
869 | */ | 869 | */ |
870 | int __ceph_caps_mds_wanted(struct ceph_inode_info *ci) | 870 | int __ceph_caps_mds_wanted(struct ceph_inode_info *ci, bool check) |
871 | { | 871 | { |
872 | struct ceph_cap *cap; | 872 | struct ceph_cap *cap; |
873 | struct rb_node *p; | 873 | struct rb_node *p; |
@@ -875,7 +875,7 @@ int __ceph_caps_mds_wanted(struct ceph_inode_info *ci) | |||
875 | 875 | ||
876 | for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { | 876 | for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { |
877 | cap = rb_entry(p, struct ceph_cap, ci_node); | 877 | cap = rb_entry(p, struct ceph_cap, ci_node); |
878 | if (!__cap_is_valid(cap)) | 878 | if (check && !__cap_is_valid(cap)) |
879 | continue; | 879 | continue; |
880 | if (cap == ci->i_auth_cap) | 880 | if (cap == ci->i_auth_cap) |
881 | mds_wanted |= cap->mds_wanted; | 881 | mds_wanted |= cap->mds_wanted; |
@@ -2491,7 +2491,7 @@ again: | |||
2491 | ret = 1; | 2491 | ret = 1; |
2492 | goto out_unlock; | 2492 | goto out_unlock; |
2493 | } | 2493 | } |
2494 | mds_wanted = __ceph_caps_mds_wanted(ci); | 2494 | mds_wanted = __ceph_caps_mds_wanted(ci, false); |
2495 | if (need & ~(mds_wanted & need)) { | 2495 | if (need & ~(mds_wanted & need)) { |
2496 | dout("get_cap_refs %p caps were dropped" | 2496 | dout("get_cap_refs %p caps were dropped" |
2497 | " (session killed?)\n", inode); | 2497 | " (session killed?)\n", inode); |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 045d30d26624..beb24f8bb917 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -283,7 +283,7 @@ int ceph_open(struct inode *inode, struct file *file) | |||
283 | spin_lock(&ci->i_ceph_lock); | 283 | spin_lock(&ci->i_ceph_lock); |
284 | if (__ceph_is_any_real_caps(ci) && | 284 | if (__ceph_is_any_real_caps(ci) && |
285 | (((fmode & CEPH_FILE_MODE_WR) == 0) || ci->i_auth_cap)) { | 285 | (((fmode & CEPH_FILE_MODE_WR) == 0) || ci->i_auth_cap)) { |
286 | int mds_wanted = __ceph_caps_mds_wanted(ci); | 286 | int mds_wanted = __ceph_caps_mds_wanted(ci, true); |
287 | int issued = __ceph_caps_issued(ci, NULL); | 287 | int issued = __ceph_caps_issued(ci, NULL); |
288 | 288 | ||
289 | dout("open %p fmode %d want %s issued %s using existing\n", | 289 | dout("open %p fmode %d want %s issued %s using existing\n", |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index f3f9215abf8e..6477264bfc7e 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -602,7 +602,7 @@ static inline int __ceph_caps_wanted(struct ceph_inode_info *ci) | |||
602 | } | 602 | } |
603 | 603 | ||
604 | /* what the mds thinks we want */ | 604 | /* what the mds thinks we want */ |
605 | extern int __ceph_caps_mds_wanted(struct ceph_inode_info *ci); | 605 | extern int __ceph_caps_mds_wanted(struct ceph_inode_info *ci, bool check); |
606 | 606 | ||
607 | extern void ceph_caps_init(struct ceph_mds_client *mdsc); | 607 | extern void ceph_caps_init(struct ceph_mds_client *mdsc); |
608 | extern void ceph_caps_finalize(struct ceph_mds_client *mdsc); | 608 | extern void ceph_caps_finalize(struct ceph_mds_client *mdsc); |