Commit 0ceed5db321ac0f9782e77dda476ebe28a8e2199
1 parent
54ad023ba8
Exists in
master
and in
7 other branches
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>
Showing 1 changed file with 5 additions and 2 deletions Side-by-side Diff
fs/ceph/osd_client.c
... | ... | @@ -779,16 +779,18 @@ |
779 | 779 | struct ceph_osd_request *req; |
780 | 780 | u64 tid; |
781 | 781 | int numops, object_len, flags; |
782 | + s32 result; | |
782 | 783 | |
783 | 784 | tid = le64_to_cpu(msg->hdr.tid); |
784 | 785 | if (msg->front.iov_len < sizeof(*rhead)) |
785 | 786 | goto bad; |
786 | 787 | numops = le32_to_cpu(rhead->num_ops); |
787 | 788 | object_len = le32_to_cpu(rhead->object_len); |
789 | + result = le32_to_cpu(rhead->result); | |
788 | 790 | if (msg->front.iov_len != sizeof(*rhead) + object_len + |
789 | 791 | numops * sizeof(struct ceph_osd_op)) |
790 | 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 | 795 | /* lookup */ |
794 | 796 | mutex_lock(&osdc->request_mutex); |
... | ... | @@ -834,7 +836,8 @@ |
834 | 836 | dout("handle_reply tid %llu flags %d\n", tid, flags); |
835 | 837 | |
836 | 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 | 841 | ((flags & CEPH_OSD_FLAG_WRITE) == 0)) |
839 | 842 | __unregister_request(osdc, req); |
840 | 843 |