diff mbox

[03/10] xfs_scrub: destroy workqueues when erroring out

Message ID 153006768447.20121.17161456551475897498.stgit@magnolia (mailing list archive)
State Accepted
Headers show

Commit Message

Darrick J. Wong June 27, 2018, 2:48 a.m. UTC
From: Darrick J. Wong <darrick.wong@oracle.com>

Fix a couple of code paths that forgot to tear down a workqueue when
erroring out, because if we don't the wq threads keep running even after
we've freed the wq memory.

Found by fuzzing core.nlinkv2=0 in xfs/377, but only because the fs will
shut down when it hits an error destroying the incore (corrupt) inode
after the scrub.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 scrub/phase2.c |    2 +-
 scrub/vfs.c    |    4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)



--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Eric Sandeen July 26, 2018, 12:29 a.m. UTC | #1
On 6/26/18 7:48 PM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Fix a couple of code paths that forgot to tear down a workqueue when
> erroring out, because if we don't the wq threads keep running even after
> we've freed the wq memory.
> 
> Found by fuzzing core.nlinkv2=0 in xfs/377, but only because the fs will
> shut down when it hits an error destroying the incore (corrupt) inode
> after the scrub.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Reviewed-by: Eric Sandeen <sandeen@redhat.com>

> ---
>  scrub/phase2.c |    2 +-
>  scrub/vfs.c    |    4 +++-
>  2 files changed, 4 insertions(+), 2 deletions(-)
> 
> 
> diff --git a/scrub/phase2.c b/scrub/phase2.c
> index ad736bf5..7078e38d 100644
> --- a/scrub/phase2.c
> +++ b/scrub/phase2.c
> @@ -102,7 +102,7 @@ xfs_scan_metadata(
>  	 */
>  	moveon = xfs_scrub_primary_super(ctx);
>  	if (!moveon)
> -		return moveon;
> +		goto out;
>  
>  	for (agno = 0; moveon && agno < ctx->geo.agcount; agno++) {
>  		ret = workqueue_add(&wq, xfs_scan_ag_metadata, agno, &moveon);
> diff --git a/scrub/vfs.c b/scrub/vfs.c
> index 77df2874..12a6a860 100644
> --- a/scrub/vfs.c
> +++ b/scrub/vfs.c
> @@ -210,7 +210,7 @@ scan_fs_tree(
>  	if (ret) {
>  		str_info(ctx, ctx->mntpoint,
>  _("Could not queue directory scan work."));
> -		goto out_free;
> +		goto out_wq;
>  	}
>  
>  	pthread_mutex_lock(&sft.lock);
> @@ -220,6 +220,8 @@ _("Could not queue directory scan work."));
>  	workqueue_destroy(&wq);
>  
>  	return sft.moveon;
> +out_wq:
> +	workqueue_destroy(&wq);
>  out_free:
>  	free(sftd->path);
>  	free(sftd);
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/scrub/phase2.c b/scrub/phase2.c
index ad736bf5..7078e38d 100644
--- a/scrub/phase2.c
+++ b/scrub/phase2.c
@@ -102,7 +102,7 @@  xfs_scan_metadata(
 	 */
 	moveon = xfs_scrub_primary_super(ctx);
 	if (!moveon)
-		return moveon;
+		goto out;
 
 	for (agno = 0; moveon && agno < ctx->geo.agcount; agno++) {
 		ret = workqueue_add(&wq, xfs_scan_ag_metadata, agno, &moveon);
diff --git a/scrub/vfs.c b/scrub/vfs.c
index 77df2874..12a6a860 100644
--- a/scrub/vfs.c
+++ b/scrub/vfs.c
@@ -210,7 +210,7 @@  scan_fs_tree(
 	if (ret) {
 		str_info(ctx, ctx->mntpoint,
 _("Could not queue directory scan work."));
-		goto out_free;
+		goto out_wq;
 	}
 
 	pthread_mutex_lock(&sft.lock);
@@ -220,6 +220,8 @@  _("Could not queue directory scan work."));
 	workqueue_destroy(&wq);
 
 	return sft.moveon;
+out_wq:
+	workqueue_destroy(&wq);
 out_free:
 	free(sftd->path);
 	free(sftd);