> This is ugly. Better introduce an extent_alloc_with_descr() or
> extent_alloc_static() interface which is similar to extent_alloc(), but
> receives the extent descriptor as an added argument.
Fair enough; seems this is indeed a better interface as it doesn't
require the use of a "fixed" extent.
Here's a new diff. I'll do the man page before committing this.
ok?
Index: sys/extent.h
===================================================================
RCS file: /cvs/src/sys/sys/extent.h,v
retrieving revision 1.12
diff -u -p -r1.12 extent.h
--- sys/extent.h 19 Apr 2009 15:26:52 -0000 1.12
+++ sys/extent.h 21 Jan 2014 00:28:12 -0000
@@ -44,6 +44,7 @@ struct extent_region {
/* er_flags */
#define ER_ALLOC 0x01 /* region descriptor dynamically allocated */
+#define ER_DISCARD 0x02 /* discard region descriptor after use */
struct extent {
char *ex_name; /* name of extent */
@@ -105,6 +106,9 @@ struct extent *extent_create(char *, u_l
void extent_destroy(struct extent *);
int extent_alloc_subregion(struct extent *, u_long, u_long,
u_long, u_long, u_long, u_long, int, u_long *);
+int extent_alloc_subregion_with_descr(struct extent *, u_long, u_long,
+ u_long, u_long, u_long, u_long, int, struct extent_region *,
+ u_long *);
int extent_alloc_region(struct extent *, u_long, u_long, int);
int extent_free(struct extent *, u_long, u_long, int);
void extent_print(struct extent *);
Index: kern/subr_extent.c
===================================================================
RCS file: /cvs/src/sys/kern/subr_extent.c,v
retrieving revision 1.48
diff -u -p -r1.48 subr_extent.c
--- kern/subr_extent.c 8 Aug 2013 23:25:06 -0000 1.48
+++ kern/subr_extent.c 21 Jan 2014 00:32:35 -0000
@@ -78,6 +78,8 @@ static void extent_insert_and_optimize(s
static struct extent_region *extent_alloc_region_descriptor(struct extent *,
int);
static void extent_free_region_descriptor(struct extent *,
struct extent_region *);
+int extent_do_alloc(struct extent *, u_long, u_long, u_long, u_long,
+ u_long, u_long, int, struct extent_region *, u_long *);
/*
* Shortcut to align to an arbitrary power-of-two boundary.
@@ -580,11 +582,11 @@ extent_alloc_region(struct extent *ex, u
* a power of 2.
*/
int
-extent_alloc_subregion(struct extent *ex, u_long substart, u_long subend,
+extent_do_alloc(struct extent *ex, u_long substart, u_long subend,
u_long size, u_long alignment, u_long skew, u_long boundary, int flags,
- u_long *result)
+ struct extent_region *myrp, u_long *result)
{
- struct extent_region *rp, *myrp, *last, *bestlast;
+ struct extent_region *rp, *last, *bestlast;
u_long newstart, newend, exend, beststart, bestovh, ovh;
u_long dontcross;
int error;
@@ -593,6 +595,8 @@ extent_alloc_subregion(struct extent *ex
/* Check arguments. */
if (ex == NULL)
panic("%s: NULL extent", __func__);
+ if (myrp == NULL)
+ panic("%s: NULL region descriptor", __func__);
if (result == NULL)
panic("%s: NULL result pointer", __func__);
if ((substart < ex->ex_start) || (substart > ex->ex_end) ||
@@ -617,18 +621,6 @@ extent_alloc_subregion(struct extent *ex
}
#endif
- /*
- * Allocate the region descriptor. It will be freed later
- * if we can coalesce with another region.
- */
- myrp = extent_alloc_region_descriptor(ex, flags);
- if (myrp == NULL) {
-#ifdef DIAGNOSTIC
- printf("%s: can't allocate region descriptor\n", __func__);
-#endif
- return (ENOMEM);
- }
-
alloc_start:
/*
* Keep a pointer to the last region we looked at so
@@ -927,6 +919,41 @@ skip:
}
int
+extent_alloc_subregion(struct extent *ex, u_long substart, u_long subend,
+ u_long size, u_long alignment, u_long skew, u_long boundary, int flags,
+ u_long *result)
+{
+ struct extent_region *rp;
+
+ /*
+ * Allocate the region descriptor. It will be freed later
+ * if we can coalesce with another region.
+ */
+ rp = extent_alloc_region_descriptor(ex, flags);
+ if (rp == NULL) {
+#ifdef DIAGNOSTIC
+ printf("%s: can't allocate region descriptor\n", __func__);
+#endif
+ return (ENOMEM);
+ }
+
+ return extent_do_alloc(ex, substart, subend, size, alignment, skew,
+ boundary, flags, rp, result);
+}
+
+int
+extent_alloc_subregion_with_descr(struct extent *ex, u_long substart,
+ u_long subend, u_long size, u_long alignment, u_long skew,
+ u_long boundary, int flags, struct extent_region *rp, u_long *result)
+{
+ KASSERT(ex->ex_flags & EXF_NOCOALESCE);
+
+ rp->er_flags = ER_DISCARD;
+ return extent_do_alloc(ex, substart, subend, size, alignment, skew,
+ boundary, flags, rp, result);
+}
+
+int
extent_free(struct extent *ex, u_long start, u_long size, int flags)
{
struct extent_region *rp, *nrp = NULL;
@@ -1111,6 +1138,9 @@ extent_alloc_region_descriptor(struct ex
static void
extent_free_region_descriptor(struct extent *ex, struct extent_region *rp)
{
+ if (rp->er_flags & ER_DISCARD)
+ return;
+
if (ex->ex_flags & EXF_FIXED) {
struct extent_fixed *fex = (struct extent_fixed *)ex;
@@ -1149,7 +1179,7 @@ extent_free_region_descriptor(struct ext
pool_put(&ex_region_pl, rp);
}
-
+
#if defined(DIAGNOSTIC) || defined(DDB) || !defined(_KERNEL)
void