Commit 0ceed5db321ac0f9782e77dda476ebe28a8e2199

Authored by Sage Weil
1 parent 54ad023ba8

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