--- a/sys/vfs/hammer2/hammer2_ondisk.c +++ b/sys/vfs/hammer2/hammer2_ondisk.c @@ -46,6 +46,22 @@ #include #include "hammer2.h" +#include + +SYSCTL_DECL(_vfs_hammer2); + +/* + * DF-2663 fault injection: make the mount-time DIOCGPART appear to fail + * (simulates real failure modes: async slice-probe race after + * disk_setdiskinfo(), d_slice == NULL, raw-device fallback ENOTTY), so the + * volu_size containment check below is skipped. + * + * ENVIRONMENT SIMULATION ONLY -- never part of a fix. + */ +int hammer2_df2663_fail_diocgpart = 0; +SYSCTL_INT(_vfs_hammer2, OID_AUTO, df2663_fail_diocgpart, CTLFLAG_RW, + &hammer2_df2663_fail_diocgpart, 0, + "FAULT-INJECT fail DIOCGPART for the 320MB test volume"); #define hprintf(X, ...) kprintf("hammer2_ondisk: " X, ## __VA_ARGS__) @@ -280,14 +296,24 @@ return EINVAL; } /* check volume size vs block device size */ - if (VOP_IOCTL(vol->dev->devvp, DIOCGPART, (void*)&part, 0, - curthread->td_ucred , NULL) == 0) { + { + int dioerr = VOP_IOCTL(vol->dev->devvp, DIOCGPART, + (void*)&part, 0, + curthread->td_ucred, NULL); + if (hammer2_df2663_fail_diocgpart && + vol->size == 0x14000000ULL) { + /* DF-2663: only the 320MB forged test + * volume, never the guest root fs */ + dioerr = ENXIO; + } + if (dioerr == 0) { if (vol->size > part.media_size) { hprintf("%s's size 0x%016jx exceeds device size " "0x%016jx\n", path, (intmax_t)vol->size, part.media_size); return EINVAL; } + } } if (vol->size == 0) { hprintf("%s has size of 0\n", path);