diff options
-rw-r--r-- | regress/sys/kern/extent/extest.awk | 11 | ||||
-rw-r--r-- | regress/sys/kern/extent/extest.exp | 13 | ||||
-rw-r--r-- | regress/sys/kern/extent/tests | 26 | ||||
-rw-r--r-- | share/man/man9/extent.9 | 14 | ||||
-rw-r--r-- | sys/kern/subr_extent.c | 35 | ||||
-rw-r--r-- | sys/sys/extent.h | 3 |
6 files changed, 91 insertions, 11 deletions
diff --git a/regress/sys/kern/extent/extest.awk b/regress/sys/kern/extent/extest.awk index 5c875d44133..e803e93267d 100644 --- a/regress/sys/kern/extent/extest.awk +++ b/regress/sys/kern/extent/extest.awk @@ -1,4 +1,4 @@ -# $OpenBSD: extest.awk,v 1.1 2005/04/21 17:45:54 miod Exp $ +# $OpenBSD: extest.awk,v 1.2 2009/04/10 20:57:04 kettenis Exp $ # $NetBSD: extest.awk,v 1.6 2002/02/21 03:59:25 mrg Exp $ BEGIN { @@ -48,8 +48,13 @@ $1 == "boundary" { } $1 == "alloc_region" { - printf("error = extent_alloc_region(ex, %s, %s, 0);\n", - $2, $3) + if ($4 == "") { + flags = "0"; + } else { + flags = $4; + } + printf("error = extent_alloc_region(ex, %s, %s, %s);\n", + $2, $3, flags) printf("if (error)\n\tprintf(\"error: %%s\\n\", strerror(error));\n") } diff --git a/regress/sys/kern/extent/extest.exp b/regress/sys/kern/extent/extest.exp index c8e0a8beb98..930ba80a494 100644 --- a/regress/sys/kern/extent/extest.exp +++ b/regress/sys/kern/extent/extest.exp @@ -1,4 +1,4 @@ -# $OpenBSD: extest.exp,v 1.1 2005/04/21 17:45:54 miod Exp $ +# $OpenBSD: extest.exp,v 1.2 2009/04/10 20:57:04 kettenis Exp $ # $NetBSD: extest.exp,v 1.9 2005/03/15 18:27:23 bouyer Exp $ # real output must start in line 5 @@ -75,3 +75,14 @@ extent `test11' (0x10 - 0x20), flags = 0x2 0x14 - 0x14 0x1e - 0x1f 0x20 - 0x20 +output for test12 +error: Resource temporarily unavailable +output for test13 +extent `test13' (0x0 - 0xffffffff), flags = 0x0 + 0xfce00000 - 0xfcefffff +output for test14 +extent `test14' (0x0 - 0xffffffff), flags = 0x0 + 0xfce00000 - 0xfce010ff +output for test15 +extent `test15' (0x0 - 0xffffffff), flags = 0x0 + 0xf8000000 - 0xffffffff diff --git a/regress/sys/kern/extent/tests b/regress/sys/kern/extent/tests index 7f69a1e20fc..a5ac81d077a 100644 --- a/regress/sys/kern/extent/tests +++ b/regress/sys/kern/extent/tests @@ -1,4 +1,4 @@ -# $OpenBSD: tests,v 1.2 2005/04/22 00:38:24 miod Exp $ +# $OpenBSD: tests,v 1.3 2009/04/10 20:57:04 kettenis Exp $ # $NetBSD: tests,v 1.9 2005/03/15 18:27:23 bouyer Exp $ #fill up an extent, should coalesce into one allocation @@ -99,3 +99,27 @@ alloc_subregion 0x20 0x20 0x1 alloc_subregion 0x20 0x20 0x1 alloc_subregion 0x10 0x20 0x1 print + +# Overlapping regions should result in a failure +extent test12 0x00000000 0xffffffff +alloc_region 0xfce00000 0x100 +alloc_region 0xfce00000 0x100000 + +# But not if we specify EX_CONFLICTOK +extent test13 0x00000000 0xffffffff +alloc_region 0xfce00000 0x100 +alloc_region 0xfce00000 0x100000 EX_CONFLICTOK +print + +# Check partial overlap +extent test14 0x00000000 0xffffffff +alloc_region 0xfce00000 0x1000 +alloc_region 0xfce00100 0x1000 EX_CONFLICTOK +print + +# Check multiple overlaps +extent test15 0x00000000 0xffffffff +alloc_region 0xfce00000 0x100 +alloc_region 0xfee00000 0x100 +alloc_region 0xf8000000 0x8000000 EX_CONFLICTOK +print diff --git a/share/man/man9/extent.9 b/share/man/man9/extent.9 index 21e5e7e56b9..275f208d7f3 100644 --- a/share/man/man9/extent.9 +++ b/share/man/man9/extent.9 @@ -1,4 +1,4 @@ -.\" $OpenBSD: extent.9,v 1.12 2008/06/26 05:42:08 ray Exp $ +.\" $OpenBSD: extent.9,v 1.13 2009/04/10 20:57:04 kettenis Exp $ .\" $NetBSD: extent.9,v 1.15 1999/03/16 00:40:47 garbled Exp $ .\" .\" Copyright (c) 1996, 1998 The NetBSD Foundation, Inc. @@ -28,7 +28,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: June 26 2008 $ +.Dd $Mdocdate: April 10 2009 $ .Dt EXTENT 9 .Os .Sh NAME @@ -234,12 +234,18 @@ beginning at .Fa start with the size .Fa size . +If the caller specifies the +.Dv EX_CONFLICTOK +flag, the allocation will succeed even if part of the requested region +has already been allocated. The caller may specify that it is okay to wait for the indicated region to be free by setting the flag .Dv EX_WAITSPACE . -If +If neither .Dv EX_WAITSPACE -is not set, the allocation will fail if the request can not be +nor +.Dv EX_CONFLICTOK +is set, the allocation will fail if the request can not be satisfied without sleeping. .Pp .Fn extent_free diff --git a/sys/kern/subr_extent.c b/sys/kern/subr_extent.c index 1703d89fad6..8053c1c9583 100644 --- a/sys/kern/subr_extent.c +++ b/sys/kern/subr_extent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_extent.c,v 1.35 2009/04/04 22:32:05 kettenis Exp $ */ +/* $OpenBSD: subr_extent.c,v 1.36 2009/04/10 20:57:04 kettenis Exp $ */ /* $NetBSD: subr_extent.c,v 1.7 1996/11/21 18:46:34 cgd Exp $ */ /*- @@ -401,6 +401,9 @@ extent_alloc_region(struct extent *ex, u_long start, u_long size, int flags) ex->ex_name, start, size); panic("extent_alloc_region: overflow"); } + if ((flags & EX_CONFLICTOK) && (flags & EX_WAITSPACE)) + panic("extent_alloc_region: EX_CONFLICTOK and EX_WAITSPACE " + "are mutually exclusive"); #endif /* @@ -476,6 +479,36 @@ extent_alloc_region(struct extent *ex, u_long start, u_long size, int flags) return (error); goto alloc_start; } + + /* + * If we tolerate conflicts adjust things such + * that all space in the requested region is + * allocated. + */ + if (flags & EX_CONFLICTOK) { + /* + * There are two possibilities: + * + * 1. The current region overlaps. + * Adjust the requested region to + * start at the end of the current + * region, and try again. + * + * 2. The current region falls + * completely within the requested + * region. Free the current region + * and try again. + */ + if (rp->er_start <= start) { + start = rp->er_end + 1; + size = end - start + 1; + } else { + LIST_REMOVE(rp, er_link); + extent_free_region_descriptor(ex, rp); + } + goto alloc_start; + } + extent_free_region_descriptor(ex, myrp); return (EAGAIN); } diff --git a/sys/sys/extent.h b/sys/sys/extent.h index 8b444e48a43..7880117d30a 100644 --- a/sys/sys/extent.h +++ b/sys/sys/extent.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extent.h,v 1.9 2008/06/26 05:42:20 ray Exp $ */ +/* $OpenBSD: extent.h,v 1.10 2009/04/10 20:57:04 kettenis Exp $ */ /* $NetBSD: extent.h,v 1.6 1997/10/09 07:43:05 jtc Exp $ */ /*- @@ -82,6 +82,7 @@ struct extent_fixed { #define EX_MALLOCOK 0x10 /* safe to call malloc() */ #define EX_WAITSPACE 0x20 /* wait for space to become free */ #define EX_BOUNDZERO 0x40 /* boundary lines start at 0 */ +#define EX_CONFLICTOK 0x80 /* allow conlficts */ /* * Special place holders for "alignment" and "boundary" arguments, |