ceph: fix flushing of caps vs cap import

If we are mid-flush and a cap is migrated to another node, we need to
resend the cap flush message to the new MDS, and do so with the original
flush_seq to avoid leaking across a sync boundary. Previously we didn't
redo the flush (we only flushed newly dirty data), which would cause a
later sync to hang forever.

Signed-off-by: Sage Weil <sage@newdream.net>

Sage Weil 088b3f5e 24be0c48

+34 -4
+34 -4
fs/ceph/caps.c
··· 1560 1560 /* NOTE: no side-effects allowed, until we take s_mutex */ 1561 1561 1562 1562 revoking = cap->implemented & ~cap->issued; 1563 - if (revoking) 1564 - dout(" mds%d revoking %s\n", cap->mds, 1565 - ceph_cap_string(revoking)); 1563 + dout(" mds%d cap %p issued %s implemented %s revoking %s\n", 1564 + cap->mds, cap, ceph_cap_string(cap->issued), 1565 + ceph_cap_string(cap->implemented), 1566 + ceph_cap_string(revoking)); 1566 1567 1567 1568 if (cap == ci->i_auth_cap && 1568 1569 (cap->issued & CEPH_CAP_FILE_WR)) { ··· 1940 1939 cap, session->s_mds); 1941 1940 spin_unlock(&inode->i_lock); 1942 1941 } 1942 + } 1943 + } 1944 + 1945 + static void kick_flushing_inode_caps(struct ceph_mds_client *mdsc, 1946 + struct ceph_mds_session *session, 1947 + struct inode *inode) 1948 + { 1949 + struct ceph_inode_info *ci = ceph_inode(inode); 1950 + struct ceph_cap *cap; 1951 + int delayed = 0; 1952 + 1953 + spin_lock(&inode->i_lock); 1954 + cap = ci->i_auth_cap; 1955 + dout("kick_flushing_inode_caps %p flushing %s flush_seq %lld\n", inode, 1956 + ceph_cap_string(ci->i_flushing_caps), ci->i_cap_flush_seq); 1957 + __ceph_flush_snaps(ci, &session, 1); 1958 + if (ci->i_flushing_caps) { 1959 + delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, 1960 + __ceph_caps_used(ci), 1961 + __ceph_caps_wanted(ci), 1962 + cap->issued | cap->implemented, 1963 + ci->i_flushing_caps, NULL); 1964 + if (delayed) { 1965 + spin_lock(&inode->i_lock); 1966 + __cap_delay_requeue(mdsc, ci); 1967 + spin_unlock(&inode->i_lock); 1968 + } 1969 + } else { 1970 + spin_unlock(&inode->i_lock); 1943 1971 } 1944 1972 } 1945 1973 ··· 2719 2689 ceph_add_cap(inode, session, cap_id, -1, 2720 2690 issued, wanted, seq, mseq, realmino, CEPH_CAP_FLAG_AUTH, 2721 2691 NULL /* no caps context */); 2722 - try_flush_caps(inode, session, NULL); 2692 + kick_flushing_inode_caps(mdsc, session, inode); 2723 2693 up_read(&mdsc->snap_rwsem); 2724 2694 2725 2695 /* make sure we re-request max_size, if necessary */