-.\" $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.
.\" 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
.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
.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"
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
-/* $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 $ */
/*-
* 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;
__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
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.
-/* $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 $ */
/*-
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 *);