fs/mmap: Suppor the partial unmap for anonymous mapping

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2023-01-11 01:09:04 +08:00 committed by Petro Karashchenko
parent fcd4a421e3
commit fd0195b0d8

View File

@ -39,32 +39,69 @@ static int unmap_anonymous(FAR struct task_group_s *group,
FAR void *start, FAR void *start,
size_t length) size_t length)
{ {
int ret; FAR void *newaddr;
off_t offset;
bool kernel = entry->priv.i;
int ret = OK;
/* De-allocate memory. /* Get the offset from the beginning of the region and the actual number
* NB: This is incomplete anounymous mapping implementation * of bytes to "unmap". All mappings must extend to the end of the region.
* see file_mmap_ below * There is no support for freeing a block of memory but leaving a block of
* memory at the end. This is a consequence of using kumm_realloc() to
* simulate the unmapping.
*/ */
if (start == entry->vaddr && length == entry->length) offset = start - entry->vaddr;
if (offset + length < entry->length)
{ {
/* entry->priv marks allocation from kernel heap */ ferr("ERROR: Cannot umap without unmapping to the end\n");
return -ENOSYS;
}
if (entry->priv.i) /* Okay.. the region is being unmapped to the end. Make sure the length
* indicates that.
*/
length = entry->length - offset;
/* Are we unmapping the entire region (offset == 0)? */
if (length >= entry->length)
{
/* Free the region */
if (kernel)
{ {
kmm_free(start); kmm_free(entry->vaddr);
} }
else else
{ {
kumm_free(start); kumm_free(entry->vaddr);
} }
/* Then remove the mapping from the list */
ret = mm_map_remove(get_group_mm(group), entry); ret = mm_map_remove(get_group_mm(group), entry);
} }
/* No.. We have been asked to "unmap' only a portion of the memory
* (offset > 0).
*/
else else
{ {
ret = -EINVAL; if (kernel)
ferr("ERROR: Unknown map type\n"); {
newaddr = kmm_realloc(entry->vaddr, length);
}
else
{
newaddr = kumm_realloc(entry->vaddr, length);
}
DEBUGASSERT(newaddr == entry->vaddr);
entry->vaddr = newaddr;
entry->length = length;
} }
return ret; return ret;