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:
parent
ba977dd5ab
commit
38a6b804e9
|
@ -276,8 +276,8 @@ STATIC const CHAR *g_excTypeString[] = {
|
|||
#ifdef LOSCFG_KERNEL_VM
|
||||
STATIC VADDR_T OsGetTextRegionBase(LosVmMapRegion *region, LosProcessCB *runProcess)
|
||||
{
|
||||
struct file *curFilep = NULL;
|
||||
struct file *lastFilep = NULL;
|
||||
struct Vnode *curVnode = NULL;
|
||||
struct Vnode *lastVnode = NULL;
|
||||
LosVmMapRegion *curRegion = NULL;
|
||||
LosVmMapRegion *lastRegion = NULL;
|
||||
|
||||
|
@ -296,9 +296,9 @@ STATIC VADDR_T OsGetTextRegionBase(LosVmMapRegion *region, LosProcessCB *runProc
|
|||
if ((lastRegion == NULL) || !LOS_IsRegionFileValid(lastRegion)) {
|
||||
goto DONE;
|
||||
}
|
||||
curFilep = curRegion->unTypeData.rf.file;
|
||||
lastFilep = lastRegion->unTypeData.rf.file;
|
||||
} while (!strcmp(curFilep->f_path, lastFilep->f_path));
|
||||
curVnode = curRegion->unTypeData.rf.vnode;
|
||||
lastVnode = lastRegion->unTypeData.rf.vnode;
|
||||
} while (curVnode == lastVnode);
|
||||
|
||||
DONE:
|
||||
#ifdef LOSCFG_KERNEL_DYNLOAD
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "user_copy.h"
|
||||
#include "los_vm_filemap.h"
|
||||
#include "los_hash.h"
|
||||
#include "los_vm_common.h"
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
|
@ -2204,6 +2205,207 @@ ERROUT:
|
|||
return -fatfs_2_vfs(res);
|
||||
}
|
||||
|
||||
ssize_t fatfs_readpage(struct Vnode *vnode, char *buff, off_t pos)
|
||||
{
|
||||
FATFS *fs = (FATFS *)(vnode->originMount->data);
|
||||
DIR_FILE *dfp = (DIR_FILE *)(vnode->data);
|
||||
FILINFO *finfo = &(dfp->fno);
|
||||
FAT_ENTRY *ep = &(dfp->fat_entry);
|
||||
DWORD clust;
|
||||
DWORD sclust;
|
||||
QWORD sect;
|
||||
QWORD step;
|
||||
QWORD n;
|
||||
size_t position; /* byte offset */
|
||||
BYTE *buf = (BYTE *)buff;
|
||||
size_t buflen = PAGE_SIZE;
|
||||
FRESULT result;
|
||||
int ret;
|
||||
|
||||
ret = lock_fs(fs);
|
||||
if (ret == FALSE) {
|
||||
result = FR_TIMEOUT;
|
||||
goto ERROR_OUT;
|
||||
}
|
||||
|
||||
if (finfo->fsize <= pos) {
|
||||
result = FR_OK;
|
||||
goto ERROR_UNLOCK;
|
||||
}
|
||||
|
||||
if (ep->clst == 0) {
|
||||
ep->clst = finfo->sclst;
|
||||
}
|
||||
|
||||
if (pos >= ep->pos) {
|
||||
clust = ep->clst;
|
||||
position = ep->pos;
|
||||
} else {
|
||||
clust = finfo->sclst;
|
||||
position = 0;
|
||||
}
|
||||
|
||||
/* Get to the current cluster */
|
||||
n = pos / SS(fs) / fs->csize - position / SS(fs) / fs->csize;
|
||||
while (n--) {
|
||||
clust = get_fat(&(dfp->f_dir.obj), clust);
|
||||
if ((clust == BAD_CLUSTER) || (clust == DISK_ERROR)) {
|
||||
result = FR_DISK_ERR;
|
||||
goto ERROR_UNLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get to the currnet sector */
|
||||
sect = clst2sect(fs, clust);
|
||||
sect += (pos / SS(fs)) & (fs->csize - 1);
|
||||
|
||||
/* How many sectors do we need to read once */
|
||||
if (fs->csize < buflen / SS(fs)) {
|
||||
step = fs->csize;
|
||||
} else {
|
||||
step = buflen / SS(fs);
|
||||
}
|
||||
|
||||
n = 0;
|
||||
sclust = clust;
|
||||
while (n < buflen / SS(fs)) {
|
||||
if (disk_read(fs->pdrv, buf, sect, step) != RES_OK) {
|
||||
result = FR_DISK_ERR;
|
||||
goto ERROR_UNLOCK;
|
||||
}
|
||||
n += step;
|
||||
if (n >= buflen / SS(fs)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* As cluster size is aligned, it must jump to next cluster when cluster size is less than pagesize */
|
||||
clust = get_fat(&(dfp->f_dir.obj), clust);
|
||||
if ((clust == BAD_CLUSTER) || (clust == DISK_ERROR)) {
|
||||
result = FR_DISK_ERR;
|
||||
goto ERROR_UNLOCK;
|
||||
} else if (fatfs_is_last_cluster(fs, clust)) {
|
||||
break; /* read end */
|
||||
}
|
||||
sect = clst2sect(fs, clust);
|
||||
buf += step * SS(fs);
|
||||
}
|
||||
|
||||
ep->clst = sclust;
|
||||
ep->pos = pos;
|
||||
|
||||
unlock_fs(fs, FR_OK);
|
||||
|
||||
return (ssize_t)min(finfo->fsize - pos, n * SS(fs));
|
||||
|
||||
ERROR_UNLOCK:
|
||||
unlock_fs(fs, result);
|
||||
ERROR_OUT:
|
||||
return -fatfs_2_vfs(result);
|
||||
}
|
||||
|
||||
ssize_t fatfs_writepage(struct Vnode *vnode, char *buff, off_t pos, size_t buflen)
|
||||
{
|
||||
FATFS *fs = (FATFS *)(vnode->originMount->data);
|
||||
DIR_FILE *dfp = (DIR_FILE *)(vnode->data);
|
||||
FILINFO *finfo = &(dfp->fno);
|
||||
FAT_ENTRY *ep = &(dfp->fat_entry);
|
||||
DWORD clust;
|
||||
DWORD sclst;
|
||||
QWORD sect;
|
||||
QWORD step;
|
||||
QWORD n;
|
||||
size_t position; /* byte offset */
|
||||
BYTE *buf = (BYTE *)buff;
|
||||
FRESULT result;
|
||||
FIL fil;
|
||||
int ret;
|
||||
|
||||
ret = lock_fs(fs);
|
||||
if (ret == FALSE) {
|
||||
result = FR_TIMEOUT;
|
||||
goto ERROR_OUT;
|
||||
}
|
||||
|
||||
if (finfo->fsize <= pos) {
|
||||
result = FR_OK;
|
||||
goto ERROR_UNLOCK;
|
||||
}
|
||||
|
||||
if (ep->clst == 0) {
|
||||
ep->clst = finfo->sclst;
|
||||
}
|
||||
|
||||
if (pos >= ep->pos) {
|
||||
clust = ep->clst;
|
||||
position = ep->pos;
|
||||
} else {
|
||||
clust = finfo->sclst;
|
||||
position = 0;
|
||||
}
|
||||
|
||||
/* Get to the current cluster */
|
||||
n = pos / SS(fs) / fs->csize - position / SS(fs) / fs->csize;
|
||||
while (n--) {
|
||||
clust = get_fat(&(dfp->f_dir.obj), clust);
|
||||
if ((clust == BAD_CLUSTER) || (clust == DISK_ERROR)) {
|
||||
result = FR_DISK_ERR;
|
||||
goto ERROR_UNLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get to the currnet sector */
|
||||
sect = clst2sect(fs, clust);
|
||||
sect += (pos / SS(fs)) & (fs->csize - 1);
|
||||
|
||||
/* How many sectors do we need to read once */
|
||||
if (fs->csize < buflen / SS(fs)) {
|
||||
step = fs->csize;
|
||||
} else {
|
||||
step = buflen / SS(fs);
|
||||
}
|
||||
|
||||
n = 0;
|
||||
sclst = clust;
|
||||
while (n < buflen / SS(fs)) {
|
||||
if (disk_write(fs->pdrv, buf, sect, step) != RES_OK) {
|
||||
result = FR_DISK_ERR;
|
||||
goto ERROR_UNLOCK;
|
||||
}
|
||||
n += step;
|
||||
if (n >= buflen / SS(fs)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* As cluster size is aligned, it must jump to next cluster when cluster size is less than pagesize */
|
||||
clust = get_fat(&(dfp->f_dir.obj), clust);
|
||||
if ((clust == BAD_CLUSTER) || (clust == DISK_ERROR)) {
|
||||
result = FR_DISK_ERR;
|
||||
goto ERROR_UNLOCK;
|
||||
} else if (fatfs_is_last_cluster(fs, clust)) {
|
||||
break; /* read end */
|
||||
}
|
||||
sect = clst2sect(fs, clust);
|
||||
buf += step * SS(fs);
|
||||
}
|
||||
|
||||
ep->clst = sclst;
|
||||
ep->pos = pos;
|
||||
|
||||
fil.obj.fs = fs;
|
||||
if (update_filbuff(finfo, &fil, NULL) < 0) {
|
||||
result = FR_DISK_ERR;
|
||||
goto ERROR_UNLOCK;
|
||||
}
|
||||
|
||||
unlock_fs(fs, FR_OK);
|
||||
|
||||
return (ssize_t)min(finfo->fsize - pos, n * SS(fs));
|
||||
ERROR_UNLOCK:
|
||||
unlock_fs(fs, result);
|
||||
ERROR_OUT:
|
||||
return -fatfs_2_vfs(result);
|
||||
}
|
||||
|
||||
struct VnodeOps fatfs_vops = {
|
||||
/* file ops */
|
||||
.Getattr = fatfs_stat,
|
||||
|
@ -2211,6 +2413,8 @@ struct VnodeOps fatfs_vops = {
|
|||
.Lookup = fatfs_lookup,
|
||||
.Rename = fatfs_rename,
|
||||
.Create = fatfs_create,
|
||||
.ReadPage = fatfs_readpage,
|
||||
.WritePage = fatfs_writepage,
|
||||
.Unlink = fatfs_unlink,
|
||||
.Reclaim = fatfs_reclaim,
|
||||
.Truncate = fatfs_truncate,
|
||||
|
|
|
@ -41,81 +41,6 @@ extern "C" {
|
|||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* vfs/fs_file_mapping.c ****************************************************/
|
||||
/****************************************************************************
|
||||
* Name: init_file_mapping
|
||||
*
|
||||
* Description:
|
||||
* Init the global management structure of path <-> page_mapping
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
extern UINT32 init_file_mapping(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: add_mapping
|
||||
*
|
||||
* Description:
|
||||
* Create a new path <-> page_mapping mapping and add to global list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
extern void add_mapping(struct file *filep, const char *fullpath);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: find_mapping
|
||||
*
|
||||
* Description:
|
||||
* Find the page_mapping for path in global list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
extern struct page_mapping *find_mapping(const char *path);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: remove_mapping
|
||||
*
|
||||
* Description:
|
||||
* Drop all the page-caches for the file, and then remove mapping between
|
||||
* the file and pagecache.
|
||||
* ex_filp NULL: do not exclude any file, just matching the fullpath;
|
||||
* ex_filp not NULL: exclude it, which means, ex_filp can be open.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
extern int remove_mapping(const char *fullpath);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rename_mapping
|
||||
*
|
||||
* Description:
|
||||
* Rename the mapping from global path <-> page_mapping list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
extern void rename_mapping(const char *src, const char *dst);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: dec_mapping
|
||||
*
|
||||
* Description:
|
||||
* Decrease the refcnt of mapping.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
extern void dec_mapping_nolock(struct page_mapping *mapping);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Name: update_file_path
|
||||
*
|
||||
* Description:
|
||||
* Update the path in file descriptors when do renaming.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
extern int update_file_path(const char *old_path, const char *new_path);
|
||||
|
||||
/**
|
||||
* @ingroup fs
|
||||
* @brief Initializes the vfs filesystem
|
||||
|
|
|
@ -276,7 +276,7 @@ int VfsJffs2Close(struct file *filep)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ssize_t VfsJffs2Read(struct file *filep, char *buffer, size_t bufLen)
|
||||
ssize_t VfsJffs2ReadPage(struct Vnode *vnode, char *buffer, off_t off)
|
||||
{
|
||||
struct jffs2_inode *node = NULL;
|
||||
struct jffs2_inode_info *f = NULL;
|
||||
|
@ -285,6 +285,32 @@ ssize_t VfsJffs2Read(struct file *filep, char *buffer, size_t bufLen)
|
|||
|
||||
LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
|
||||
|
||||
node = (struct jffs2_inode *)vnode->data;
|
||||
f = JFFS2_INODE_INFO(node);
|
||||
c = JFFS2_SB_INFO(node->i_sb);
|
||||
|
||||
off_t pos = min(node->i_size, off);
|
||||
ssize_t len = min(PAGE_SIZE, (node->i_size - pos));
|
||||
ret = jffs2_read_inode_range(c, f, (unsigned char *)buffer, off, len);
|
||||
if (ret) {
|
||||
LOS_MuxUnlock(&g_jffs2FsLock);
|
||||
return ret;
|
||||
}
|
||||
node->i_atime = Jffs2CurSec();
|
||||
|
||||
LOS_MuxUnlock(&g_jffs2FsLock);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
ssize_t VfsJffs2Read(struct file *filep, char *buffer, size_t bufLen)
|
||||
{
|
||||
struct jffs2_inode *node = NULL;
|
||||
struct jffs2_inode_info *f = NULL;
|
||||
struct jffs2_sb_info *c = NULL;
|
||||
int ret;
|
||||
|
||||
LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
|
||||
node = (struct jffs2_inode *)filep->f_vnode->data;
|
||||
f = JFFS2_INODE_INFO(node);
|
||||
c = JFFS2_SB_INFO(node->i_sb);
|
||||
|
@ -293,7 +319,6 @@ ssize_t VfsJffs2Read(struct file *filep, char *buffer, size_t bufLen)
|
|||
off_t len = min(bufLen, (node->i_size - pos));
|
||||
ret = jffs2_read_inode_range(c, f, (unsigned char *)buffer, filep->f_pos, len);
|
||||
if (ret) {
|
||||
PRINTK("VfsJffs2Read(): read_inode_range failed %d\n", ret);
|
||||
LOS_MuxUnlock(&g_jffs2FsLock);
|
||||
return ret;
|
||||
}
|
||||
|
@ -305,6 +330,59 @@ ssize_t VfsJffs2Read(struct file *filep, char *buffer, size_t bufLen)
|
|||
return len;
|
||||
}
|
||||
|
||||
ssize_t VfsJffs2WritePage(struct Vnode *vnode, char *buffer, off_t pos, size_t buflen)
|
||||
{
|
||||
struct jffs2_inode *node = NULL;
|
||||
struct jffs2_inode_info *f = NULL;
|
||||
struct jffs2_sb_info *c = NULL;
|
||||
struct jffs2_raw_inode ri = {0};
|
||||
struct IATTR attr = {0};
|
||||
int ret;
|
||||
uint32_t writtenLen;
|
||||
|
||||
LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
|
||||
|
||||
node = (struct jffs2_inode *)vnode->data;
|
||||
f = JFFS2_INODE_INFO(node);
|
||||
c = JFFS2_SB_INFO(node->i_sb);
|
||||
|
||||
if (pos < 0) {
|
||||
LOS_MuxUnlock(&g_jffs2FsLock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ri.ino = cpu_to_je32(f->inocache->ino);
|
||||
ri.mode = cpu_to_jemode(node->i_mode);
|
||||
ri.uid = cpu_to_je16(node->i_uid);
|
||||
ri.gid = cpu_to_je16(node->i_gid);
|
||||
ri.atime = ri.ctime = ri.mtime = cpu_to_je32(Jffs2CurSec());
|
||||
|
||||
if (pos > node->i_size) {
|
||||
int err;
|
||||
attr.attr_chg_valid = CHG_SIZE;
|
||||
attr.attr_chg_size = pos;
|
||||
err = jffs2_setattr(node, &attr);
|
||||
if (err) {
|
||||
LOS_MuxUnlock(&g_jffs2FsLock);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
ri.isize = cpu_to_je32(node->i_size);
|
||||
|
||||
ret = jffs2_write_inode_range(c, f, &ri, (unsigned char *)buffer, pos, buflen, &writtenLen);
|
||||
if (ret) {
|
||||
node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime);
|
||||
LOS_MuxUnlock(&g_jffs2FsLock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime);
|
||||
|
||||
LOS_MuxUnlock(&g_jffs2FsLock);
|
||||
|
||||
return (ssize_t)writtenLen;
|
||||
}
|
||||
|
||||
ssize_t VfsJffs2Write(struct file *filep, const char *buffer, size_t bufLen)
|
||||
{
|
||||
struct jffs2_inode *node = NULL;
|
||||
|
@ -878,6 +956,8 @@ const struct MountOps jffs_operations = {
|
|||
struct VnodeOps g_jffs2Vops = {
|
||||
.Lookup = VfsJffs2Lookup,
|
||||
.Create = VfsJffs2Create,
|
||||
.ReadPage = VfsJffs2ReadPage,
|
||||
.WritePage = VfsJffs2WritePage,
|
||||
.Rename = VfsJffs2Rename,
|
||||
.Mkdir = VfsJffs2Mkdir,
|
||||
.Getattr = VfsJffs2Stat,
|
||||
|
|
|
@ -71,9 +71,9 @@ static int VnodeListProcess(struct SeqBuf *buf, LIST_HEAD* list)
|
|||
struct Vnode *nextItem = NULL;
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, list, struct Vnode, actFreeEntry) {
|
||||
LosBufPrintf(buf, "%-10p %-10p %-10p %10p 0x%08x %-3d %-4s %-3d %-3d %o\n",
|
||||
LosBufPrintf(buf, "%-10p %-10p %-10p %10p 0x%08x %-3d %-4s %-3d %-3d %-8o\t%s\n",
|
||||
item, item->parent, item->data, item->vop, item->hash, item->useCount,
|
||||
VnodeTypeToStr(item->type), item->gid, item->uid, item->mode);
|
||||
VnodeTypeToStr(item->type), item->gid, item->uid, item->mode, item->filePath);
|
||||
count++;
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ static int PageCacheEntryProcess(struct SeqBuf *buf, struct page_mapping *mappin
|
|||
int total = 0;
|
||||
LosFilePage *fpage = NULL;
|
||||
|
||||
if (mapping == NULL) {
|
||||
if (mapping->nrpages == 0) {
|
||||
LosBufPrintf(buf, "null]\n");
|
||||
return total;
|
||||
}
|
||||
|
@ -119,18 +119,18 @@ static int PageCacheEntryProcess(struct SeqBuf *buf, struct page_mapping *mappin
|
|||
|
||||
static int PageCacheMapProcess(struct SeqBuf *buf)
|
||||
{
|
||||
struct file_map *mapList = GetFileMappingList();
|
||||
char *name = NULL;
|
||||
struct file_map *curMap = NULL;
|
||||
LIST_HEAD *vnodeList = GetVnodeActiveList();
|
||||
struct page_mapping *mapping = NULL;
|
||||
struct Vnode *vnode = NULL;
|
||||
int total = 0;
|
||||
|
||||
(VOID)LOS_MuxLock(&mapList->lock, LOS_WAIT_FOREVER);
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(curMap, &mapList->head, struct file_map, head) {
|
||||
name = curMap->rename ? curMap->rename: curMap->owner;
|
||||
LosBufPrintf(buf, "%s:[", name);
|
||||
total += PageCacheEntryProcess(buf, &curMap->mapping);
|
||||
VnodeHold();
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(vnode, vnodeList, struct Vnode, actFreeEntry) {
|
||||
mapping = &vnode->mapping;
|
||||
LosBufPrintf(buf, "%p, %s:[", vnode, vnode->filePath);
|
||||
total += PageCacheEntryProcess(buf, mapping);
|
||||
}
|
||||
(VOID)LOS_MuxUnlock(&mapList->lock);
|
||||
VnodeDrop();
|
||||
return total;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ kernel_module(module_name) {
|
|||
"operation/vfs_fallocate.c",
|
||||
"operation/vfs_fallocate64.c",
|
||||
"operation/vfs_fcntl.c",
|
||||
"operation/vfs_file_mapping.c",
|
||||
"operation/vfs_force_umount.c",
|
||||
"operation/vfs_init.c",
|
||||
"operation/vfs_other.c",
|
||||
|
|
|
@ -125,12 +125,16 @@ struct Vnode {
|
|||
LIST_ENTRY actFreeEntry; /* vnode active/free list entry */
|
||||
struct Mount *originMount; /* fs info about this vnode */
|
||||
struct Mount *newMount; /* fs info about who mount on this vnode */
|
||||
char *filePath; /* file path of the vnode */
|
||||
struct page_mapping mapping; /* page mapping of the vnode */
|
||||
};
|
||||
|
||||
struct VnodeOps {
|
||||
int (*Create)(struct Vnode *parent, const char *name, int mode, struct Vnode **vnode);
|
||||
int (*Lookup)(struct Vnode *parent, const char *name, int len, struct Vnode **vnode);
|
||||
int (*Open)(struct Vnode *vnode, int fd, int mode, int flags);
|
||||
ssize_t (*ReadPage)(struct Vnode *vnode, char *buffer, off_t pos);
|
||||
ssize_t (*WritePage)(struct Vnode *vnode, char *buffer, off_t pos, size_t buflen);
|
||||
int (*Close)(struct Vnode *vnode);
|
||||
int (*Reclaim)(struct Vnode *vnode);
|
||||
int (*Unlink)(struct Vnode *parent, struct Vnode *vnode, const char *fileName);
|
||||
|
|
|
@ -1,303 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fs/file.h"
|
||||
#include "fs/file.h"
|
||||
#include "fs/fs_operation.h"
|
||||
#include "unistd.h"
|
||||
#include "los_mux.h"
|
||||
#include "los_list.h"
|
||||
#include "los_atomic.h"
|
||||
#include "los_vm_filemap.h"
|
||||
|
||||
#ifdef LOSCFG_KERNEL_VM
|
||||
|
||||
static struct file_map g_file_mapping = {0};
|
||||
|
||||
uint init_file_mapping()
|
||||
{
|
||||
uint ret;
|
||||
|
||||
LOS_ListInit(&g_file_mapping.head);
|
||||
|
||||
ret = LOS_MuxInit(&g_file_mapping.lock, NULL);
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_ERR("Create mutex for file map of page cache failed, (ret=%u)\n", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void clear_file_mapping(const struct page_mapping *mapping)
|
||||
{
|
||||
unsigned int i = 3; /* file start fd */
|
||||
struct file *filp = NULL;
|
||||
|
||||
while (i < CONFIG_NFILE_DESCRIPTORS) {
|
||||
filp = &tg_filelist.fl_files[i];
|
||||
if (filp->f_mapping == mapping) {
|
||||
filp->f_mapping = NULL;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static struct page_mapping *find_mapping_nolock(const char *fullpath)
|
||||
{
|
||||
char *map_name = NULL;
|
||||
struct file_map *fmap = NULL;
|
||||
int name_len = strlen(fullpath);
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(fmap, &g_file_mapping.head, struct file_map, head) {
|
||||
map_name = fmap->rename ? fmap->rename: fmap->owner;
|
||||
if ((name_len == fmap->name_len) && !strcmp(map_name, fullpath)) {
|
||||
return &fmap->mapping;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void add_mapping(struct file *filep, const char *fullpath)
|
||||
{
|
||||
int path_len;
|
||||
status_t retval;
|
||||
struct file_map *fmap = NULL;
|
||||
struct page_mapping *mapping = NULL;
|
||||
|
||||
if (filep == NULL || fullpath == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
|
||||
mapping = find_mapping_nolock(fullpath);
|
||||
if (mapping) {
|
||||
LOS_AtomicInc(&mapping->ref);
|
||||
filep->f_mapping = mapping;
|
||||
mapping->host = filep;
|
||||
goto out;
|
||||
}
|
||||
|
||||
path_len = strlen(fullpath);
|
||||
|
||||
fmap = (struct file_map *)zalloc(sizeof(struct file_map) + path_len + 1);
|
||||
if (!fmap) {
|
||||
PRINT_WARN("%s %d, Mem alloc failed.\n", __FUNCTION__, __LINE__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
LOS_AtomicSet(&fmap->mapping.ref, 1);
|
||||
|
||||
fmap->name_len = path_len;
|
||||
(void)strcpy_s(fmap->owner, path_len + 1, fullpath);
|
||||
|
||||
LOS_ListInit(&fmap->mapping.page_list);
|
||||
LOS_SpinInit(&fmap->mapping.list_lock);
|
||||
retval = LOS_MuxInit(&fmap->mapping.mux_lock, NULL);
|
||||
if (retval != LOS_OK) {
|
||||
PRINT_ERR("%s %d, Create mutex for mapping.mux_lock failed, status: %d\n", __FUNCTION__, __LINE__, retval);
|
||||
goto out;
|
||||
}
|
||||
|
||||
LOS_ListTailInsert(&g_file_mapping.head, &fmap->head);
|
||||
|
||||
filep->f_mapping = &fmap->mapping;
|
||||
filep->f_mapping->host = filep;
|
||||
|
||||
out:
|
||||
(VOID)LOS_MuxUnlock(&g_file_mapping.lock);
|
||||
}
|
||||
|
||||
int remove_mapping_nolock(struct page_mapping *mapping)
|
||||
{
|
||||
struct file_map *fmap = NULL;
|
||||
|
||||
if (mapping == NULL) {
|
||||
set_errno(EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxDestroy(&mapping->mux_lock);
|
||||
clear_file_mapping(mapping);
|
||||
OsFileCacheRemove(mapping);
|
||||
fmap = LOS_DL_LIST_ENTRY(mapping, struct file_map, mapping);
|
||||
LOS_ListDelete(&fmap->head);
|
||||
if (fmap->rename) {
|
||||
LOS_MemFree(m_aucSysMem0, fmap->rename);
|
||||
}
|
||||
LOS_MemFree(m_aucSysMem0, fmap);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void dec_mapping_nolock(struct page_mapping *mapping)
|
||||
{
|
||||
if (mapping == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
|
||||
if (LOS_AtomicRead(&mapping->ref) > 0) {
|
||||
LOS_AtomicDec(&mapping->ref);
|
||||
}
|
||||
|
||||
if (LOS_AtomicRead(&mapping->ref) <= 0) {
|
||||
remove_mapping_nolock(mapping);
|
||||
} else {
|
||||
OsFileCacheFlush(mapping);
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxUnlock(&g_file_mapping.lock);
|
||||
}
|
||||
|
||||
int remove_mapping(const char *fullpath)
|
||||
{
|
||||
int ret;
|
||||
struct filelist *f_list = NULL;
|
||||
struct page_mapping *mapping = NULL;
|
||||
|
||||
f_list = &tg_filelist;
|
||||
ret = sem_wait(&f_list->fl_sem);
|
||||
if (ret < 0) {
|
||||
PRINTK("sem_wait error, ret=%d\n", ret);
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
|
||||
|
||||
mapping = find_mapping_nolock(fullpath);
|
||||
if (mapping) {
|
||||
ret = remove_mapping_nolock(mapping);
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxUnlock(&g_file_mapping.lock);
|
||||
|
||||
(void)sem_post(&f_list->fl_sem);
|
||||
return OK;
|
||||
}
|
||||
|
||||
void rename_mapping(const char *src_path, const char *dst_path)
|
||||
{
|
||||
int ret;
|
||||
char *tmp = NULL;
|
||||
int path_len;
|
||||
struct file_map *fmap = NULL;
|
||||
struct page_mapping *mapping = NULL;
|
||||
|
||||
if (src_path == NULL || dst_path == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
path_len = strlen(dst_path);
|
||||
|
||||
/* protect the whole list in case of this node been deleted just after we found it */
|
||||
|
||||
(VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
|
||||
|
||||
mapping = find_mapping_nolock(src_path);
|
||||
if (!mapping) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
fmap = LOS_DL_LIST_ENTRY(mapping, struct file_map, mapping);
|
||||
|
||||
tmp = LOS_MemAlloc(m_aucSysMem0, path_len + 1);
|
||||
if (!tmp) {
|
||||
PRINT_ERR("%s-%d: Mem alloc failed, path length(%d)\n", __FUNCTION__, __LINE__, path_len);
|
||||
goto out;
|
||||
}
|
||||
ret = strncpy_s(tmp, path_len, dst_path, strlen(dst_path));
|
||||
if (ret != 0) {
|
||||
(VOID)LOS_MemFree(m_aucSysMem0, tmp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp[path_len] = '\0';
|
||||
fmap->rename = tmp;
|
||||
|
||||
out:
|
||||
(VOID)LOS_MuxUnlock(&g_file_mapping.lock);
|
||||
}
|
||||
|
||||
int update_file_path(const char *old_path, const char *new_path)
|
||||
{
|
||||
struct filelist *f_list = NULL;
|
||||
struct file *filp = NULL;
|
||||
int ret;
|
||||
|
||||
f_list = &tg_filelist;
|
||||
ret = sem_wait(&f_list->fl_sem);
|
||||
if (ret < 0) {
|
||||
PRINTK("sem_wait error, ret=%d\n", ret);
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
|
||||
for (int i = 3; i < CONFIG_NFILE_DESCRIPTORS; i++) {
|
||||
if (!get_bit(i)) {
|
||||
continue;
|
||||
}
|
||||
filp = &tg_filelist.fl_files[i];
|
||||
if (filp->f_path == NULL || strcmp(filp->f_path, old_path)) {
|
||||
continue;
|
||||
}
|
||||
int len = strlen(new_path) + 1;
|
||||
char *tmp_path = LOS_MemAlloc(m_aucSysMem0, len);
|
||||
if (tmp_path == NULL) {
|
||||
PRINT_ERR("%s-%d: Mem alloc failed, path length(%d)\n", __FUNCTION__, __LINE__, len);
|
||||
ret = VFS_ERROR;
|
||||
goto out;
|
||||
}
|
||||
ret = strncpy_s(tmp_path, strlen(new_path) + 1, new_path, len);
|
||||
if (ret != 0) {
|
||||
(VOID)LOS_MemFree(m_aucSysMem0, tmp_path);
|
||||
PRINT_ERR("%s-%d: strcpy failed.\n", __FUNCTION__, __LINE__);
|
||||
ret = VFS_ERROR;
|
||||
goto out;
|
||||
}
|
||||
free(filp->f_path);
|
||||
filp->f_path = tmp_path;
|
||||
}
|
||||
ret = LOS_OK;
|
||||
|
||||
out:
|
||||
(VOID)LOS_MuxUnlock(&g_file_mapping.lock);
|
||||
(void)sem_post(&f_list->fl_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_DEBUG_VERSION
|
||||
struct file_map* GetFileMappingList(void)
|
||||
{
|
||||
return &g_file_mapping;
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -79,14 +79,7 @@ void los_vfs_init(void)
|
|||
PRINT_ERR("los_vfs_init VnodeDevInit failed error %d\n", retval);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_KERNEL_VM
|
||||
retval = init_file_mapping();
|
||||
if (retval != LOS_OK) {
|
||||
PRINT_ERR("Page cache file map init failed\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
g_vfs_init = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ int VnodesInit(void)
|
|||
}
|
||||
g_rootVnode->mode = S_IRWXU | S_IRWXG | S_IRWXO | S_IFDIR;
|
||||
g_rootVnode->type = VNODE_TYPE_DIR;
|
||||
g_rootVnode->filePath = "/";
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
@ -155,6 +156,11 @@ int VnodeAlloc(struct VnodeOps *vop, struct Vnode **newVnode)
|
|||
LOS_ListTailInsert(&g_vnodeActiveList, &(vnode->actFreeEntry));
|
||||
vnode->vop = vop;
|
||||
}
|
||||
LOS_ListInit(&vnode->mapping.page_list);
|
||||
LOS_SpinInit(&vnode->mapping.list_lock);
|
||||
(VOID)LOS_MuxInit(&vnode->mapping.mux_lock, NULL);
|
||||
vnode->mapping.host = vnode;
|
||||
|
||||
VnodeDrop();
|
||||
|
||||
*newVnode = vnode;
|
||||
|
@ -182,6 +188,9 @@ int VnodeFree(struct Vnode *vnode)
|
|||
vnode->vop->Reclaim(vnode);
|
||||
}
|
||||
|
||||
if (vnode->filePath) {
|
||||
free(vnode->filePath);
|
||||
}
|
||||
if (vnode->vop == &g_devfsOps) {
|
||||
/* for dev vnode, just free it */
|
||||
free(vnode->data);
|
||||
|
@ -363,6 +372,8 @@ STEP_FINISH:
|
|||
int VnodeLookupAt(const char *path, struct Vnode **result, uint32_t flags, struct Vnode *orgVnode)
|
||||
{
|
||||
int ret;
|
||||
int vnodePathLen;
|
||||
char *vnodePath = NULL;
|
||||
struct Vnode *startVnode = NULL;
|
||||
char *normalizedPath = NULL;
|
||||
|
||||
|
@ -391,7 +402,10 @@ int VnodeLookupAt(const char *path, struct Vnode **result, uint32_t flags, struc
|
|||
if (currentDir == NULL || *currentDir == '\0') {
|
||||
// return target or parent vnode as result
|
||||
*result = currentVnode;
|
||||
goto OUT_FREE_PATH;
|
||||
if (currentVnode->filePath == NULL) {
|
||||
currentVnode->filePath = normalizedPath;
|
||||
}
|
||||
return ret;
|
||||
} else if (VfsVnodePermissionCheck(currentVnode, EXEC_OP)) {
|
||||
ret = -EACCES;
|
||||
goto OUT_FREE_PATH;
|
||||
|
@ -401,13 +415,29 @@ int VnodeLookupAt(const char *path, struct Vnode **result, uint32_t flags, struc
|
|||
// no such file, lookup failed
|
||||
goto OUT_FREE_PATH;
|
||||
}
|
||||
if (currentVnode->filePath == NULL) {
|
||||
vnodePathLen = currentDir - normalizedPath;
|
||||
vnodePath = malloc(vnodePathLen + 1);
|
||||
if (vnodePath == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto OUT_FREE_PATH;
|
||||
}
|
||||
ret = strncpy_s(vnodePath, vnodePathLen + 1, normalizedPath, vnodePathLen);
|
||||
if (ret != EOK) {
|
||||
ret = -ENAMETOOLONG;
|
||||
free(vnodePath);
|
||||
goto OUT_FREE_PATH;
|
||||
}
|
||||
currentVnode->filePath = vnodePath;
|
||||
currentVnode->filePath[vnodePathLen] = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
OUT_FREE_PATH:
|
||||
if (normalizedPath) {
|
||||
free(normalizedPath);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -534,6 +564,9 @@ int VnodeCreate(struct Vnode *parent, const char *name, int mode, struct Vnode *
|
|||
newVnode->uid = parent->uid;
|
||||
newVnode->gid = parent->gid;
|
||||
newVnode->mode = mode;
|
||||
/* The 'name' here is not full path, but for device we don't depend on this path, it's just a name for DFx.
|
||||
When we have devfs, we can get a fullpath. */
|
||||
newVnode->filePath = strdup(name);
|
||||
|
||||
*vnode = newVnode;
|
||||
return 0;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1044,39 +1044,24 @@ STATIC INT32 OsConsoleFileInit(CONSOLE_CB *consoleCB)
|
|||
INT32 ret;
|
||||
struct Vnode *vnode = NULL;
|
||||
struct file *filep = NULL;
|
||||
CHAR *fullpath = NULL;
|
||||
|
||||
ret = vfs_normalize_path(NULL, consoleCB->name, &fullpath);
|
||||
if (ret < 0) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
VnodeHold();
|
||||
ret = VnodeLookup(fullpath, &vnode, 0);
|
||||
ret = VnodeLookup(consoleCB->name, &vnode, 0);
|
||||
if (ret != LOS_OK) {
|
||||
ret = EACCES;
|
||||
goto ERROUT_WITH_FULLPATH;
|
||||
goto ERROUT;
|
||||
}
|
||||
|
||||
consoleCB->fd = files_allocate(vnode, O_RDWR, (off_t)0, consoleCB, STDERR_FILENO + 1);
|
||||
if (consoleCB->fd < 0) {
|
||||
filep = files_allocate(vnode, O_RDWR, 0, consoleCB, FILE_START_FD);
|
||||
if (filep == NULL) {
|
||||
ret = EMFILE;
|
||||
goto ERROUT_WITH_FULLPATH;
|
||||
goto ERROUT;
|
||||
}
|
||||
|
||||
ret = fs_getfilep(consoleCB->fd, &filep);
|
||||
if (ret < 0) {
|
||||
ret = EPERM;
|
||||
goto ERROUT_WITH_FULLPATH;
|
||||
}
|
||||
filep->f_path = fullpath;
|
||||
filep->ops = (struct file_operations_vfs *)((struct drv_data *)vnode->data)->ops;
|
||||
VnodeDrop();
|
||||
return LOS_OK;
|
||||
consoleCB->fd = filep->fd;
|
||||
|
||||
ERROUT_WITH_FULLPATH:
|
||||
ERROUT:
|
||||
VnodeDrop();
|
||||
free(fullpath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -526,7 +526,7 @@ STATIC INT32 OsMmapELFFile(INT32 procfd, const LD_ELF_PHDR *elfPhdr, const LD_EL
|
|||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsLoadInterpBinary(const ELFLoadInfo *loadInfo, UINTPTR *interpMapBase)
|
||||
STATIC INT32 OsLoadInterpBinary(ELFLoadInfo *loadInfo, UINTPTR *interpMapBase)
|
||||
{
|
||||
UINTPTR loadBase = 0;
|
||||
UINT32 mapSize;
|
||||
|
@ -542,10 +542,11 @@ STATIC INT32 OsLoadInterpBinary(const ELFLoadInfo *loadInfo, UINTPTR *interpMapB
|
|||
interpMapBase, mapSize, &loadBase);
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
OsELFClose(loadInfo->interpInfo.procfd);
|
||||
loadInfo->interpInfo.procfd = INVALID_FD;
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC CHAR *OsGetParamPtr(CHAR * const *ptr, INT32 index)
|
||||
|
@ -929,6 +930,8 @@ STATIC INT32 OsLoadELFSegment(ELFLoadInfo *loadInfo)
|
|||
|
||||
ret = OsMmapELFFile(loadInfo->execInfo.procfd, loadInfo->execInfo.elfPhdr, &loadInfo->execInfo.elfEhdr,
|
||||
&loadInfo->loadAddr, mapSize, &loadBase);
|
||||
OsELFClose(loadInfo->execInfo.procfd);
|
||||
loadInfo->execInfo.procfd = INVALID_FD;
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
|
||||
return ret;
|
||||
|
|
Loading…
Reference in New Issue