From: Dave Chinner Date: Mon, 3 Mar 2014 01:17:46 +0000 (+1100) Subject: repair: fix prefetch queue limiting X-Git-Tag: v3.2.0-rc1~55 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=004e18d4795711f06f95d1113663da2203f89918;p=thirdparty%2Fxfsprogs-dev.git repair: fix prefetch queue limiting The length of the prefetch queue is limited by a semaphore. To avoid a ABBA deadlock, we only trywait on the semaphore so if we fail to get it we can kick the IO queues before sleeping. Unfortunately, the "need to sleep" detection is just a little wrong - it needs to lok at errno, not err for the EAGAIN value. Hence this queue throttling has not been working for a long time. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- diff --git a/repair/phase6.c b/repair/phase6.c index 7be68b3f5..63359d1c0 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -2999,8 +2999,15 @@ traverse_function( if (irec->ino_isa_dir == 0) continue; - if (pf_args) + if (pf_args) { sem_post(&pf_args->ra_count); +#ifdef XR_PF_TRACE + sem_getvalue(&pf_args->ra_count, &i); + pftrace( + "processing inode chunk %p in AG %d (sem count = %d)", + irec, agno, i); +#endif + } for (i = 0; i < XFS_INODES_PER_CHUNK; i++) { if (inode_isadir(irec, i)) diff --git a/repair/prefetch.c b/repair/prefetch.c index 984bedaaa..f4f3d71c2 100644 --- a/repair/prefetch.c +++ b/repair/prefetch.c @@ -723,7 +723,7 @@ pf_queuing_worker( irec, args->agno, i); #endif err = sem_trywait(&args->ra_count); - if (err == EAGAIN) { + if (err < 0 && errno == EAGAIN) { /* * Kick the queue once we have reached the limit; * without this the threads processing the inodes