DragonFlyBSD Kernel Audit
DF-0823 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/hammer2/hammer2_admin.c b/sys/vfs/hammer2/hammer2_admin.c
index 0000000..1111111 100644
--- a/sys/vfs/hammer2/hammer2_admin.c
+++ b/sys/vfs/hammer2/hammer2_admin.c
@@ -431,9 +431,18 @@
 	lockmgr(&pmp->lock, LK_EXCLUSIVE);
 	pmp->has_xop_threads = 1;
 
-	pmp->xop_groups = kmalloc(hammer2_xop_nthreads *
-				  sizeof(hammer2_xop_group_t),
-				  M_HAMMER2, M_WAITOK | M_ZERO);
+	/*
+	 * Only allocate xop_groups once.  This function may be called
+	 * multiple times (from hammer2_mount_helper and again from
+	 * hammer2_pfsalloc when a new chain joins the cluster).
+	 * Without this guard the second call would leak the first
+	 * allocation and orphan its running threads.
+	 */
+	if (pmp->xop_groups == NULL) {
+		pmp->xop_groups = kmalloc(hammer2_xop_nthreads *
+					  sizeof(hammer2_xop_group_t),
+					  M_HAMMER2, M_WAITOK | M_ZERO);
+	}
 	for (i = 0; i < pmp->iroot->cluster.nchains; ++i) {
 		for (j = 0; j < hammer2_xop_nthreads; ++j) {
 			if (pmp->xop_groups[j].thrs[i].td)
@@ -458,7 +467,7 @@
 		return;
 	}
 
-	for (i = 0; i < pmp->pfs_nmasters; ++i) {
+	for (i = 0; i < pmp->iroot->cluster.nchains; ++i) {
 		for (j = 0; j < hammer2_xop_nthreads; ++j) {
 			if (pmp->xop_groups[j].thrs[i].td)
 				hammer2_thr_delete(&pmp->xop_groups[j].thrs[i]);