aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-05-11 12:53:18 -0400
committerSage Weil <sage@newdream.net>2010-05-11 12:53:18 -0400
commit0ceed5db321ac0f9782e77dda476ebe28a8e2199 (patch)
tree356f6a3f2dc26ba04589e9abd603139c62094730
parent54ad023ba8108d0163acc931ed4b5e4a8a3a7327 (diff)
ceph: unregister osd request on failure
The osd request wasn't being unregistered when the osd returned a failure code, even though the result was returned to the caller. This would cause it to eventually time out, and then crash the kernel when it tried to resend the request using a stale page vector. Signed-off-by: Sage Weil <sage@newdream.net>
-rw-r--r--fs/ceph/osd_client.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c
index c7b4dedaace6..8128082a028e 100644
--- a/fs/ceph/osd_client.c
+++ b/fs/ceph/osd_client.c
@@ -779,16 +779,18 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
779 struct ceph_osd_request *req; 779 struct ceph_osd_request *req;
780 u64 tid; 780 u64 tid;
781 int numops, object_len, flags; 781 int numops, object_len, flags;
782 s32 result;
782 783
783 tid = le64_to_cpu(msg->hdr.tid); 784 tid = le64_to_cpu(msg->hdr.tid);
784 if (msg->front.iov_len < sizeof(*rhead)) 785 if (msg->front.iov_len < sizeof(*rhead))
785 goto bad; 786 goto bad;
786 numops = le32_to_cpu(rhead->num_ops); 787 numops = le32_to_cpu(rhead->num_ops);
787 object_len = le32_to_cpu(rhead->object_len); 788 object_len = le32_to_cpu(rhead->object_len);
789 result = le32_to_cpu(rhead->result);
788 if (msg->front.iov_len != sizeof(*rhead) + object_len + 790 if (msg->front.iov_len != sizeof(*rhead) + object_len +
789 numops * sizeof(struct ceph_osd_op)) 791 numops * sizeof(struct ceph_osd_op))
790 goto bad; 792 goto bad;
791 dout("handle_reply %p tid %llu\n", msg, tid); 793 dout("handle_reply %p tid %llu result %d\n", msg, tid, (int)result);
792 794
793 /* lookup */ 795 /* lookup */
794 mutex_lock(&osdc->request_mutex); 796 mutex_lock(&osdc->request_mutex);
@@ -834,7 +836,8 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
834 dout("handle_reply tid %llu flags %d\n", tid, flags); 836 dout("handle_reply tid %llu flags %d\n", tid, flags);
835 837
836 /* either this is a read, or we got the safe response */ 838 /* either this is a read, or we got the safe response */
837 if ((flags & CEPH_OSD_FLAG_ONDISK) || 839 if (result < 0 ||
840 (flags & CEPH_OSD_FLAG_ONDISK) ||
838 ((flags & CEPH_OSD_FLAG_WRITE) == 0)) 841 ((flags & CEPH_OSD_FLAG_WRITE) == 0))
839 __unregister_request(osdc, req); 842 __unregister_request(osdc, req);
840 843