fs/mmap: Suppor the partial unmap for anonymous mapping
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
parent
fcd4a421e3
commit
fd0195b0d8
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user