{
        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);
 }
 
 
        s->s_renew_seq = 0;
        INIT_LIST_HEAD(&s->s_caps);
        s->s_nr_caps = 0;
+       s->s_trim_caps = 0;
        atomic_set(&s->s_ref, 1);
        INIT_LIST_HEAD(&s->s_waiting);
        INIT_LIST_HEAD(&s->s_unsafe);
        s->s_num_cap_releases = 0;
+       s->s_iterating_caps = false;
        INIT_LIST_HEAD(&s->s_cap_releases);
        INIT_LIST_HEAD(&s->s_cap_releases_done);
        INIT_LIST_HEAD(&s->s_cap_flushing);
 
        dout("iterate_session_caps %p mds%d\n", session, session->s_mds);
        spin_lock(&session->s_cap_lock);
+       session->s_iterating_caps = true;
        list_for_each_entry_safe(cap, ncap, &session->s_caps, session_caps) {
                inode = igrab(&cap->ci->vfs_inode);
                if (!inode)
                spin_unlock(&session->s_cap_lock);
                ret = cb(inode, cap, arg);
                iput(inode);
-               if (ret < 0)
-                       return ret;
                spin_lock(&session->s_cap_lock);
+               if (ret < 0)
+                       goto out;
        }
+       ret = 0;
+out:
+       session->s_iterating_caps = false;
        spin_unlock(&session->s_cap_lock);
-
-       return 0;
+       return ret;
 }
 
 static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
                dout("trim_caps mds%d done: %d / %d, trimmed %d\n",
                     session->s_mds, session->s_nr_caps, max_caps,
                        trim_caps - session->s_trim_caps);
+               session->s_trim_caps = 0;
        }
        return 0;
 }