ceph: reuse request message when replaying against recovering mds

Replayed rename operations (after an mds failure/recovery) were broken
because the request paths were regenerated from the dentry names, which
get mangled when d_move() is called.

Instead, resend the previous request message when replaying completed
operations. Just make sure the REPLAY flag is set and the target ino is
filled in.

This fixes problems with workloads doing renames when the MDS restarts,
where the rename operation appears to succeed, but on mds restart then
fails (leading to client confusion, app breakage, etc.).

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

Sage Weil 01a92f17 f91d3471

+22 -5
+22 -5
fs/ceph/mds_client.c
··· 1580 1580 dout("prepare_send_request %p tid %lld %s (attempt %d)\n", req, 1581 1581 req->r_tid, ceph_mds_op_name(req->r_op), req->r_attempts); 1582 1582 1583 + if (req->r_got_unsafe) { 1584 + /* 1585 + * Replay. Do not regenerate message (and rebuild 1586 + * paths, etc.); just use the original message. 1587 + * Rebuilding paths will break for renames because 1588 + * d_move mangles the src name. 1589 + */ 1590 + msg = req->r_request; 1591 + rhead = msg->front.iov_base; 1592 + 1593 + flags = le32_to_cpu(rhead->flags); 1594 + flags |= CEPH_MDS_FLAG_REPLAY; 1595 + rhead->flags = cpu_to_le32(flags); 1596 + 1597 + if (req->r_target_inode) 1598 + rhead->ino = cpu_to_le64(ceph_ino(req->r_target_inode)); 1599 + 1600 + rhead->num_retry = req->r_attempts - 1; 1601 + return 0; 1602 + } 1603 + 1583 1604 if (req->r_request) { 1584 1605 ceph_msg_put(req->r_request); 1585 1606 req->r_request = NULL; ··· 1622 1601 rhead->flags = cpu_to_le32(flags); 1623 1602 rhead->num_fwd = req->r_num_fwd; 1624 1603 rhead->num_retry = req->r_attempts - 1; 1604 + rhead->ino = 0; 1625 1605 1626 1606 dout(" r_locked_dir = %p\n", req->r_locked_dir); 1627 - 1628 - if (req->r_target_inode && req->r_got_unsafe) 1629 - rhead->ino = cpu_to_le64(ceph_ino(req->r_target_inode)); 1630 - else 1631 - rhead->ino = 0; 1632 1607 return 0; 1633 1608 } 1634 1609