From 5fc83f470d8ada25927701512cf94a53dab6c4c8 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 29 Jul 2014 17:23:17 -0400 Subject: xprtrdma: Fix panic in rpcrdma_register_frmr_external() seg1->mr_nsegs is not yet initialized when it is used to unmap segments during an error exit. Use the same unmapping logic for all error exits. "if (frmr_wr.wr.fast_reg.length < len) {" used to be a BUG_ON check. The broken code will never be executed under normal operation. Fixes: c977dea (xprtrdma: Remove BUG_ON() call sites) Signed-off-by: Chuck Lever Tested-by: Steve Wise Tested-by: Shirley Ma Tested-by: Devesh Sharma Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/verbs.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'net/sunrpc/xprtrdma') diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 176dafc6e6d7..f337bdaa9939 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -1548,9 +1548,8 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg, frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT; frmr_wr.wr.fast_reg.length = page_no << PAGE_SHIFT; if (frmr_wr.wr.fast_reg.length < len) { - while (seg1->mr_nsegs--) - rpcrdma_unmap_one(ia, seg++); - return -EIO; + rc = -EIO; + goto out_err; } /* Bump the key */ @@ -1568,8 +1567,7 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg, if (rc) { dprintk("RPC: %s: failed ib_post_send for register," " status %i\n", __func__, rc); - while (i--) - rpcrdma_unmap_one(ia, --seg); + goto out_err; } else { seg1->mr_rkey = seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey; seg1->mr_base = seg1->mr_dma + pageoff; @@ -1577,6 +1575,10 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg, seg1->mr_len = len; } *nsegs = i; + return 0; +out_err: + while (i--) + rpcrdma_unmap_one(ia, --seg); return rc; } -- cgit