提交 78b01f7d 编写于 作者: 鸿蒙内核源码分析's avatar 鸿蒙内核源码分析

开始对VFS模块代码注释,从进程文件管理器切入 process->files

鸿蒙内核源码分析系列 【 CSDN | OSCHINA | WIKI 】
鸿蒙内核源码注释中文版 【 CSDN仓 | Gitee仓 | Github仓 | Coding仓 】四大仓库每日同步更新代码和wiki
项目给鸿蒙内核源码逐行加上中文注解,详细阐述框架和代码细节, 精读 HarmonyOS 内核源码, 将迅速拔高对计算机整体理解,从此高屋建瓴看问题.
上级 08353dc2
......@@ -40,7 +40,7 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//从用户空间拷贝
size_t arch_copy_from_user(void *dst, const void *src, size_t len)
{
return LOS_ArchCopyFromUser(dst, src, len);
......@@ -48,68 +48,68 @@ size_t arch_copy_from_user(void *dst, const void *src, size_t len)
size_t LOS_ArchCopyFromUser(void *dst, const void *src, size_t len)
{
if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)src, len)) {
if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)src, len)) {//[src,src+len]在内核空间
return len;
}
return _arm_user_copy(dst, src, len);
return _arm_user_copy(dst, src, len);//完成从用户空间到内核空间的拷贝
}
//拷贝到用户空间
size_t arch_copy_to_user(void *dst, const void *src, size_t len)
{
return LOS_ArchCopyToUser(dst, src, len);
return LOS_ArchCopyToUser(dst, src, len);//
}
size_t LOS_ArchCopyToUser(void *dst, const void *src, size_t len)
{//先判断地址是不是在用户空间
if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)dst, len)) {
if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)dst, len)) {//[dst,dst+len]在内核空间
return len;
}
return _arm_user_copy(dst, src, len);
return _arm_user_copy(dst, src, len);//完成从内核空间到用户空间的拷贝
}
//将内核数据拷贝到用户空间
INT32 LOS_CopyFromKernel(VOID *dest, UINT32 max, const VOID *src, UINT32 count)
{
INT32 ret;
if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)dest, count)) {
if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)dest, count)) {//[dest,dest+count] 在内核空间的情况
ret = memcpy_s(dest, max, src, count);
} else {
ret = ((max >= count) ? _arm_user_copy(dest, src, count) : ERANGE_AND_RESET);
} else {//[dest,dest+count] 在用户空间
ret = ((max >= count) ? _arm_user_copy(dest, src, count) : ERANGE_AND_RESET);//用户空间copy
}
return ret;
}
//将用户空间的数据拷贝到内核空间
INT32 LOS_CopyToKernel(VOID *dest, UINT32 max, const VOID *src, UINT32 count)
{
INT32 ret;
if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)src, count)) {
if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)src, count)) {//[src,src+count] 在内核空间的情况
ret = memcpy_s(dest, max, src, count);
} else {
} else {//[src,src+count] 在内核空间的情况
ret = ((max >= count) ? _arm_user_copy(dest, src, count) : ERANGE_AND_RESET);
}
return ret;
}
//清除用户空间
INT32 LOS_UserMemClear(unsigned char *buf, UINT32 len)
{
INT32 ret = 0;
if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, len)) {
(VOID)memset_s(buf, len, 0, len);
if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, len)) {//内核空间的情况
(VOID)memset_s(buf, len, 0, len);//清0
} else {
unsigned char *tmp = (unsigned char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, len);
unsigned char *tmp = (unsigned char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, len);//1.在内核申请内存
if (tmp == NULL) {
return -ENOMEM;
}
(VOID)memset_s(tmp, len, 0, len);
if (_arm_user_copy(buf, tmp, len) != 0) {
ret = -EFAULT;
(VOID)memset_s(tmp, len, 0, len);//2.清0
if (_arm_user_copy(buf, tmp, len) != 0) {//这个清空有点意思,此时内核存钱清0了,再将0拷贝至用户内存
ret = -EFAULT; //不能直接将用户空间清0吗?要这么绕一圈 @note_thinking
}
LOS_MemFree(OS_SYS_MEM_ADDR, tmp);
LOS_MemFree(OS_SYS_MEM_ADDR, tmp);//释放内核空间
}
return ret;
}
......
......@@ -37,27 +37,37 @@
#include <semaphore.h>
#include "linux/spinlock.h"
/****************************************************************************
fd 文件描述符(file descriptor)为了高效管理已被打开的文件所创建的索引。本质上就是一个非负整数
当应用程序请求内核打开/新建一个文件时,内核会返回一个文件描述符用于对应这个打开/新建的文件,
读写文件也是需要使用这个文件描述符来指定待读写的文件的。
在鸿蒙系统中,所有的文件操作,都是通过fd来定位资源和状态的
****************************************************************************/
/* open file table for process fd */
struct file_table_s {
signed short sysFd; /* system fd associate with the tg_filelist index */
signed short sysFd; /* system fd associate with the tg_filelist index */ //与tg_filelist索引关联的系统fd
};
struct fd_table_s {
struct fd_table_s {//fd表结构体
unsigned int max_fds;
struct file_table_s *ft_fds; /* process fd array associate with system fd */
fd_set *open_fds;
struct file_table_s *ft_fds; /* process fd array associate with system fd *///进程的FD数组,与系统fd相关联
fd_set *open_fds;
fd_set *proc_fds;
sem_t ft_sem; /* manage access to the file table */
sem_t ft_sem; /* manage access to the file table */ //管理对文件表的访问
};
struct files_struct {
int count;
struct fd_table_s *fdt;
unsigned int file_lock;
unsigned int next_fd;
//files_struct 一般用于进程 process->files
struct files_struct {//进程文件表结构体
int count; //持有的文件数量
struct fd_table_s *fdt; //持有的文件表
unsigned int file_lock; //文件互斥锁
unsigned int next_fd; //下一个fd
#ifdef VFS_USING_WORKDIR
spinlock_t workdir_lock;
char workdir[PATH_MAX];
spinlock_t workdir_lock; //工作区目录自旋锁
char workdir[PATH_MAX]; //工作区路径
#endif
};
......
......@@ -70,17 +70,17 @@ static int AssignProcessFd(const struct fd_table_s *fdt, int minFd)
return VFS_ERROR;
}
//获取FD表
static struct fd_table_s *GetFdTable(void)
{
struct fd_table_s *fdt = NULL;
struct files_struct *procFiles = OsCurrProcessGet()->files;
struct files_struct *procFiles = OsCurrProcessGet()->files;//获取当前进程的文件管理器
if (procFiles == NULL) {
return NULL;
}
fdt = procFiles->fdt;
fdt = procFiles->fdt;//返回这个fdt
if ((fdt == NULL) || (fdt->ft_fds == NULL)) {
return NULL;
}
......
......@@ -37,36 +37,71 @@
#include "los_list.h"
#include "los_atomic.h"
#include "los_vm_filemap.h"
/******************************************************************
定义见于 ..\third_party\NuttX\include\nuttx\fs\fs.h
typedef volatile INT32 Atomic;
struct page_mapping {
LOS_DL_LIST page_list; /* all pages * /
SPIN_LOCK_S list_lock; /* lock protecting it * /
LosMux mux_lock; /* mutex lock * /
unsigned long nrpages; /* number of total pages * /
unsigned long flags;
Atomic ref; /* reference counting * /
struct file *host; /* owner of this mapping * /
};
/* map: full_path(owner) <-> mapping * /
struct file_map {
LOS_DL_LIST head; //挂入文件链表的节点
LosMux lock; /* lock to protect this mapping * /
struct page_mapping mapping; //映射内容区
char *owner; /* owner: full path of file * /
};
struct file
{
unsigned int f_magicnum; /* file magic number * /
int f_oflags; /* Open mode flags * /
FAR struct inode *f_inode; /* Driver interface * /
loff_t f_pos; /* File position * /
unsigned long f_refcount; /* reference count * /
char *f_path; /* File fullpath * /
void *f_priv; /* Per file driver private data * /
const char *f_relpath; /* realpath * /
struct page_mapping *f_mapping; /* mapping file to memory * /
void *f_dir; /* DIR struct for iterate the directory if open a directory * /
};
******************************************************************/
static struct file_map g_file_mapping = {0};
//初始化文件映射
uint init_file_mapping()
{
uint ret;
LOS_ListInit(&g_file_mapping.head);
LOS_ListInit(&g_file_mapping.head);//初始化文件映射的链表
ret = LOS_MuxInit(&g_file_mapping.lock, NULL);
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 struct page_mapping *find_mapping_nolock(const char *fullpath)
{
struct file_map *fmap = NULL;
LOS_DL_LIST_FOR_EACH_ENTRY(fmap, &g_file_mapping.head, struct file_map, head) {
if (!strcmp(fmap->owner, fullpath)) {
LOS_DL_LIST_FOR_EACH_ENTRY(fmap, &g_file_mapping.head, struct file_map, head) {//遍历文件映射链表
if (!strcmp(fmap->owner, fullpath)) {//对比文件路径
return &fmap->mapping;
}
}
return NULL;
}
//添加一个文件映射
void add_mapping(struct file *filep, const char *fullpath)
{
void *tmp = NULL;
......@@ -80,30 +115,30 @@ void add_mapping(struct file *filep, const char *fullpath)
return;
}
(VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
(VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);//操作临界区,先拿锁
path_len = strlen(fullpath) + 1;
mapping = find_mapping_nolock(fullpath);
if (mapping) {
LOS_AtomicInc(&mapping->ref);
filep->f_mapping = mapping;
mapping = find_mapping_nolock(fullpath);//先看有米有映射过
if (mapping) {//有映射过的情况
LOS_AtomicInc(&mapping->ref);//引用自增
filep->f_mapping = mapping;//赋值
mapping->host = filep;
(VOID)LOS_MuxUnlock(&g_file_mapping.lock);
return;
(VOID)LOS_MuxUnlock(&g_file_mapping.lock);//释放锁
return;//收工
}
(VOID)LOS_MuxUnlock(&g_file_mapping.lock);
(VOID)LOS_MuxUnlock(&g_file_mapping.lock);//没有映射过的情况下 先释放锁
fmap = (struct file_map *)LOS_MemAlloc(m_aucSysMem0, fmap_len);
fmap = (struct file_map *)LOS_MemAlloc(m_aucSysMem0, fmap_len);//分配一个file_map
/* page-cache as a optimization feature, just return when out of memory */
/* page-cache as a optimization feature, just return when out of memory *///页面缓存作为一个优化功能,当内存不足时返回
if (!fmap) {
PRINT_WARN("%s-%d: Mem alloc failed. fmap length(%d)\n",
__FUNCTION__, __LINE__, fmap_len);
return;
}
tmp = LOS_MemAlloc(m_aucSysMem0, path_len);
tmp = LOS_MemAlloc(m_aucSysMem0, path_len);//分配一块内存放文件路径,为什么要这么做?因为需要在内核区操作,而参数路径在用户区
/* page-cache as a optimization feature, just return when out of memory */
......@@ -114,27 +149,27 @@ void add_mapping(struct file *filep, const char *fullpath)
return;
}
(void)memset_s(fmap, fmap_len, 0, fmap_len);
fmap->owner = tmp;
LOS_AtomicSet(&fmap->mapping.ref, 1);
(void)strcpy_s(fmap->owner, path_len, fullpath);
(void)memset_s(fmap, fmap_len, 0, fmap_len);//清0
fmap->owner = tmp;//赋值,此时owner指向内核区
LOS_AtomicSet(&fmap->mapping.ref, 1);//引用设为1
(void)strcpy_s(fmap->owner, path_len, fullpath);//从用户区 拷贝到内核区
LOS_ListInit(&fmap->mapping.page_list);
LOS_SpinInit(&fmap->mapping.list_lock);
retval = LOS_MuxInit(&fmap->mapping.mux_lock, NULL);
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);
}
(VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
LOS_ListTailInsert(&g_file_mapping.head, &fmap->head);
(VOID)LOS_MuxUnlock(&g_file_mapping.lock);
(VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);//先拿全局变量g_file_mapping的互斥锁
LOS_ListTailInsert(&g_file_mapping.head, &fmap->head);//因为要将本次文件挂上去
(VOID)LOS_MuxUnlock(&g_file_mapping.lock);//释放锁
filep->f_mapping = &fmap->mapping;
filep->f_mapping->host = filep;
filep->f_mapping = &fmap->mapping;//映射互绑操作,都是自己人了,
filep->f_mapping->host = filep;//文件互绑操作,亲上加亲了。
return;
}
//查找文件映射
struct page_mapping *find_mapping(const char *fullpath)
{
struct page_mapping *mapping = NULL;
......@@ -145,16 +180,16 @@ struct page_mapping *find_mapping(const char *fullpath)
(VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
mapping = find_mapping_nolock(fullpath);
if (mapping) {
LOS_AtomicInc(&mapping->ref);
mapping = find_mapping_nolock(fullpath);//找去
if (mapping) {//找到
LOS_AtomicInc(&mapping->ref);//引用自增
}
(VOID)LOS_MuxUnlock(&g_file_mapping.lock);
return mapping;
}
//引用递减
void dec_mapping(struct page_mapping *mapping)
{
if (mapping == NULL) {
......@@ -163,25 +198,25 @@ void dec_mapping(struct page_mapping *mapping)
(VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
if (LOS_AtomicRead(&mapping->ref) > 0) {
LOS_AtomicDec(&mapping->ref);
LOS_AtomicDec(&mapping->ref);//ref 递减
}
(VOID)LOS_MuxUnlock(&g_file_mapping.lock);
}
//清除文件映射,无锁方式
void clear_file_mapping_nolock(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;
while (i < CONFIG_NFILE_DESCRIPTORS) {//循环遍历查找
filp = &tg_filelist.fl_files[i];//一个个来
if (filp->f_mapping == mapping) {//发现一样
filp->f_mapping = NULL;//直接NULL,注意这里并没有break,而是继续撸到最后,这里如果break了会怎样? @note_thinking
}
i++;
}
}
//删除一个映射
int remove_mapping_nolock(const char *fullpath, const struct file *ex_filp)
{
int fd;
......@@ -198,11 +233,11 @@ int remove_mapping_nolock(const char *fullpath, const struct file *ex_filp)
/* file start fd */
for (fd = 3; fd < CONFIG_NFILE_DESCRIPTORS; fd++) {
node = files_get_openfile(fd);
node = files_get_openfile(fd);//通过文件句柄获取inode
if (node == NULL) {
continue;
}
filp = &tg_filelist.fl_files[fd];
filp = &tg_filelist.fl_files[fd];//拿到文件
/* ex_filp NULL: do not exclude any file, just matching the file name ; ex_filp not NULL: exclude it.
* filp != ex_filp includes the two scenarios.
......@@ -230,11 +265,11 @@ int remove_mapping_nolock(const char *fullpath, const struct file *ex_filp)
}
(VOID)LOS_MuxDestroy(&mapping->mux_lock);
clear_file_mapping_nolock(mapping);
OsFileCacheRemove(mapping);
clear_file_mapping_nolock(mapping);//清除自己
OsFileCacheRemove(mapping);//从缓存中删除自己
fmap = LOS_DL_LIST_ENTRY(mapping,
struct file_map, mapping);
LOS_ListDelete(&fmap->head);
struct file_map, mapping);//找到自己的inode
LOS_ListDelete(&fmap->head);//从链表中摘除自己
LOS_MemFree(m_aucSysMem0, fmap);
out:
......@@ -242,22 +277,22 @@ out:
return OK;
}
//删除文件映射
int remove_mapping(const char *fullpath, const struct file *ex_filp)
{
int ret;
struct filelist *f_list = NULL;
f_list = &tg_filelist;
ret = sem_wait(&f_list->fl_sem);
ret = sem_wait(&f_list->fl_sem);//等待信号量
if (ret < 0) {
PRINTK("sem_wait error, ret=%d\n", ret);
return VFS_ERROR;
}
ret = remove_mapping_nolock(fullpath, ex_filp);
ret = remove_mapping_nolock(fullpath, ex_filp);//调用删除实体
(void)sem_post(&f_list->fl_sem);
(void)sem_post(&f_list->fl_sem);//发出信号量
return OK;
}
......
......@@ -37,8 +37,39 @@
#include "sys/statfs.h"
#include "linux/spinlock.h"
#include "disk_pri.h"
//VFS是Virtual File System(虚拟文件系统)的缩写,它不是一个实际的文件系统,而是一个异构文件系统之上的软件粘合层
//虚拟文件系统初始化 los_vfs_init()只能调用一次,多次调用将会造成文件系统异常
/************************************************************************
VFS是Virtual File System(虚拟文件系统)的缩写,它不是一个实际的文件系统,而是一个异构文件系统之上的软件粘合层
虚拟文件系统初始化 los_vfs_init()只能调用一次,多次调用将会造成文件系统异常
inode->i_mode 的标签如下:
#define S_IFMT 0170000 //文件类型位域掩码
#define S_IFDIR 0040000 //目录
#define S_IFCHR 0020000 //字符设备
#define S_IFBLK 0060000 //块设备
#define S_IFREG 0100000 //普通文件
#define S_IFIFO 0010000 //FIFO
#define S_IFLNK 0120000 //符号链接
#define S_IFSOCK 0140000 //套接字
#define S_ISUID 04000 //设置用户ID
#define S_ISGID 02000 //设置组ID
#define S_ISVTX 01000 //粘住位 此扩展功能的应用在/tmp目录下有所体现,我们可以在该目录下任意创建自己的文件,但就是不能删除或更名其他用户的文件
#define S_IRUSR 0400 //所有者有读权限
#define S_IWUSR 0200 //所有者有写权限
#define S_IXUSR 0100 //所有者有执行权限
#define S_IRWXU 0700 //所有者有读,写,执行权限
#define S_IRGRP 0040 //组有读权限
#define S_IWGRP 0020 //组有写权限
#define S_IXGRP 0010 //组有执行权限
#define S_IRWXG 0070 //组有读,写,执行权限
#define S_IROTH 0004 //其他有读权限
#define S_IWOTH 0002 //其他有写权限
#define S_IXOTH 0001 //其他有执行权限
#define S_IRWXO 0007 //其他有读,写,执行权限
例如:chmod 777 (S_IRWXU S_IRWXG S_IRWXO)
************************************************************************/
void los_vfs_init(void)
{
int err;
......@@ -51,22 +82,22 @@ void los_vfs_init(void)
}
spin_lock_init(&g_diskSpinlock);
spin_lock_init(&g_diskFatBlockSpinlock);
files_initlist(&tg_filelist);
fs_initialize();
if ((err = inode_reserve("/", &g_root_inode)) < 0) {
spin_lock_init(&g_diskFatBlockSpinlock); //此处连拿两把锁
files_initlist(&tg_filelist);//主要初始化列表访问互斥体
fs_initialize();//初始inode、文件和VFS数据结构
if ((err = inode_reserve("/", &g_root_inode)) < 0) {//为伪文件系统保留一个(初始化的)索引节点。 "/"为根节点
PRINT_ERR("los_vfs_init failed error %d\n", -err);
return;
}
g_root_inode->i_mode |= S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
if ((err = inode_reserve("/dev", &dev)) < 0) {
if ((err = inode_reserve("/dev", &dev)) < 0) {//为伪文件系统保留一个(初始化的)索引节点。 "/dev"
PRINT_ERR("los_vfs_init failed error %d\n", -err);
return;
}
dev->i_mode |= S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
retval = init_file_mapping();
retval = init_file_mapping();//初始化文件映射
if (retval != LOS_OK) {
PRINT_ERR("Page cache file map init failed\n");
return;
......
......@@ -37,7 +37,7 @@
#include "fs/fs.h"
#include "inode/inode.h"
#include "user_copy.h"
//将文件数据读取到内核空间
static char *pread_buf_and_check(int fd, const struct iovec *iov, int iovcnt, ssize_t *totalbytesread, off_t *offset)
{
char *buf = NULL;
......@@ -62,7 +62,7 @@ static char *pread_buf_and_check(int fd, const struct iovec *iov, int iovcnt, ss
return NULL;
}
buf = (char *)LOS_VMalloc(buflen * sizeof(char));
buf = (char *)LOS_VMalloc(buflen * sizeof(char));//申请内核内存
if (buf == NULL) {
set_errno(ENOMEM);
*totalbytesread = VFS_ERROR;
......@@ -70,7 +70,7 @@ static char *pread_buf_and_check(int fd, const struct iovec *iov, int iovcnt, ss
}
*totalbytesread = (offset == NULL) ? read(fd, buf, buflen)
: pread(fd, buf, buflen, *offset);
: pread(fd, buf, buflen, *offset);//读入内核内存
if ((*totalbytesread == VFS_ERROR) || (*totalbytesread == 0)) {
LOS_VFree(buf);
return NULL;
......@@ -78,7 +78,7 @@ static char *pread_buf_and_check(int fd, const struct iovec *iov, int iovcnt, ss
return buf;
}
//vfs 读文件操作
ssize_t vfs_readv(int fd, const struct iovec *iov, int iovcnt, off_t *offset)
{
int i;
......@@ -89,8 +89,8 @@ ssize_t vfs_readv(int fd, const struct iovec *iov, int iovcnt, off_t *offset)
ssize_t totalbytesread = 0;
ssize_t bytesleft;
buf = pread_buf_and_check(fd, iov, iovcnt, &totalbytesread, offset);
if (buf == NULL) {
buf = pread_buf_and_check(fd, iov, iovcnt, &totalbytesread, offset);//将文件数据读取到内核buf
if (buf == NULL) {//
return totalbytesread;
}
......@@ -103,12 +103,12 @@ ssize_t vfs_readv(int fd, const struct iovec *iov, int iovcnt, off_t *offset)
}
if (bytesleft <= bytestoread) {
ret = LOS_CopyFromKernel(iov[i].iov_base, bytesleft, curbuf, bytesleft);
ret = LOS_CopyFromKernel(iov[i].iov_base, bytesleft, curbuf, bytesleft);//从内核拷贝buf至用户空间
bytesleft = ret;
goto out;
}
ret = LOS_CopyFromKernel(iov[i].iov_base, bytestoread, curbuf, bytestoread);
ret = LOS_CopyFromKernel(iov[i].iov_base, bytestoread, curbuf, bytestoread);//从内核拷贝buf至用户空间
if (ret != 0) {
bytesleft = bytesleft - (bytestoread - ret);
goto out;
......@@ -118,7 +118,7 @@ ssize_t vfs_readv(int fd, const struct iovec *iov, int iovcnt, off_t *offset)
}
out:
LOS_VFree(buf);
LOS_VFree(buf);//释放内核内存
if ((i == 0) && (ret == iov[i].iov_len)) {
/* failed in the first iovec copy, and 0 bytes copied */
set_errno(EFAULT);
......@@ -127,7 +127,7 @@ out:
return totalbytesread - bytesleft;
}
//读文件操作
ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
{
return vfs_readv(fd, iov, iovcnt, NULL);
......
......@@ -182,7 +182,7 @@ static int vfs_normalize_path_parame_check(const char *filename, char **pathname
return namelen;
}
//vfs不是绝对路径
static char *vfs_not_absolute_path(const char *directory, const char *filename, char **pathname, int namelen)
{
int ret;
......@@ -214,12 +214,12 @@ static char *vfs_not_absolute_path(const char *directory, const char *filename,
return fullpath;
}
//全路径标准化
static char *vfs_normalize_fullpath(const char *directory, const char *filename, char **pathname, int namelen)
{
char *fullpath = NULL;
if (filename[0] != '/') {
if (filename[0] != '/') { //不是绝对路径的情况
/* not a absolute path */
fullpath = vfs_not_absolute_path(directory, filename, pathname, namelen);
......@@ -246,7 +246,7 @@ static char *vfs_normalize_fullpath(const char *directory, const char *filename,
return fullpath;
}
//路径标准化
int vfs_normalize_path(const char *directory, const char *filename, char **pathname)
{
char *fullpath = NULL;
......
......@@ -1497,7 +1497,7 @@ LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR
processName = strrchr(name, '/');
processName = (processName == NULL) ? name : (processName + 1); /* 1: Do not include '/' */
ret = OsSetProcessName(processCB, processName);
ret = OsSetProcessName(processCB, processName);//设置进程名称
if (ret != LOS_OK) {
return ret;
}
......@@ -1519,7 +1519,7 @@ LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR
OsCurrTaskGet()->sig.sigprocmask = 0;
#ifdef LOSCFG_FS_VFS
delete_files(OsCurrProcessGet(), (struct files_struct *)oldFiles);
delete_files(OsCurrProcessGet(), (struct files_struct *)oldFiles);//删除进程文件管理器快照
#endif
OsSwtmrRecycle(processCB->processID);//定时器回收
......
......@@ -109,11 +109,11 @@ typedef struct ProcessCB {
UINTPTR sigHandler; /**< signal handler */
sigset_t sigShare; /**< signal share bit */
#if (LOSCFG_KERNEL_LITEIPC == YES)
ProcIpcInfo ipcInfo; /**< memory pool for lite ipc */
ProcIpcInfo ipcInfo; /**< memory pool for lite ipc */
#endif
LosVmSpace *vmSpace; /**< VMM space for processes */
LosVmSpace *vmSpace; /**< VMM space for processes */ //进程空间
#ifdef LOSCFG_FS_VFS
struct files_struct *files; /**< Files held by the process */
struct files_struct *files; /**< Files held by the process */ //进程所持有的所有文件,注者称之为 文件管理器
#endif
timer_t timerID; /**< iTimer */
......
......@@ -146,8 +146,8 @@ STATIC INT32 OsELFLoadInit(const CHAR *fileName, ELFLoadInfo *loadInfo)
{
INT32 ret;
#ifdef LOSCFG_FS_VFS
const struct files_struct *oldFiles = OsCurrProcessGet()->files;
loadInfo->oldFiles = (UINTPTR)create_files_snapshot(oldFiles);
const struct files_struct *oldFiles = OsCurrProcessGet()->files;//保存当前进程持有的文件管理器
loadInfo->oldFiles = (UINTPTR)create_files_snapshot(oldFiles);//创建老文件管理器快照
#else
loadInfo->oldFiles = NULL;
#endif
......@@ -1011,7 +1011,7 @@ STATIC VOID OsDeInitFiles(ELFLoadInfo *loadInfo)
(VOID)close(loadInfo->interpFD);
}
#ifdef LOSCFG_FS_VFS
delete_files_snapshot((struct files_struct *)loadInfo->oldFiles);
delete_files_snapshot((struct files_struct *)loadInfo->oldFiles);//删除文件管理器快照
#endif
}
//加载ELF文件
......
git add -A
git commit -m '看完整的kernel_liteos_a源码需引入third,verdor项目,包括FreeBSD/mbedtls/musl/NuttX 和 hi3516dv300
git commit -m '开始对VFS模块代码注释,从进程文件管理器切入 process->files
鸿蒙内核源码分析系列 【 CSDN | OSCHINA | WIKI 】
鸿蒙内核源码注释中文版 【 CSDN仓 | Gitee仓 | Github仓 | Coding仓 】四大仓库每日同步更新代码和wiki
项目给鸿蒙内核源码逐行加上中文注解,详细阐述框架和代码细节, 精读 HarmonyOS 内核源码, 将迅速拔高对计算机整体理解,从此高屋建瓴看问题.'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册