Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging/lustre/osc: Revert erroneous list_for_each_entry_safe use

I have been having a lot of unexplainable crashes in osc_lru_shrink
lately that I could not see a good explanation for and then I found
this patch that slip under the radar somehow that incorrectly
converted while loop for lru list iteration into
list_for_each_entry_safe totally ignoring that in the body of
the loop we drop spinlocks guarding this list and move list entries
around.
Not sure why it was not showing up right away, perhaps some of the
more recent LRU changes committed caused some extra pressure on this
code that finally highlighted the breakage.

Reverts: 8adddc36b1fc ("staging: lustre: osc: Use list_for_each_entry_safe")
CC: Bhaktipriya Shridhar <bhaktipriya96@gmail.com>
Signed-off-by: Oleg Drokin <green@linuxhacker.ru>
Cc: stable <stable@vger.kernel.org> # 4.6+
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Oleg Drokin and committed by
Greg Kroah-Hartman
cd15dd6e 0af72df2

+3 -2
+3 -2
drivers/staging/lustre/lustre/osc/osc_page.c
··· 537 537 struct cl_object *clobj = NULL; 538 538 struct cl_page **pvec; 539 539 struct osc_page *opg; 540 - struct osc_page *temp; 541 540 int maxscan = 0; 542 541 long count = 0; 543 542 int index = 0; ··· 567 568 if (force) 568 569 cli->cl_lru_reclaim++; 569 570 maxscan = min(target << 1, atomic_long_read(&cli->cl_lru_in_list)); 570 - list_for_each_entry_safe(opg, temp, &cli->cl_lru_list, ops_lru) { 571 + while (!list_empty(&cli->cl_lru_list)) { 571 572 struct cl_page *page; 572 573 bool will_free = false; 573 574 ··· 577 578 if (--maxscan < 0) 578 579 break; 579 580 581 + opg = list_entry(cli->cl_lru_list.next, struct osc_page, 582 + ops_lru); 580 583 page = opg->ops_cl.cpl_page; 581 584 if (lru_page_busy(cli, page)) { 582 585 list_move_tail(&opg->ops_lru, &cli->cl_lru_list);