ceph: do not include cap/dentry releases in replayed messages
authorSage Weil <sage@newdream.net>
Thu, 15 Jul 2010 21:58:39 +0000 (14:58 -0700)
committerSage Weil <sage@newdream.net>
Fri, 16 Jul 2010 17:30:18 +0000 (10:30 -0700)
Strip the cap and dentry releases from replayed messages.  They can
cause the shared state to get out of sync because they were generated
(with the request message) earlier, and no longer reflect the current
client state.

Signed-off-by: Sage Weil <sage@newdream.net>
fs/ceph/mds_client.c
fs/ceph/mds_client.h

index 23332bc4451521a9e0a623f7c5ce4f456ea121ff..416c08d315db52a409e85cc094588d3b5bfceed5 100644 (file)
@@ -1514,6 +1514,9 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
        ceph_encode_filepath(&p, end, ino1, path1);
        ceph_encode_filepath(&p, end, ino2, path2);
 
+       /* make note of release offset, in case we need to replay */
+       req->r_request_release_offset = p - msg->front.iov_base;
+
        /* cap releases */
        releases = 0;
        if (req->r_inode_drop)
@@ -1598,6 +1601,11 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc,
                        rhead->ino = cpu_to_le64(ceph_ino(req->r_target_inode));
 
                rhead->num_retry = req->r_attempts - 1;
+
+               /* remove cap/dentry releases from message */
+               rhead->num_releases = 0;
+               msg->hdr.front_len = cpu_to_le32(req->r_request_release_offset);
+               msg->front.iov_len = req->r_request_release_offset;
                return 0;
        }
 
index b292fa42a66d8026b49a0217ffc0b4e89f381497..952410c60d093e7ba5c39ed630c6283664d90c5a 100644 (file)
@@ -188,6 +188,7 @@ struct ceph_mds_request {
        int r_old_inode_drop, r_old_inode_unless;
 
        struct ceph_msg  *r_request;  /* original request */
+       int r_request_release_offset;
        struct ceph_msg  *r_reply;
        struct ceph_mds_reply_info_parsed r_reply_info;
        int r_err;