> 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

Reply via email to