|
|
0690ef |
[PATCH] xfs_repair: fix prefetch queue waiting
|
|
|
0690ef |
|
|
|
0690ef |
This fixes a regression caused by:
|
|
|
0690ef |
|
|
|
0690ef |
97b1fcf xfs_repair: fix array overrun in do_inode_prefetch
|
|
|
0690ef |
|
|
|
0690ef |
The thread creation loop has 2 ways to exit; either via
|
|
|
0690ef |
the loop counter based on thread_count, or the break statement
|
|
|
0690ef |
if we've started enough workers to cover all AGs.
|
|
|
0690ef |
|
|
|
0690ef |
Whether or not the loop counter "i" reflects the number of
|
|
|
0690ef |
threads started depends on whether or not we exited via the
|
|
|
0690ef |
break.
|
|
|
0690ef |
|
|
|
0690ef |
The above commit prevented us from indexing off the end
|
|
|
0690ef |
of the queues[] array if we actually advanced "i" all the
|
|
|
0690ef |
way to thread_count, but in the case where we break, "i"
|
|
|
0690ef |
is one *less* than the nr of threads started, so we don't
|
|
|
0690ef |
wait for completion of all threads, and all hell breaks
|
|
|
0690ef |
loose in phase 5.
|
|
|
0690ef |
|
|
|
0690ef |
Just stop with the cleverness of re-using the loop counter -
|
|
|
0690ef |
instead, explicitly count threads that we start, and then use
|
|
|
0690ef |
that counter to wait for each worker to complete.
|
|
|
0690ef |
|
|
|
0690ef |
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
|
|
|
0690ef |
Reviewed-by: Brian Foster <bfoster@redhat.com>
|
|
|
0690ef |
---
|
|
|
0690ef |
|
|
|
0690ef |
I have one fs which demonstrates the problem, and have verified
|
|
|
0690ef |
the regression & tested the fix against that.
|
|
|
0690ef |
|
|
|
0690ef |
I'll run this over xfstests overnight, but it seems obvious
|
|
|
0690ef |
from here (OTOH the other fix seemed obvious too)
|
|
|
0690ef |
|
|
|
0690ef |
diff --git a/repair/prefetch.c b/repair/prefetch.c
|
|
|
0690ef |
index e47a48e..4c32395 100644
|
|
|
0690ef |
--- a/repair/prefetch.c
|
|
|
0690ef |
+++ b/repair/prefetch.c
|
|
|
0690ef |
@@ -944,6 +944,7 @@ do_inode_prefetch(
|
|
|
0690ef |
int i;
|
|
|
0690ef |
struct work_queue queue;
|
|
|
0690ef |
struct work_queue *queues;
|
|
|
0690ef |
+ int queues_started = 0;
|
|
|
0690ef |
|
|
|
0690ef |
/*
|
|
|
0690ef |
* If the previous phases of repair have not overflowed the buffer
|
|
|
0690ef |
@@ -987,6 +988,7 @@ do_inode_prefetch(
|
|
|
0690ef |
|
|
|
0690ef |
create_work_queue(&queues[i], mp, 1);
|
|
|
0690ef |
queue_work(&queues[i], prefetch_ag_range_work, 0, wargs);
|
|
|
0690ef |
+ queues_started++;
|
|
|
0690ef |
|
|
|
0690ef |
if (wargs->end_ag >= mp->m_sb.sb_agcount)
|
|
|
0690ef |
break;
|
|
|
0690ef |
@@ -995,7 +997,7 @@ do_inode_prefetch(
|
|
|
0690ef |
/*
|
|
|
0690ef |
* wait for workers to complete
|
|
|
0690ef |
*/
|
|
|
0690ef |
- while (i--)
|
|
|
0690ef |
+ for (i = 0; i < queues_started; i++)
|
|
|
0690ef |
destroy_work_queue(&queues[i]);
|
|
|
0690ef |
free(queues);
|
|
|
0690ef |
}
|
|
|
0690ef |
|
|
|
0690ef |
_______________________________________________
|
|
|
0690ef |
xfs mailing list
|
|
|
0690ef |
xfs@oss.sgi.com
|
|
|
0690ef |
http://oss.sgi.com/mailman/listinfo/xfs
|
|
|
0690ef |
|
|
|
0690ef |
|