aboutsummaryrefslogtreecommitdiff
path: root/lib/libcuse/cuse_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libcuse/cuse_lib.c')
-rw-r--r--lib/libcuse/cuse_lib.c104
1 files changed, 49 insertions, 55 deletions
diff --git a/lib/libcuse/cuse_lib.c b/lib/libcuse/cuse_lib.c
index 436b5db728bd..3f040d0eeeda 100644
--- a/lib/libcuse/cuse_lib.c
+++ b/lib/libcuse/cuse_lib.c
@@ -1,6 +1,5 @@
-/* $FreeBSD$ */
/*-
- * Copyright (c) 2010-2012 Hans Petter Selasky. All rights reserved.
+ * Copyright (c) 2010-2022 Hans Petter Selasky. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -142,10 +141,10 @@ cuse_vmoffset(void *_ptr)
uint8_t *ptr_max;
uint8_t *ptr = _ptr;
unsigned long remainder;
- int n;
+ unsigned long n;
CUSE_LOCK();
- for (n = 0; n != CUSE_ALLOC_UNIT_MAX; n++) {
+ for (n = remainder = 0; n != CUSE_ALLOC_UNIT_MAX; n++) {
if (a_cuse[n].ptr == NULL)
continue;
@@ -153,89 +152,84 @@ cuse_vmoffset(void *_ptr)
ptr_max = a_cuse[n].ptr + a_cuse[n].size - 1;
if ((ptr >= ptr_min) && (ptr <= ptr_max)) {
-
- CUSE_UNLOCK();
-
remainder = (ptr - ptr_min);
-
- remainder -= remainder % PAGE_SIZE;
-
- return ((n * PAGE_SIZE * CUSE_ALLOC_PAGES_MAX) + remainder);
+ break;
}
}
CUSE_UNLOCK();
- return (0x80000000UL); /* failure */
+ return ((n << CUSE_ALLOC_UNIT_SHIFT) + remainder);
}
void *
-cuse_vmalloc(int size)
+cuse_vmalloc(unsigned size)
{
struct cuse_alloc_info info;
+ unsigned long pgsize;
+ unsigned long x;
+ unsigned long m;
+ unsigned long n;
void *ptr;
int error;
- int n;
- if (f_cuse < 0)
+ /* some sanity checks */
+ if (f_cuse < 0 || size < 1 || size > CUSE_ALLOC_BYTES_MAX)
return (NULL);
memset(&info, 0, sizeof(info));
- if (size < 1)
- return (NULL);
+ pgsize = getpagesize();
+ info.page_count = howmany(size, pgsize);
- info.page_count = howmany(size, PAGE_SIZE);
+ /* compute how many units the allocation needs */
+ m = howmany(size, 1 << CUSE_ALLOC_UNIT_SHIFT);
+ if (m == 0 || m > CUSE_ALLOC_UNIT_MAX)
+ return (NULL);
CUSE_LOCK();
- for (n = 0; n != CUSE_ALLOC_UNIT_MAX; n++) {
-
- if (a_cuse[n].ptr != NULL)
+ for (n = 0; n <= CUSE_ALLOC_UNIT_MAX - m; ) {
+ if (a_cuse[n].size != 0) {
+ /* skip to next available unit, depending on allocation size */
+ n += howmany(a_cuse[n].size, 1 << CUSE_ALLOC_UNIT_SHIFT);
continue;
-
- a_cuse[n].ptr = ((uint8_t *)1); /* reserve */
- a_cuse[n].size = 0;
-
+ }
+ /* check if there are "m" free units ahead */
+ for (x = 1; x != m; x++) {
+ if (a_cuse[n + x].size != 0)
+ break;
+ }
+ if (x != m) {
+ /* skip to next available unit, if any */
+ n += x + 1;
+ continue;
+ }
+ /* reserve this unit by setting the size to a non-zero value */
+ a_cuse[n].size = size;
CUSE_UNLOCK();
info.alloc_nr = n;
error = ioctl(f_cuse, CUSE_IOCTL_ALLOC_MEMORY, &info);
- if (error) {
-
- CUSE_LOCK();
-
- a_cuse[n].ptr = NULL;
-
- if (errno == EBUSY)
- continue;
- else
- break;
- }
- ptr = mmap(NULL, info.page_count * PAGE_SIZE,
- PROT_READ | PROT_WRITE,
- MAP_SHARED, f_cuse, CUSE_ALLOC_PAGES_MAX *
- PAGE_SIZE * n);
-
- if (ptr == MAP_FAILED) {
+ if (error == 0) {
+ ptr = mmap(NULL, info.page_count * pgsize,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED, f_cuse, n << CUSE_ALLOC_UNIT_SHIFT);
- error = ioctl(f_cuse, CUSE_IOCTL_FREE_MEMORY, &info);
+ if (ptr != MAP_FAILED) {
+ CUSE_LOCK();
+ a_cuse[n].ptr = ptr;
+ CUSE_UNLOCK();
- if (error) {
- /* ignore */
+ return (ptr); /* success */
}
- CUSE_LOCK();
-
- a_cuse[n].ptr = NULL;
- break;
+ (void) ioctl(f_cuse, CUSE_IOCTL_FREE_MEMORY, &info);
}
- CUSE_LOCK();
- a_cuse[n].ptr = ptr;
- a_cuse[n].size = size;
- CUSE_UNLOCK();
- return (ptr); /* success */
+ CUSE_LOCK();
+ a_cuse[n].size = 0;
+ n++;
}
CUSE_UNLOCK();
return (NULL); /* failure */
@@ -267,7 +261,7 @@ cuse_vmfree(void *ptr)
int error;
int n;
- if (f_cuse < 0)
+ if (f_cuse < 0 || ptr == NULL)
return;
CUSE_LOCK();