Implement extent_alloc_region_with_descr(9) which is the equivalent of
authorkettenis <kettenis@openbsd.org>
Fri, 19 Jan 2024 22:12:24 +0000 (22:12 +0000)
committerkettenis <kettenis@openbsd.org>
Fri, 19 Jan 2024 22:12:24 +0000 (22:12 +0000)
extent_alloc_region(9) that uses a pre-allocated region descriptor.

ok patrick@

share/man/man9/extent.9
sys/kern/subr_extent.c
sys/sys/extent.h

index 85511b8..734afa5 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: extent.9,v 1.19 2015/11/01 21:26:48 jmc Exp $
+.\"    $OpenBSD: extent.9,v 1.20 2024/01/19 22:12:24 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: November 1 2015 $
+.Dd $Mdocdate: January 19 2024 $
 .Dt EXTENT 9
 .Os
 .Sh NAME
@@ -39,6 +39,7 @@
 .Nm extent_alloc_subregion ,
 .Nm extent_alloc_subregion_with_descr ,
 .Nm extent_alloc_region ,
+.Nm extent_alloc_region_with_descr ,
 .Nm extent_free ,
 .Nm extent_print
 .Nd general purpose extent manager
@@ -83,6 +84,8 @@
 .Ft int
 .Fn extent_alloc_region "struct extent *ex" "u_long start" "u_long size" "int flags"
 .Ft int
+.Fn extent_alloc_region_with_descr "struct extent *ex" "u_long start" "u_long size" "int flags" "struct extent_region *rp"
+.Ft int
 .Fn extent_free "struct extent *ex" "u_long start" "u_long size" "int flags"
 .Ft void
 .Fn extent_print "struct extent *ex"
@@ -290,6 +293,15 @@ nor
 is set, the allocation will fail if the request cannot be
 satisfied without sleeping.
 .Pp
+.Fn extent_alloc_region_with_descr
+is similar to
+.Fn extent_alloc_region
+but allows the caller to provide a pre-allocated region descriptor instead
+of having the function allocate one.
+This function can only be used with extents that have the
+.Dv EX_NOCOALESCE
+property.
+.Pp
 .Fn extent_free
 frees a region of
 .Fa size
index be5690a..49ab339 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: subr_extent.c,v 1.64 2022/12/05 23:18:37 deraadt Exp $        */
+/*     $OpenBSD: subr_extent.c,v 1.65 2024/01/19 22:12:24 kettenis Exp $       */
 /*     $NetBSD: subr_extent.c,v 1.7 1996/11/21 18:46:34 cgd Exp $      */
 
 /*-
@@ -398,9 +398,10 @@ extent_insert_and_optimize(struct extent *ex, u_long start, u_long size,
  * Allocate a specific region in an extent map.
  */
 int
-extent_alloc_region(struct extent *ex, u_long start, u_long size, int flags)
+extent_do_alloc_region(struct extent *ex, u_long start, u_long size,
+    int flags, struct extent_region *myrp)
 {
-       struct extent_region *rp, *last, *myrp;
+       struct extent_region *rp, *last;
        u_long end = start + (size - 1);
        int error;
 
@@ -435,23 +436,11 @@ extent_alloc_region(struct extent *ex, u_long start, u_long size, int flags)
                    __func__, start, end);
                panic("%s: region lies outside extent", __func__);
 #else
+               extent_free_region_descriptor(ex, myrp);
                return (EINVAL);
 #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:
        /*
         * Attempt to place ourselves in the desired area of the
@@ -567,6 +556,39 @@ extent_alloc_region(struct extent *ex, u_long start, u_long size, int flags)
        return (0);
 }
 
+int
+extent_alloc_region(struct extent *ex, u_long start, u_long size, int flags)
+{
+       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_region(ex, start, size, flags, rp);
+}
+
+int
+extent_alloc_region_with_descr(struct extent *ex, u_long start,
+    u_long size, int flags, struct extent_region *rp)
+{
+#ifdef DIAGNOSTIC
+       if ((ex->ex_flags & EXF_NOCOALESCE) == 0)
+               panic("%s: EX_NOCOALESCE not set", __func__);
+#endif
+
+       rp->er_flags = ER_DISCARD;
+       return extent_do_alloc_region(ex, start, size, flags, rp);
+}
+
 /*
  * Macro to check (x + y) <= z.  This check is designed to fail
  * if an overflow occurs.
index 21be296..5a1395a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: extent.h,v 1.14 2014/02/08 20:29:01 kettenis Exp $    */
+/*     $OpenBSD: extent.h,v 1.15 2024/01/19 22:12:24 kettenis Exp $    */
 /*     $NetBSD: extent.h,v 1.6 1997/10/09 07:43:05 jtc Exp $   */
 
 /*-
@@ -110,6 +110,8 @@ 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_alloc_region_with_descr(struct extent *, u_long, u_long,
+           int, struct extent_region *);
 int    extent_free(struct extent *, u_long, u_long, int);
 void   extent_print(struct extent *);