diff options
Diffstat (limited to 'lib/libcuse/cuse_lib.c')
-rw-r--r-- | lib/libcuse/cuse_lib.c | 104 |
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(); |