summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--regress/sys/kern/extent/extest.awk11
-rw-r--r--regress/sys/kern/extent/extest.exp13
-rw-r--r--regress/sys/kern/extent/tests26
-rw-r--r--share/man/man9/extent.914
-rw-r--r--sys/kern/subr_extent.c35
-rw-r--r--sys/sys/extent.h3
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,