mirror of
https://github.com/apache/nuttx.git
synced 2026-05-16 05:27:45 +08:00
fs/shmfs: fix inode leak issue
If the shm file is removed and a subsequent close, only release shm object, but inode is leaked. Should decrease refcount to release inode when unmapped, that matched with refcount increase when mapped. Another fix that remove the shm file failed. nsh> rm /var/shm/pts_mmap_1_2_5 nsh: rm: unlink failed: 6 Signed-off-by: fangxinyong <fangxinyong@xiaomi.com>
This commit is contained in:
+23
-9
@@ -258,6 +258,18 @@ static int shmfs_map_object(FAR struct shmfs_object_s *object,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: shmfs_add_map
|
||||
****************************************************************************/
|
||||
|
||||
static int shmfs_add_map(FAR struct mm_map_entry_s *entry,
|
||||
FAR struct inode *inode)
|
||||
{
|
||||
entry->munmap = shmfs_munmap;
|
||||
entry->priv.p = (FAR void *)inode;
|
||||
return mm_map_add(get_current_mm(), entry);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: shmfs_mmap
|
||||
****************************************************************************/
|
||||
@@ -294,16 +306,11 @@ static int shmfs_mmap(FAR struct file *filep,
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
if (ret < 0 ||
|
||||
(ret = shmfs_add_map(entry, filep->f_inode)) < 0)
|
||||
{
|
||||
inode_release(filep->f_inode);
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->munmap = shmfs_munmap;
|
||||
entry->priv.p = (FAR void *)filep->f_inode;
|
||||
ret = mm_map_add(get_current_mm(), entry);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -349,6 +356,7 @@ static int shmfs_munmap(FAR struct task_group_s *group,
|
||||
FAR void *start,
|
||||
size_t length)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
int ret;
|
||||
|
||||
/* Partial unmap is not supported yet */
|
||||
@@ -358,6 +366,8 @@ static int shmfs_munmap(FAR struct task_group_s *group,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
inode = (FAR struct inode *)entry->priv.p;
|
||||
|
||||
/* Unmap the virtual memory area from the user's address space */
|
||||
|
||||
ret = shmfs_unmap_area(group, entry->vaddr, entry->length);
|
||||
@@ -369,13 +379,17 @@ static int shmfs_munmap(FAR struct task_group_s *group,
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
ret = shmfs_release((FAR struct inode *)entry->priv.p);
|
||||
ret = shmfs_release(inode);
|
||||
}
|
||||
|
||||
/* Remove the mapping. */
|
||||
/* Unkeep the inode when unmapped, decrease refcount */
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
inode_release(inode);
|
||||
|
||||
/* Remove the mapping. */
|
||||
|
||||
ret = mm_map_remove(get_group_mm(group), entry);
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -123,7 +123,8 @@ int nx_unlink(FAR const char *pathname)
|
||||
* release all resources because it is no longer accessible.
|
||||
*/
|
||||
|
||||
if (INODE_IS_DRIVER(inode) && inode->u.i_ops->unlink)
|
||||
if ((INODE_IS_DRIVER(inode) || INODE_IS_SHM(inode)) &&
|
||||
inode->u.i_ops->unlink)
|
||||
{
|
||||
/* Notify the character driver that it has been unlinked */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user