incubator-nuttx/fs/mmap/fs_munmap.c

170 lines
5.6 KiB
C

/****************************************************************************
* fs/mmap/fs_munmap.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/mm/map.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <stdint.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/kmalloc.h>
#include "inode/inode.h"
#include "fs_rammap.h"
#include "sched/sched.h"
/****************************************************************************
* Private Functions
****************************************************************************/
static int file_munmap_(FAR void *start, size_t length,
enum mm_map_type_e type)
{
FAR struct tcb_s *tcb = this_task();
FAR struct task_group_s *group = tcb->group;
FAR struct mm_map_entry_s *entry = NULL;
FAR struct mm_map_s *mm = get_current_mm();
int ret = OK;
/* Iterate through all the mappings and call the underlying
* unmap for every mapping where "start" lies
* break loop on any errors.
*
* Get exclusive access to mm_map for this
*/
ret = mm_map_lock();
if (ret == OK)
{
entry = mm_map_find(mm, start, length);
/* If entry don't find, the start and length is invalid. */
if (entry == NULL)
{
ret = -EINVAL;
goto unlock;
}
do
{
DEBUGASSERT(entry->munmap);
ret = entry->munmap(group, entry, start, length);
}
while (ret == OK && (entry = mm_map_find(mm, start, length)));
unlock:
mm_map_unlock();
}
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: file_mummap
*
* Description:
* Equivalent to the standard file_mummap() function except it does not set
* the errno variable.
*
****************************************************************************/
int file_munmap(FAR void *start, size_t length)
{
return file_munmap_(start, length, MAP_KERNEL);
}
/****************************************************************************
* Name: munmap
*
* Description:
*
* munmap() system call deletes mappings for the specified address range.
* All memory starting with 'start' and continuing for a length of 'length'
* bytes are removed.
*
* NuttX operates in a flat open address space. Therefore, it generally
* does not require mmap() and, hence, munmap functionality. There are
* two exceptions where mmap() is available:
*
* 1. mmap() is the API that is used to support direct access to random
* access media under the following very restrictive conditions:
*
* a. The filesystem implements the mmap file operation. Any file
* system that maps files contiguously on the media should support
* this ioctl. (vs. file system that scatter files over the media
* in non-contiguous sectors). As of this writing, ROMFS is the
* only file system that meets this requirement.
* b. The underlying block driver supports the BIOC_XIPBASE ioctl
* command that maps the underlying media to a randomly accessible
* address. At present, only the RAM/ROM disk driver does this.
*
* munmap() is still not required in this first case. The mapped address
* is a static address in the MCUs address space does not need to be
* munmapped. Support for munmap() in this case provided by the simple
* definition in sys/mman.h:
*
* #define munmap(start, length)
*
* 2. If CONFIG_FS_RAMMAP is defined in the configuration, then mmap() will
* support simulation of memory mapped files by copying files whole
* into RAM. munmap() is required in this case to free the allocated
* memory holding the shared copy of the file.
*
* Input Parameters:
* start The start address of the mapping to delete. For this
* simplified munmap() implementation, the must be the start
* address of the memory region (the same address returned by
* mmap()).
* length The length region to be unmapped.
*
* Returned Value:
* On success, munmap() returns 0, on failure -1, and errno is set
* (probably to EINVAL).
*
****************************************************************************/
int munmap(FAR void *start, size_t length)
{
int ret;
ret = file_munmap_(start, length, MAP_USER);
if (ret < 0)
{
set_errno(-ret);
ret = ERROR;
}
return ret;
}