ceph: make sure flushing inode in proper session's cap_flushing list
authorYan, Zheng <zyan@redhat.com>
Tue, 24 Jan 2017 02:02:32 +0000 (10:02 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 20 Feb 2017 11:16:07 +0000 (12:16 +0100)
when flushing inode's auth cap changes, we need to move it into the
new auth cap session's cap_flushing list

Signed-off-by: Yan, Zheng <zyan@redhat.com>
fs/ceph/caps.c

index d941c48e8bff096abfa2e26d181e51539faf0f97..ed8c7addce91962dd5dc4d1289eb1adf2a6f384f 100644 (file)
@@ -3410,6 +3410,7 @@ retry:
                        tcap->implemented |= issued;
                        if (cap == ci->i_auth_cap)
                                ci->i_auth_cap = tcap;
+
                        if (!list_empty(&ci->i_cap_flush_list) &&
                            ci->i_auth_cap == tcap) {
                                spin_lock(&mdsc->cap_dirty_lock);
@@ -3423,9 +3424,18 @@ retry:
        } else if (tsession) {
                /* add placeholder for the export tagert */
                int flag = (cap == ci->i_auth_cap) ? CEPH_CAP_FLAG_AUTH : 0;
+               tcap = new_cap;
                ceph_add_cap(inode, tsession, t_cap_id, -1, issued, 0,
                             t_seq - 1, t_mseq, (u64)-1, flag, &new_cap);
 
+               if (!list_empty(&ci->i_cap_flush_list) &&
+                   ci->i_auth_cap == tcap) {
+                       spin_lock(&mdsc->cap_dirty_lock);
+                       list_move_tail(&ci->i_flushing_item,
+                                      &tcap->session->s_cap_flushing);
+                       spin_unlock(&mdsc->cap_dirty_lock);
+               }
+
                __ceph_remove_cap(cap, false);
                goto out_unlock;
        }