From baaa8a4a8a963dc2a96f778b359fc4600b40d710 Mon Sep 17 00:00:00 2001 From: kettenis Date: Fri, 19 Jan 2024 22:12:24 +0000 Subject: [PATCH] Implement extent_alloc_region_with_descr(9) which is the equivalent of extent_alloc_region(9) that uses a pre-allocated region descriptor. ok patrick@ --- share/man/man9/extent.9 | 16 ++++++++++-- sys/kern/subr_extent.c | 54 +++++++++++++++++++++++++++++------------ sys/sys/extent.h | 4 ++- 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/share/man/man9/extent.9 b/share/man/man9/extent.9 index 85511b8a866..734afa53c2a 100644 --- a/share/man/man9/extent.9 +++ b/share/man/man9/extent.9 @@ -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 diff --git a/sys/kern/subr_extent.c b/sys/kern/subr_extent.c index be5690a9dba..49ab339ba9e 100644 --- a/sys/kern/subr_extent.c +++ b/sys/kern/subr_extent.c @@ -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. diff --git a/sys/sys/extent.h b/sys/sys/extent.h index 21be2968c05..5a1395a1667 100644 --- a/sys/sys/extent.h +++ b/sys/sys/extent.h @@ -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 *); -- 2.20.1