diff options
author | Sage Weil <sage@newdream.net> | 2010-05-11 12:53:18 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-05-11 12:53:18 -0400 |
commit | 0ceed5db321ac0f9782e77dda476ebe28a8e2199 (patch) | |
tree | 356f6a3f2dc26ba04589e9abd603139c62094730 | |
parent | 54ad023ba8108d0163acc931ed4b5e4a8a3a7327 (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.c | 7 |
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 | ||