aboutsummaryrefslogtreecommitdiff
path: root/fs/ceph/caps.c
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2009-12-21 20:40:34 -0800
committerSage Weil <sage@newdream.net>2009-12-23 08:17:14 -0800
commit5dacf09121ffb2e5fc7d15b78cae0b77042a1935 (patch)
tree8a4ec2fde459f93936a91644d024673d37347408 /fs/ceph/caps.c
parent7067f797b8409f1e10ec95ac2c1e17a200173d13 (diff)
ceph: do not touch_caps while iterating over caps list
Avoid confusing iterate_session_caps(), flag the session while we are iterating so that __touch_cap does not rearrange items on the list. All other modifiers of session->s_caps do so under the protection of s_mutex. Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r--fs/ceph/caps.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index dfb509f5354..93c1afe3f0b 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -697,10 +697,15 @@ static void __touch_cap(struct ceph_cap *cap)
{
struct ceph_mds_session *s = cap->session;
- dout("__touch_cap %p cap %p mds%d\n", &cap->ci->vfs_inode, cap,
- s->s_mds);
spin_lock(&s->s_cap_lock);
- list_move_tail(&cap->session_caps, &s->s_caps);
+ if (!s->s_iterating_caps) {
+ dout("__touch_cap %p cap %p mds%d\n", &cap->ci->vfs_inode, cap,
+ s->s_mds);
+ list_move_tail(&cap->session_caps, &s->s_caps);
+ } else {
+ dout("__touch_cap %p cap %p mds%d NOP, iterating over caps\n",
+ &cap->ci->vfs_inode, cap, s->s_mds);
+ }
spin_unlock(&s->s_cap_lock);
}