feat: page cache backed by vnode instead of filep
1, change the owner of page to vnode 2, save the file path in vnode close: #I44TBS Signed-off-by: Leon Chan <chenwei26@huawei.com>
This commit is contained in:
@@ -44,6 +44,8 @@
|
||||
#include "los_vm_zone.h"
|
||||
#include "los_vm_common.h"
|
||||
|
||||
struct Vnode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
@@ -91,8 +93,8 @@ struct VmMapRegion {
|
||||
UINT8 regionType; /**< vm region type: ANON, FILE, DEV */
|
||||
union {
|
||||
struct VmRegionFile {
|
||||
unsigned int fileMagic;
|
||||
struct file *file;
|
||||
int f_oflags;
|
||||
struct Vnode *vnode;
|
||||
const LosVmFileOps *vmFOps;
|
||||
} rf;
|
||||
struct VmRegionAnon {
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "los_mmu_descriptor_v6.h"
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
#include "fs/file.h"
|
||||
#include "vnode.h"
|
||||
#endif
|
||||
#include "los_printf.h"
|
||||
#include "los_vm_page.h"
|
||||
@@ -55,13 +56,13 @@
|
||||
|
||||
const CHAR *OsGetRegionNameOrFilePath(LosVmMapRegion *region)
|
||||
{
|
||||
struct file *filep = NULL;
|
||||
struct Vnode *vnode = NULL;
|
||||
if (region == NULL) {
|
||||
return "";
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
} else if (LOS_IsRegionFileValid(region)) {
|
||||
filep = region->unTypeData.rf.file;
|
||||
return filep->f_path;
|
||||
vnode = region->unTypeData.rf.vnode;
|
||||
return vnode->filePath;
|
||||
#endif
|
||||
} else if (region->regionFlags & VM_MAP_REGION_FLAG_HEAP) {
|
||||
return "HEAP";
|
||||
|
||||
@@ -45,6 +45,10 @@
|
||||
#include "los_process_pri.h"
|
||||
#include "arm.h"
|
||||
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
#include "vnode.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef LOSCFG_KERNEL_VM
|
||||
|
||||
@@ -106,11 +110,11 @@ STATIC STATUS_T OsDoReadFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
|
||||
return LOS_OK;
|
||||
}
|
||||
if (region->unTypeData.rf.vmFOps == NULL || region->unTypeData.rf.vmFOps->fault == NULL) {
|
||||
VM_ERR("region args invalid, file path: %s", region->unTypeData.rf.file->f_path);
|
||||
VM_ERR("region args invalid, file path: %s", region->unTypeData.rf.vnode->filePath);
|
||||
return LOS_ERRNO_VM_INVALID_ARGS;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxAcquire(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
(VOID)LOS_MuxAcquire(®ion->unTypeData.rf.vnode->mapping.mux_lock);
|
||||
ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault);
|
||||
if (ret == LOS_OK) {
|
||||
paddr = LOS_PaddrQuery(vmPgFault->pageKVaddr);
|
||||
@@ -124,14 +128,14 @@ STATIC STATUS_T OsDoReadFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
|
||||
if (ret < 0) {
|
||||
VM_ERR("LOS_ArchMmuMap failed");
|
||||
OsDelMapInfo(region, vmPgFault, false);
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock);
|
||||
return LOS_ERRNO_VM_NO_MEMORY;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock);
|
||||
return LOS_OK;
|
||||
}
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock);
|
||||
|
||||
return LOS_ERRNO_VM_NO_MEMORY;
|
||||
}
|
||||
@@ -145,8 +149,8 @@ STATIC LosVmPage *OsCowUnmapOrg(LosArchMmu *archMmu, LosVmMapRegion *region, Los
|
||||
LosFilePage *fpage = NULL;
|
||||
VADDR_T vaddr = (VADDR_T)vmf->vaddr;
|
||||
|
||||
LOS_SpinLockSave(®ion->unTypeData.rf.file->f_mapping->list_lock, &intSave);
|
||||
fpage = OsFindGetEntry(region->unTypeData.rf.file->f_mapping, vmf->pgoff);
|
||||
LOS_SpinLockSave(®ion->unTypeData.rf.vnode->mapping.list_lock, &intSave);
|
||||
fpage = OsFindGetEntry(®ion->unTypeData.rf.vnode->mapping, vmf->pgoff);
|
||||
if (fpage != NULL) {
|
||||
oldPage = fpage->vmPage;
|
||||
OsSetPageLocked(oldPage);
|
||||
@@ -159,7 +163,7 @@ STATIC LosVmPage *OsCowUnmapOrg(LosArchMmu *archMmu, LosVmMapRegion *region, Los
|
||||
} else {
|
||||
LOS_ArchMmuUnmap(archMmu, vaddr, 1);
|
||||
}
|
||||
LOS_SpinUnlockRestore(®ion->unTypeData.rf.file->f_mapping->list_lock, intSave);
|
||||
LOS_SpinUnlockRestore(®ion->unTypeData.rf.vnode->mapping.list_lock, intSave);
|
||||
|
||||
return oldPage;
|
||||
}
|
||||
@@ -197,11 +201,11 @@ status_t OsDoCowFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
|
||||
newPaddr = VM_PAGE_TO_PHYS(newPage);
|
||||
kvaddr = OsVmPageToVaddr(newPage);
|
||||
|
||||
(VOID)LOS_MuxAcquire(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
(VOID)LOS_MuxAcquire(®ion->unTypeData.rf.vnode->mapping.mux_lock);
|
||||
ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault);
|
||||
if (ret != LOS_OK) {
|
||||
VM_ERR("call region->vm_ops->fault fail");
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock);
|
||||
goto ERR_OUT;
|
||||
}
|
||||
|
||||
@@ -227,10 +231,10 @@ status_t OsDoCowFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
|
||||
if (ret < 0) {
|
||||
VM_ERR("LOS_ArchMmuMap failed");
|
||||
ret = LOS_ERRNO_VM_NO_MEMORY;
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock);
|
||||
goto ERR_OUT;
|
||||
}
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock);
|
||||
|
||||
if (oldPage != NULL) {
|
||||
OsCleanPageLocked(oldPage);
|
||||
@@ -273,17 +277,17 @@ status_t OsDoSharedFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
|
||||
return LOS_ERRNO_VM_NO_MEMORY;
|
||||
}
|
||||
|
||||
LOS_SpinLockSave(®ion->unTypeData.rf.file->f_mapping->list_lock, &intSave);
|
||||
fpage = OsFindGetEntry(region->unTypeData.rf.file->f_mapping, vmPgFault->pgoff);
|
||||
LOS_SpinLockSave(®ion->unTypeData.rf.vnode->mapping.list_lock, &intSave);
|
||||
fpage = OsFindGetEntry(®ion->unTypeData.rf.vnode->mapping, vmPgFault->pgoff);
|
||||
if (fpage) {
|
||||
OsMarkPageDirty(fpage, region, 0, 0);
|
||||
}
|
||||
LOS_SpinUnlockRestore(®ion->unTypeData.rf.file->f_mapping->list_lock, intSave);
|
||||
LOS_SpinUnlockRestore(®ion->unTypeData.rf.vnode->mapping.list_lock, intSave);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxAcquire(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
(VOID)LOS_MuxAcquire(®ion->unTypeData.rf.vnode->mapping.mux_lock);
|
||||
ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault);
|
||||
if (ret == LOS_OK) {
|
||||
paddr = LOS_PaddrQuery(vmPgFault->pageKVaddr);
|
||||
@@ -297,14 +301,14 @@ status_t OsDoSharedFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
|
||||
if (ret < 0) {
|
||||
VM_ERR("LOS_ArchMmuMap failed. ret=%d", ret);
|
||||
OsDelMapInfo(region, vmPgFault, TRUE);
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock);
|
||||
return LOS_ERRNO_VM_NO_MEMORY;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock);
|
||||
return LOS_OK;
|
||||
}
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -382,7 +386,7 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
|
||||
vaddr = ROUNDDOWN(vaddr, PAGE_SIZE);
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
if (LOS_IsRegionFileValid(region)) {
|
||||
if (region->unTypeData.rf.file->f_mapping == NULL) {
|
||||
if (region->unTypeData.rf.vnode == NULL) {
|
||||
goto CHECK_FAILED;
|
||||
}
|
||||
vmPgFault.vaddr = vaddr;
|
||||
|
||||
@@ -172,17 +172,17 @@ VOID OsVmmFileRemove(LosVmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T pg
|
||||
UINT32 intSave;
|
||||
vaddr_t vaddr;
|
||||
paddr_t paddr = 0;
|
||||
struct file *file = NULL;
|
||||
struct Vnode *vnode = NULL;
|
||||
struct page_mapping *mapping = NULL;
|
||||
LosFilePage *fpage = NULL;
|
||||
LosFilePage *tmpPage = NULL;
|
||||
LosVmPage *mapPage = NULL;
|
||||
|
||||
if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.file->f_mapping == NULL)) {
|
||||
if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.vnode == NULL)) {
|
||||
return;
|
||||
}
|
||||
file = region->unTypeData.rf.file;
|
||||
mapping = file->f_mapping;
|
||||
vnode = region->unTypeData.rf.vnode;
|
||||
mapping = &vnode->mapping;
|
||||
vaddr = region->range.base + ((UINT32)(pgoff - region->pgOff) << PAGE_SHIFT);
|
||||
|
||||
status_t status = LOS_ArchMmuQuery(archMmu, vaddr, &paddr, NULL);
|
||||
@@ -232,15 +232,15 @@ VOID OsMarkPageDirty(LosFilePage *fpage, LosVmMapRegion *region, INT32 off, INT3
|
||||
}
|
||||
}
|
||||
|
||||
STATIC UINT32 GetDirtySize(LosFilePage *fpage, struct file *file)
|
||||
STATIC UINT32 GetDirtySize(LosFilePage *fpage, struct Vnode *vnode)
|
||||
{
|
||||
UINT32 fileSize;
|
||||
UINT32 dirtyBegin;
|
||||
UINT32 dirtyEnd;
|
||||
struct stat buf_stat;
|
||||
|
||||
if (stat(file->f_path, &buf_stat) != OK) {
|
||||
VM_ERR("FlushDirtyPage get file size failed. (filepath=%s)", file->f_path);
|
||||
if (stat(vnode->filePath, &buf_stat) != OK) {
|
||||
VM_ERR("FlushDirtyPage get file size failed. (filePath=%s)", vnode->filePath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -264,31 +264,29 @@ STATIC INT32 OsFlushDirtyPage(LosFilePage *fpage)
|
||||
UINT32 ret;
|
||||
size_t len;
|
||||
char *buff = NULL;
|
||||
VM_OFFSET_T oldPos;
|
||||
struct file *file = fpage->mapping->host;
|
||||
if ((file == NULL) || (file->f_vnode == NULL)) {
|
||||
VM_ERR("page cache file error");
|
||||
struct Vnode *vnode = fpage->mapping->host;
|
||||
if (vnode == NULL) {
|
||||
VM_ERR("page cache vnode error");
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
oldPos = file_seek(file, 0, SEEK_CUR);
|
||||
buff = (char *)OsVmPageToVaddr(fpage->vmPage);
|
||||
file_seek(file, (((UINT32)fpage->pgoff << PAGE_SHIFT) + fpage->dirtyOff), SEEK_SET);
|
||||
len = fpage->dirtyEnd - fpage->dirtyOff;
|
||||
len = (len == 0) ? GetDirtySize(fpage, file) : len;
|
||||
len = (len == 0) ? GetDirtySize(fpage, vnode) : len;
|
||||
if (len == 0) {
|
||||
OsCleanPageDirty(fpage->vmPage);
|
||||
(VOID)file_seek(file, oldPos, SEEK_SET);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
ret = file_write(file, (VOID *)buff, len);
|
||||
buff = (char *)OsVmPageToVaddr(fpage->vmPage);
|
||||
|
||||
/* actually, we did not update the fpage->dirtyOff */
|
||||
ret = vnode->vop->WritePage(vnode, (VOID *)buff, fpage->pgoff, len);
|
||||
if (ret <= 0) {
|
||||
VM_ERR("WritePage error ret %d", ret);
|
||||
} else {
|
||||
OsCleanPageDirty(fpage->vmPage);
|
||||
}
|
||||
ret = (ret <= 0) ? LOS_NOK : LOS_OK;
|
||||
OsCleanPageDirty(fpage->vmPage);
|
||||
(VOID)file_seek(file, oldPos, SEEK_SET);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -336,15 +334,17 @@ VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *vmf, BOOL cleanDirty)
|
||||
UINT32 intSave;
|
||||
LosMapInfo *info = NULL;
|
||||
LosFilePage *fpage = NULL;
|
||||
struct page_mapping *mapping = NULL;
|
||||
|
||||
if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.file->f_mapping == NULL) || (vmf == NULL)) {
|
||||
if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.vnode == NULL) || (vmf == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOS_SpinLockSave(®ion->unTypeData.rf.file->f_mapping->list_lock, &intSave);
|
||||
fpage = OsFindGetEntry(region->unTypeData.rf.file->f_mapping, vmf->pgoff);
|
||||
mapping = ®ion->unTypeData.rf.vnode->mapping;
|
||||
LOS_SpinLockSave(&mapping->list_lock, &intSave);
|
||||
fpage = OsFindGetEntry(mapping, vmf->pgoff);
|
||||
if (fpage == NULL) {
|
||||
LOS_SpinUnlockRestore(®ion->unTypeData.rf.file->f_mapping->list_lock, intSave);
|
||||
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -356,31 +356,30 @@ VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *vmf, BOOL cleanDirty)
|
||||
fpage->n_maps--;
|
||||
LOS_ListDelete(&info->node);
|
||||
LOS_AtomicDec(&fpage->vmPage->refCounts);
|
||||
LOS_SpinUnlockRestore(®ion->unTypeData.rf.file->f_mapping->list_lock, intSave);
|
||||
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
|
||||
LOS_MemFree(m_aucSysMem0, info);
|
||||
return;
|
||||
}
|
||||
LOS_SpinUnlockRestore(®ion->unTypeData.rf.file->f_mapping->list_lock, intSave);
|
||||
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
|
||||
}
|
||||
|
||||
INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf)
|
||||
{
|
||||
INT32 ret;
|
||||
VM_OFFSET_T oldPos;
|
||||
VOID *kvaddr = NULL;
|
||||
|
||||
UINT32 intSave;
|
||||
bool newCache = false;
|
||||
struct file *file = NULL;
|
||||
struct Vnode *vnode = NULL;
|
||||
struct page_mapping *mapping = NULL;
|
||||
LosFilePage *fpage = NULL;
|
||||
|
||||
if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.file->f_mapping == NULL) || (vmf == NULL)) {
|
||||
if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.vnode == NULL) || (vmf == NULL)) {
|
||||
VM_ERR("Input param is NULL");
|
||||
return LOS_NOK;
|
||||
}
|
||||
file = region->unTypeData.rf.file;
|
||||
mapping = file->f_mapping;
|
||||
vnode = region->unTypeData.rf.vnode;
|
||||
mapping = &vnode->mapping;
|
||||
|
||||
/* get or create a new cache node */
|
||||
LOS_SpinLockSave(&mapping->list_lock, &intSave);
|
||||
@@ -404,10 +403,7 @@ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf)
|
||||
|
||||
/* read file to new page cache */
|
||||
if (newCache) {
|
||||
oldPos = file_seek(file, 0, SEEK_CUR);
|
||||
file_seek(file, fpage->pgoff << PAGE_SHIFT, SEEK_SET);
|
||||
ret = file_read(file, kvaddr, PAGE_SIZE);
|
||||
file_seek(file, oldPos, SEEK_SET);
|
||||
ret = vnode->vop->ReadPage(vnode, kvaddr, fpage->pgoff << PAGE_SHIFT);
|
||||
if (ret == 0) {
|
||||
VM_ERR("Failed to read from file!");
|
||||
OsReleaseFpage(mapping, fpage);
|
||||
@@ -505,8 +501,9 @@ LosVmFileOps g_commVmOps = {
|
||||
INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region)
|
||||
{
|
||||
region->unTypeData.rf.vmFOps = &g_commVmOps;
|
||||
region->unTypeData.rf.file = filep;
|
||||
region->unTypeData.rf.fileMagic = filep->f_magicnum;
|
||||
region->unTypeData.rf.vnode = filep->f_vnode;
|
||||
region->unTypeData.rf.f_oflags = filep->f_oflags;
|
||||
|
||||
return ENOERR;
|
||||
}
|
||||
|
||||
@@ -516,11 +513,11 @@ STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region)
|
||||
if (filep == NULL) {
|
||||
return LOS_ERRNO_VM_MAP_FAILED;
|
||||
}
|
||||
file_hold(filep);
|
||||
vnode = filep->f_vnode;
|
||||
if (vnode == NULL) {
|
||||
return LOS_ERRNO_VM_MAP_FAILED;
|
||||
}
|
||||
|
||||
VnodeHold();
|
||||
vnode->useCount++;
|
||||
VnodeDrop();
|
||||
if (filep->ops != NULL && filep->ops->mmap != NULL) {
|
||||
if (vnode->type == VNODE_TYPE_CHR || vnode->type == VNODE_TYPE_BLK) {
|
||||
LOS_SetRegionTypeDev(region);
|
||||
@@ -529,12 +526,15 @@ STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region)
|
||||
}
|
||||
int ret = filep->ops->mmap(filep, region);
|
||||
if (ret != LOS_OK) {
|
||||
file_release(filep);
|
||||
return LOS_ERRNO_VM_MAP_FAILED;
|
||||
}
|
||||
} else {
|
||||
VM_ERR("mmap file type unknown");
|
||||
file_release(filep);
|
||||
return LOS_ERRNO_VM_MAP_FAILED;
|
||||
}
|
||||
file_release(filep);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
@@ -600,40 +600,7 @@ LosFilePage *OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff)
|
||||
return fpage;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
VOID OsVmmFileRegionFree(struct file *filep, LosProcessCB *processCB)
|
||||
{
|
||||
int ret;
|
||||
LosVmSpace *space = NULL;
|
||||
LosVmMapRegion *region = NULL;
|
||||
LosRbNode *pstRbNode = NULL;
|
||||
LosRbNode *pstRbNodeTmp = NULL;
|
||||
|
||||
if (processCB == NULL) {
|
||||
processCB = OsCurrProcessGet();
|
||||
}
|
||||
|
||||
space = processCB->vmSpace;
|
||||
if (space != NULL) {
|
||||
(VOID)LOS_MuxAcquire(&space->regionMux);
|
||||
/* free the regions associated with filep */
|
||||
RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeTmp)
|
||||
region = (LosVmMapRegion *)pstRbNode;
|
||||
if (LOS_IsRegionFileValid(region)) {
|
||||
if (region->unTypeData.rf.file != filep) {
|
||||
continue;
|
||||
}
|
||||
ret = LOS_RegionFree(space, region);
|
||||
if (ret != LOS_OK) {
|
||||
VM_ERR("free region error, space %p, region %p", space, region);
|
||||
}
|
||||
}
|
||||
RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeTmp)
|
||||
(VOID)LOS_MuxRelease(&space->regionMux);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#ifndef LOSCFG_FS_VFS
|
||||
INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region)
|
||||
{
|
||||
UNUSED(filep);
|
||||
@@ -642,3 +609,4 @@ INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "los_process_pri.h"
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
#include "fs/file.h"
|
||||
#include "vnode.h"
|
||||
#endif
|
||||
#include "los_task.h"
|
||||
#include "los_memory_pri.h"
|
||||
@@ -308,12 +309,12 @@ STATUS_T LOS_VmSpaceClone(LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace)
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
if (LOS_IsRegionFileValid(oldRegion)) {
|
||||
LosFilePage *fpage = NULL;
|
||||
LOS_SpinLockSave(&oldRegion->unTypeData.rf.file->f_mapping->list_lock, &intSave);
|
||||
fpage = OsFindGetEntry(oldRegion->unTypeData.rf.file->f_mapping, newRegion->pgOff + i);
|
||||
LOS_SpinLockSave(&oldRegion->unTypeData.rf.vnode->mapping.list_lock, &intSave);
|
||||
fpage = OsFindGetEntry(&oldRegion->unTypeData.rf.vnode->mapping, newRegion->pgOff + i);
|
||||
if ((fpage != NULL) && (fpage->vmPage == page)) { /* cow page no need map */
|
||||
OsAddMapInfo(fpage, &newVmSpace->archMmu, vaddr);
|
||||
}
|
||||
LOS_SpinUnlockRestore(&oldRegion->unTypeData.rf.file->f_mapping->list_lock, intSave);
|
||||
LOS_SpinUnlockRestore(&oldRegion->unTypeData.rf.vnode->mapping.list_lock, intSave);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -436,13 +437,9 @@ VADDR_T OsAllocSpecificRange(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len, UIN
|
||||
|
||||
BOOL LOS_IsRegionFileValid(LosVmMapRegion *region)
|
||||
{
|
||||
struct file *filep = NULL;
|
||||
if ((region != NULL) && (LOS_IsRegionTypeFile(region)) &&
|
||||
(region->unTypeData.rf.file != NULL)) {
|
||||
filep = region->unTypeData.rf.file;
|
||||
if (region->unTypeData.rf.fileMagic == filep->f_magicnum) {
|
||||
return TRUE;
|
||||
}
|
||||
(region->unTypeData.rf.vnode != NULL)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -465,6 +462,7 @@ LosVmMapRegion *OsCreateRegion(VADDR_T vaddr, size_t len, UINT32 regionFlags, un
|
||||
return region;
|
||||
}
|
||||
|
||||
memset_s(region, sizeof(LosVmMapRegion), 0, sizeof(LosVmMapRegion));
|
||||
region->range.base = vaddr;
|
||||
region->range.size = len;
|
||||
region->pgOff = offset;
|
||||
@@ -624,6 +622,9 @@ STATUS_T LOS_RegionFree(LosVmSpace *space, LosVmMapRegion *region)
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
if (LOS_IsRegionFileValid(region)) {
|
||||
OsFilePagesRemove(space, region);
|
||||
VnodeHold();
|
||||
region->unTypeData.rf.vnode->useCount--;
|
||||
VnodeDrop();
|
||||
} else
|
||||
#endif
|
||||
|
||||
@@ -675,8 +676,11 @@ LosVmMapRegion *OsVmRegionDup(LosVmSpace *space, LosVmMapRegion *oldRegion, VADD
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
if (LOS_IsRegionTypeFile(oldRegion)) {
|
||||
newRegion->unTypeData.rf.vmFOps = oldRegion->unTypeData.rf.vmFOps;
|
||||
newRegion->unTypeData.rf.file = oldRegion->unTypeData.rf.file;
|
||||
newRegion->unTypeData.rf.fileMagic = oldRegion->unTypeData.rf.fileMagic;
|
||||
newRegion->unTypeData.rf.vnode = oldRegion->unTypeData.rf.vnode;
|
||||
newRegion->unTypeData.rf.f_oflags = oldRegion->unTypeData.rf.f_oflags;
|
||||
VnodeHold();
|
||||
newRegion->unTypeData.rf.vnode->useCount++;
|
||||
VnodeDrop();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ STATIC INLINE BOOL OsProtMprotectPermCheck(unsigned long prot, LosVmMapRegion *r
|
||||
{
|
||||
UINT32 protFlags = 0;
|
||||
UINT32 permFlags = 0;
|
||||
UINT32 fileFlags = (((region->unTypeData).rf).file)->f_oflags;
|
||||
UINT32 fileFlags = region->unTypeData.rf.f_oflags;
|
||||
permFlags |= ((fileFlags & O_ACCMODE) ^ O_RDONLY) ? 0 : VM_MAP_REGION_FLAG_PERM_READ;
|
||||
permFlags |= (fileFlags & O_WRONLY) ? VM_MAP_REGION_FLAG_PERM_WRITE : 0;
|
||||
permFlags |= (fileFlags & O_RDWR) ? (VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE) : 0;
|
||||
|
||||
Reference in New Issue
Block a user