diff options
author | NeilBrown <neilb@suse.com> | 2017-12-14 15:43:43 +1100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-12-19 11:51:21 +0100 |
commit | a93639090a2743c8e205c1ac25439702702b4ce4 (patch) | |
tree | 49fd142fbfba7829ce0b0dbcee6b75942de3a575 /drivers | |
parent | 1291a0d5049dbc06baaaf66a9ff3f53db493b19b (diff) | |
download | linux-stable-a93639090a2743c8e205c1ac25439702702b4ce4.tar.gz linux-stable-a93639090a2743c8e205c1ac25439702702b4ce4.tar.bz2 linux-stable-a93639090a2743c8e205c1ac25439702702b4ce4.zip |
staging: lustre: lnet: Fix recent breakage from list_for_each conversion
Commit 8e55b6fd0660 ("staging: lustre: lnet: replace list_for_each
with list_for_each_entry") was intended to be an idempotent change,
but actually broke the behavior of ksocknal_add_peer() causing mounts to fail.
The fact that it caused an existing "route2 = NULL;" to become
redundant could have been a clue. The fact that the loop body
set the new loop variable to NULL might also have been a clue
The original code relied on "route2" being NULL if nothing was found.
The new code would always set route2 to a non-NULL value if the list
was empty, and would likely crash if the list was not empty.
Restore correct functionality by using code-flow rather the value of
"route2" to determine whether to use on old route, or to add a new one.
Fixes: 8e55b6fd0660 ("staging: lustre: lnet: replace list_for_each with list_for_each_entry")
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c | 23 |
1 files changed, 10 insertions, 13 deletions
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 986c2a40d978..8267119ccc8e 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -487,21 +487,18 @@ ksocknal_add_peer(struct lnet_ni *ni, struct lnet_process_id id, __u32 ipaddr, ksocknal_nid2peerlist(id.nid)); } - route2 = NULL; list_for_each_entry(route2, &peer->ksnp_routes, ksnr_list) { - if (route2->ksnr_ipaddr == ipaddr) - break; - - route2 = NULL; - } - if (!route2) { - ksocknal_add_route_locked(peer, route); - route->ksnr_share_count++; - } else { - ksocknal_route_decref(route); - route2->ksnr_share_count++; + if (route2->ksnr_ipaddr == ipaddr) { + /* Route already exists, use the old one */ + ksocknal_route_decref(route); + route2->ksnr_share_count++; + goto out; + } } - + /* Route doesn't already exist, add the new one */ + ksocknal_add_route_locked(peer, route); + route->ksnr_share_count++; +out: write_unlock_bh(&ksocknal_data.ksnd_global_lock); return 0; |