From 8d4ef45e078010d98f5c4f786e551d487f3e6e18 Mon Sep 17 00:00:00 2001 From: Noopur Maheshwari Date: Thu, 28 Jan 2016 22:58:49 +0530 Subject: [PATCH] LU-7524 fld: fld_clientlookup retries next target fld_client_lookup() retries for another target, if the remote target is deactive. This was introduced in http://review.whamcloud.com/#/c/14313/ For getting the next export target from the list, we use: target = list_entry(target->ft_chain.next, struct lu_fld_target,ft_chain); Now for tests that deactivate the last target, &(target->ft_chain) is the last entry in the list, and the next of the last entry(target->ft_chain.next) is the list_head. Using the macro list_entry maps the list_head pointer back into a pointer to the structure that contains the list_head. Thus, it turns the head of the list into its containing structure(lu_fld_target). Hence, since the head of the list does not have any data associated with it, the containing structure(i.e.target) formed from the head of the list also does not have any data. Therefore, an export target with no obd device data is generated. This corrupted export target(generated from the head of the list) causes the assertion. The fix is: While fld_client_lookup retries for another target, if the next entry in the export target list is the head of the list(&fld->lcf_targets), move to the next entry after the head(target->ft_chain.next->next) and retrieve the target. Else retrieve the next target entry(target->ft_chain.next). Seagate-bug-id: MRP-3200 Signed-off-by: Noopur Maheshwari Change-Id: Ia353437a315de0f1bb44d8822e836ac969b0567f Reviewed-on: http://review.whamcloud.com/17683 Tested-by: Jenkins Reviewed-by: Fan Yong Tested-by: Maloo Reviewed-by: Alex Zhuravlev Reviewed-by: Lai Siyao Reviewed-by: Oleg Drokin --- lustre/fld/fld_request.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lustre/fld/fld_request.c b/lustre/fld/fld_request.c index 21ce719..9354922 100644 --- a/lustre/fld/fld_request.c +++ b/lustre/fld/fld_request.c @@ -499,8 +499,13 @@ again: * then try next target in the list, until trying all targets * or fld lookup succeeds */ spin_lock(&fld->lcf_lock); - if (target->ft_chain.next == fld->lcf_targets.prev) - target = list_entry(fld->lcf_targets.next, + + /* If the next entry in the list is the head of the list, + * move to the next entry after the head and retrieve + * the target. Else retreive the next target entry. */ + + if (target->ft_chain.next == &fld->lcf_targets) + target = list_entry(target->ft_chain.next->next, struct lu_fld_target, ft_chain); else target = list_entry(target->ft_chain.next, -- 1.8.3.1