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>
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index dfb509f..93c1afe 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -697,10 +697,15 @@
{
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);
}