Module Name: src
Committed By: andvar
Date: Sun Mar 16 12:27:50 UTC 2025
Modified Files:
src/sys/dev/ata: ata_raid_subr.c ld_ataraid.c
Log Message:
ataraid(4), ld(4): ensure RAID disk status is set before resolving vnode.
Given a RAID array disk is missing (due to removal, failure, or a code bug),
its configuration is skipped. This causes ld(4) attachment at ataraid(4) to
fail because adi->adi_dev is NULL.
The fix will treat disks without known status (ADI_S_ONLINE, ADI_S_SPARE,
ADI_S_ASSIGNED) as if ata_raid_disk_vnode_find() returned NULL, more gracefully
solving above situation and avoiding the crash.
Additionally, replace vnode block device opening logic with vn_bdev_open()
(vn_subr(9)). This function provides identical functionality while also
incrementing vp->v_writecount, preventing a 'vp->v_writecount > 0` assertion
failure on vn_close().
More details are available in the tech-kern mailing list thread:
the https://mail-index.netbsd.org/tech-kern/2025/03/10/msg030179.html thread
and PR thread.
Should fix PR kern/43986
Also observed in PR kern/59130 (due to a different bug).
pullups are needed to netbsd-9, netbsd-10.
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/ata/ata_raid_subr.c
cvs rdiff -u -r1.50 -r1.51 src/sys/dev/ata/ld_ataraid.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/ata/ata_raid_subr.c
diff -u src/sys/dev/ata/ata_raid_subr.c:1.4 src/sys/dev/ata/ata_raid_subr.c:1.5
--- src/sys/dev/ata/ata_raid_subr.c:1.4 Sat Mar 19 13:51:01 2022
+++ src/sys/dev/ata/ata_raid_subr.c Sun Mar 16 12:27:50 2025
@@ -1,4 +1,4 @@
-/* $NetBSD: ata_raid_subr.c,v 1.4 2022/03/19 13:51:01 hannken Exp $ */
+/* $NetBSD: ata_raid_subr.c,v 1.5 2025/03/16 12:27:50 andvar Exp $ */
/*-
* Copyright (c) 2008 Juan Romero Pardines.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_raid_subr.c,v 1.4 2022/03/19 13:51:01 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_raid_subr.c,v 1.5 2025/03/16 12:27:50 andvar Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -77,19 +77,11 @@ ata_raid_disk_vnode_find(struct ataraid_
bmajor = devsw_name2blk(device_xname(adi->adi_dev), NULL, 0);
dev = MAKEDISKDEV(bmajor, device_unit(adi->adi_dev), RAW_PART);
- error = bdevvp(dev, &vp);
+ error = vn_bdev_open(dev, &vp, curlwp);
if (error) {
kmem_free(adv, sizeof(struct ataraid_disk_vnode));
return NULL;
}
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- error = VOP_OPEN(vp, FREAD|FWRITE, NOCRED);
- if (error) {
- vput(vp);
- kmem_free(adv, sizeof(struct ataraid_disk_vnode));
- return NULL;
- }
- VOP_UNLOCK(vp);
adv->adv_adi = adi;
adv->adv_vnode = vp;
Index: src/sys/dev/ata/ld_ataraid.c
diff -u src/sys/dev/ata/ld_ataraid.c:1.50 src/sys/dev/ata/ld_ataraid.c:1.51
--- src/sys/dev/ata/ld_ataraid.c:1.50 Fri Jan 17 19:31:31 2020
+++ src/sys/dev/ata/ld_ataraid.c Sun Mar 16 12:27:50 2025
@@ -1,4 +1,4 @@
-/* $NetBSD: ld_ataraid.c,v 1.50 2020/01/17 19:31:31 ad Exp $ */
+/* $NetBSD: ld_ataraid.c,v 1.51 2025/03/16 12:27:50 andvar Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
@@ -47,7 +47,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_ataraid.c,v 1.50 2020/01/17 19:31:31 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_ataraid.c,v 1.51 2025/03/16 12:27:50 andvar Exp $");
#if defined(_KERNEL_OPT)
#include "bio.h"
@@ -226,7 +226,11 @@ ld_ataraid_attach(device_t parent, devic
*/
for (i = 0; i < aai->aai_ndisks; i++) {
adi = &aai->aai_disks[i];
- vp = ata_raid_disk_vnode_find(adi);
+ vp = NULL;
+ if (adi->adi_status &
+ (ADI_S_ONLINE | ADI_S_ASSIGNED | ADI_S_SPARE))
+ vp = ata_raid_disk_vnode_find(adi);
+
if (vp == NULL) {
/*
* XXX This is bogus. We should just mark the