summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiu Yawei <yawei.niu@intel.com>2017-01-28 19:05:08 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-02-03 13:01:38 +0100
commitd7cad1697541f26f2db0891d99147940c22e7f5a (patch)
tree6955b50d29d65383096f586aefaa8c149456eee2
parent9fc9a344a3d6531a91abafdf8c5309831b038ab7 (diff)
downloadop-kernel-dev-d7cad1697541f26f2db0891d99147940c22e7f5a.zip
op-kernel-dev-d7cad1697541f26f2db0891d99147940c22e7f5a.tar.gz
staging: ptlrpc: leaked rs on difficult reply
reply_out_callback() should call ptlrpc_schedule_difficult_reply() to finalize the rs if it's already not on uncommitted list, otherwise, the rs and the export held by rs could be leaked: - target_send_reply() sends a difficult reply before the transaction committed, the reply is linked to scp_rep_active; - export gets disconnected by umount or whatever reason, server_disconnect_export() is called to complete all outstanding replies, which will calls into ptlrpc_handle_rs() to dispose of the rs, so the rs is removed from the uncommitted list and LNetMDUnlink() is called to unlink the reply buffer and generate an unlink event; - reply_out_callback() is called to process above unlink event, ptlrpc_schedule_difficult_reply() is supposed to be called to dispose of the rs finally. However, it could be skipped because of following flawed code snippet: if (!rs->rs_no_ack || rs->rs_transno <= rs->rs_export->exp_obd->obd_last_committed) ptlrpc_schedule_difficult_reply(rs); The intention of above code is: if rs_no_ack is true (COS enabled), and transaction is not committed, we should rely on commit callback to release the rs. However, it overlooked the situation that rs could have been removed from the uncommitted list by disconnecting export. Signed-off-by: Niu Yawei <yawei.niu@intel.com> Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-7903 Reviewed-on: http://review.whamcloud.com/22696 Reviewed-by: Andreas Dilger <andreas.dilger@intel.com> Reviewed-by: Lai Siyao <lai.siyao@intel.com> Reviewed-by: Oleg Drokin <oleg.drokin@intel.com> Signed-off-by: James Simmons <jsimmons@infradead.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/events.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/staging/lustre/lustre/ptlrpc/events.c b/drivers/staging/lustre/lustre/ptlrpc/events.c
index ae1650d..dc0fe9d 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/events.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/events.c
@@ -420,7 +420,8 @@ void reply_out_callback(lnet_event_t *ev)
rs->rs_on_net = 0;
if (!rs->rs_no_ack ||
rs->rs_transno <=
- rs->rs_export->exp_obd->obd_last_committed)
+ rs->rs_export->exp_obd->obd_last_committed ||
+ list_empty(&rs->rs_obd_list))
ptlrpc_schedule_difficult_reply(rs);
spin_unlock(&rs->rs_lock);
OpenPOWER on IntegriCloud