--- a/sys/vfs/tmpfs/tmpfs_subr.c +++ b/sys/vfs/tmpfs/tmpfs_subr.c @@ -104,6 +104,10 @@ KKASSERT(IFF(type == VLNK, target != NULL)); KKASSERT(IFF(type == VBLK || type == VCHR, rmajor != VNOVAL)); + /* + * DF-3071: close the check-then-act race; re-check under TMPFS_LOCK + * after the (sleeping) allocation. + */ if (tmp->tm_nodes_inuse >= tmp->tm_nodes_max) return (ENOSPC); @@ -111,6 +115,13 @@ M_WAITOK | M_ZERO | M_NULLOK); if (nnode == NULL) return (ENOSPC); + TMPFS_LOCK(tmp); + if (tmp->tm_nodes_inuse >= tmp->tm_nodes_max) { + TMPFS_UNLOCK(tmp); + kfree_obj(nnode, tmp->tm_node_zone); + return (ENOSPC); + } + TMPFS_UNLOCK(tmp); tmpfs_node_init(nnode); /* Generic initialization. */