理解 进程文件描述符 和 系统文件描述 是理解FD的关键.

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    国内:https://weharmony.gitee.io
    国外:https://weharmony.github.io
上级 d1ffbb81
......@@ -61,7 +61,7 @@ struct Mount {//装载
struct MountOps {
int (*Mount)(struct Mount *mount, struct Vnode *vnode, const void *data);//装载
int (*Unmount)(struct Mount *mount, struct Vnode **blkdriver);//卸载
int (*Statfs)(struct Mount *mount, struct statfs *sbp);//状态
int (*Statfs)(struct Mount *mount, struct statfs *sbp);//统计文件系统的信息,如该文件系统类型、总大小、可用大小等信息
};
struct Mount* MountAlloc(struct Vnode* vnode, struct MountOps* mop);
......
......@@ -107,10 +107,10 @@ static bool IsValidProcessFd(struct fd_table_s *fdt, int procFd)
}
return true;
}
//参数进程FD和参数系统FD进行绑定(关联)
void AssociateSystemFd(int procFd, int sysFd)
{
struct fd_table_s *fdt = GetFdTable();
struct fd_table_s *fdt = GetFdTable();//获取当前进程FD表
if (!IsValidProcessFd(fdt, procFd)) {
return;
......@@ -121,7 +121,7 @@ void AssociateSystemFd(int procFd, int sysFd)
}
FileTableLock(fdt);
fdt->ft_fds[procFd].sysFd = sysFd;
fdt->ft_fds[procFd].sysFd = sysFd;//绑定
FileTableUnLock(fdt);
}
......@@ -149,7 +149,7 @@ int GetAssociatedSystemFd(int procFd)
FileTableUnLock(fdt);
return VFS_ERROR;
}
int sysFd = fdt->ft_fds[procFd].sysFd;
int sysFd = fdt->ft_fds[procFd].sysFd;//进程FD捆绑系统FD
FileTableUnLock(fdt);
return sysFd;
......@@ -160,35 +160,40 @@ int GetAssociatedSystemFd(int procFd)
* 2.procFd is not allocated, we occupy it immediately.
* 3.procFd is in open(), close(), dup() process, we return EBUSY immediately.
*/
int AllocSpecifiedProcessFd(int procFd)
/* 占用procFd,有三种情况:
* 1.procFd 已经关联,我们需要将 procFd 与相关的 sysfd 解除关联。
* 2.procFd 未分配,我们立即占用。
* 3.procFd在open()、close()、dup()过程中,我们立即返回EBUSY。
*/
int AllocSpecifiedProcessFd(int procFd)//分配指定的进程Fd
{
struct fd_table_s *fdt = GetFdTable();
struct fd_table_s *fdt = GetFdTable();//获取进程FD表
if (!IsValidProcessFd(fdt, procFd)) {
return -EBADF;
}
FileTableLock(fdt);
if (fdt->ft_fds[procFd].sysFd >= 0) {
if (fdt->ft_fds[procFd].sysFd >= 0) {//第一种情况
/* Disassociate procFd */
fdt->ft_fds[procFd].sysFd = -1;
fdt->ft_fds[procFd].sysFd = -1;//解除关联
FileTableUnLock(fdt);
return OK;
}
if (FD_ISSET(procFd, fdt->proc_fds)) {
if (FD_ISSET(procFd, fdt->proc_fds)) {//还在使用中
/* procFd in race condition */
FileTableUnLock(fdt);
return -EBUSY;
} else {
} else {//未分配情况
/* Unused procFd */
FD_SET(procFd, fdt->proc_fds);
FD_SET(procFd, fdt->proc_fds);//立即占用
}
FileTableUnLock(fdt);
return OK;
}
//是否进程文件描述符
void FreeProcessFd(int procFd)
{
struct fd_table_s *fdt = GetFdTable();
......@@ -198,11 +203,11 @@ void FreeProcessFd(int procFd)
}
FileTableLock(fdt);
FD_CLR(procFd, fdt->proc_fds);
fdt->ft_fds[procFd].sysFd = -1;
FD_CLR(procFd, fdt->proc_fds); //相应位清0
fdt->ft_fds[procFd].sysFd = -1; //解绑系统文件描述符
FileTableUnLock(fdt);
}
//解绑系统文件描述符,返回系统文件描述符
int DisassociateProcessFd(int procFd)
{
struct fd_table_s *fdt = GetFdTable();
......@@ -212,13 +217,13 @@ int DisassociateProcessFd(int procFd)
}
FileTableLock(fdt);
if (fdt->ft_fds[procFd].sysFd < 0) {
if (fdt->ft_fds[procFd].sysFd < 0) {//无系统文件描述符
FileTableUnLock(fdt);
return VFS_ERROR;
return VFS_ERROR;//解绑失败
}
int sysFd = fdt->ft_fds[procFd].sysFd;
if (procFd >= MIN_START_FD) {
fdt->ft_fds[procFd].sysFd = -1;
int sysFd = fdt->ft_fds[procFd].sysFd;//存在绑定关系
if (procFd >= MIN_START_FD) {//必须大于2
fdt->ft_fds[procFd].sysFd = -1;//解绑
}
FileTableUnLock(fdt);
......@@ -252,7 +257,7 @@ int AllocLowestProcessFd(int minFd)
}
/* occupy the fd set */
FD_SET(procFd, fdt->proc_fds);
FD_SET(procFd, fdt->proc_fds);//占用该进程文件描述符
FileTableUnLock(fdt);
return procFd;
......@@ -306,30 +311,30 @@ int AllocAndAssocSystemFd(int procFd, int minFd)
return sysFd;
}
//进程FD引用数改变
static void FdRefer(int sysFd)
{
if ((sysFd > STDERR_FILENO) && (sysFd < CONFIG_NFILE_DESCRIPTORS)) {
files_refer(sysFd);
files_refer(sysFd);//增加系统FD引用次数
}
#if defined(LOSCFG_NET_LWIP_SACK)
if ((sysFd >= CONFIG_NFILE_DESCRIPTORS) && (sysFd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS))) {
socks_refer(sysFd);
socks_refer(sysFd);//增加socket引用次数
}
#endif
#if defined(LOSCFG_COMPAT_POSIX)
if ((sysFd >= MQUEUE_FD_OFFSET) && (sysFd < (MQUEUE_FD_OFFSET + CONFIG_NQUEUE_DESCRIPTORS))) {
mqueue_refer(sysFd);
mqueue_refer(sysFd);//增加mqpersonal引用次数
}
#endif
}
//关闭FD
static void FdClose(int sysFd, unsigned int targetPid)
{
UINT32 intSave;
if ((sysFd > STDERR_FILENO) && (sysFd < CONFIG_NFILE_DESCRIPTORS)) {
LosProcessCB *processCB = OS_PCB_FROM_PID(targetPid);
LosProcessCB *processCB = OS_PCB_FROM_PID(targetPid);//获取目标进程
SCHEDULER_LOCK(intSave);
if (OsProcessIsInactive(processCB)) {
SCHEDULER_UNLOCK(intSave);
......@@ -337,20 +342,20 @@ static void FdClose(int sysFd, unsigned int targetPid)
}
SCHEDULER_UNLOCK(intSave);
files_close_internal(sysFd, processCB);
files_close_internal(sysFd, processCB);//减少文件引用数(进程和系统的两个引用数)
}
#if defined(LOSCFG_NET_LWIP_SACK)
if ((sysFd >= CONFIG_NFILE_DESCRIPTORS) && (sysFd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS))) {
socks_close(sysFd);
socks_close(sysFd);//减少sockert引用数
}
#endif
#if defined(LOSCFG_COMPAT_POSIX)
if ((sysFd >= MQUEUE_FD_OFFSET) && (sysFd < (MQUEUE_FD_OFFSET + CONFIG_NQUEUE_DESCRIPTORS))) {
mq_close((mqd_t)sysFd);
mq_close((mqd_t)sysFd);//减少mqpersonal引用数
}
#endif
}
//获取参数进程FD表
static struct fd_table_s *GetProcessFTable(unsigned int pid, sem_t *semId)
{
UINT32 intSave;
......@@ -358,7 +363,7 @@ static struct fd_table_s *GetProcessFTable(unsigned int pid, sem_t *semId)
LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
SCHEDULER_LOCK(intSave);
if (OsProcessIsInactive(processCB)) {
if (OsProcessIsInactive(processCB)) {//参数进程必须处于激活状态
SCHEDULER_UNLOCK(intSave);
return NULL;
}
......@@ -374,7 +379,7 @@ static struct fd_table_s *GetProcessFTable(unsigned int pid, sem_t *semId)
return procFiles->fdt;
}
//拷贝一个进程FD给指定的进程
int CopyFdToProc(int fd, unsigned int targetPid)
{
#if !defined(LOSCFG_NET_LWIP_SACK) && !defined(LOSCFG_COMPAT_POSIX) && !defined(LOSCFG_FS_VFS)
......@@ -389,13 +394,13 @@ int CopyFdToProc(int fd, unsigned int targetPid)
return -EINVAL;
}
sysFd = GetAssociatedSystemFd(fd);
sysFd = GetAssociatedSystemFd(fd);//找到当前进程FD绑定的系统FD
if (sysFd < 0) {
return -EBADF;
}
FdRefer(sysFd);
fdt = GetProcessFTable(targetPid, &semId);
FdRefer(sysFd);//引用数要增加了.
fdt = GetProcessFTable(targetPid, &semId);//获取目标进程的FD表
if (fdt == NULL || fdt->ft_fds == NULL) {
FdClose(sysFd, targetPid);
return -EPERM;
......@@ -408,7 +413,7 @@ int CopyFdToProc(int fd, unsigned int targetPid)
return -ESRCH;
}
procFd = AssignProcessFd(fdt, 3);
procFd = AssignProcessFd(fdt, 3);//从目标进程FD表中分配一个FD出来,注意这个FD编号不一定和当前进程的编号相同,但他们都将绑定在同一个系统FD上
if (procFd < 0) {
if (sem_post(&semId) == -1) {
PRINT_ERR("sem_post error, errno %d \n", get_errno());
......@@ -418,8 +423,8 @@ int CopyFdToProc(int fd, unsigned int targetPid)
}
/* occupy the fd set */
FD_SET(procFd, fdt->proc_fds);
fdt->ft_fds[procFd].sysFd = sysFd;
FD_SET(procFd, fdt->proc_fds);//申请到了等啥呀,赶紧占用这个FD
fdt->ft_fds[procFd].sysFd = sysFd;//绑定,这句话代表的意思是有两个进程的FD都帮到同一个系统FD上
if (sem_post(&semId) == -1) {
PRINTK("sem_post error, errno %d \n", get_errno());
}
......@@ -427,7 +432,7 @@ int CopyFdToProc(int fd, unsigned int targetPid)
return procFd;
#endif
}
//关闭进程FD
int CloseProcFd(int procFd, unsigned int targetPid)
{
#if !defined(LOSCFG_NET_LWIP_SACK) && !defined(LOSCFG_COMPAT_POSIX) && !defined(LOSCFG_FS_VFS)
......@@ -441,7 +446,7 @@ int CloseProcFd(int procFd, unsigned int targetPid)
return -EINVAL;
}
fdt = GetProcessFTable(targetPid, &semId);
fdt = GetProcessFTable(targetPid, &semId);//获取进程文件描述表
if (fdt == NULL || fdt->ft_fds == NULL) {
return -EPERM;
}
......@@ -459,7 +464,7 @@ int CloseProcFd(int procFd, unsigned int targetPid)
return -EPERM;
}
sysFd = fdt->ft_fds[procFd].sysFd;
sysFd = fdt->ft_fds[procFd].sysFd;//获取参数进程描述符绑定的系统文件描述符
if (sysFd < 0) {
if (sem_post(&semId) == -1) {
PRINTK("sem_post error, errno %d \n", get_errno());
......@@ -468,12 +473,12 @@ int CloseProcFd(int procFd, unsigned int targetPid)
}
/* clean the fd set */
FD_CLR(procFd, fdt->proc_fds);
fdt->ft_fds[procFd].sysFd = -1;
FD_CLR(procFd, fdt->proc_fds);//进程FD重置
fdt->ft_fds[procFd].sysFd = -1;//解绑
if (sem_post(&semId) == -1) {
PRINTK("sem_post error, errno %d \n", get_errno());
}
FdClose(sysFd, targetPid);
FdClose(sysFd, targetPid);//注意这个操作只是让对应的引用数量减少
return 0;
#endif
......
......@@ -56,7 +56,7 @@ int fstat(int fd, struct stat *buf)
return VFS_ERROR;
}
return stat(filep->f_path, buf);
return stat(filep->f_path, buf);//统计
}
int fstat64(int fd, struct stat64 *buf)
......@@ -681,18 +681,18 @@ void lsfd(void)
while (i < CONFIG_NFILE_DESCRIPTORS) {
node = files_get_openfile(i);//bitmap对应位 为 1的
if (node) {
PRINTK("%5d %s\n", i, f_list->fl_files[i].f_path);
PRINTK("%5d %s\n", i, f_list->fl_files[i].f_path);//打印fd 和 路径
}
i++;
}
(void)sem_post(&f_list->fl_sem);
}
//获取用户创建文件掩码
mode_t GetUmask(void)
{
return OsCurrProcessGet()->umask;
}
//给当前进程设置系统创建文件掩码,并返回进程旧掩码
mode_t SysUmask(mode_t mask)
{
UINT32 intSave;
......
......@@ -45,7 +45,7 @@
/****************************************************************************
* Global Functions
****************************************************************************/
//更新时间
int utime(const char *path, const struct utimbuf *ptimes)
{
int ret;
......@@ -54,7 +54,7 @@ int utime(const char *path, const struct utimbuf *ptimes)
time_t cur_sec;
struct IATTR attr = {0};
/* Sanity checks */
/* Sanity checks *///健全性检查
if (path == NULL) {
......@@ -66,7 +66,7 @@ int utime(const char *path, const struct utimbuf *ptimes)
ret = -ENOENT;
goto errout;
}
//找到绝对路径
ret = vfs_normalize_path((const char *)NULL, path, &fullpath);
if (ret < 0) {
goto errout;
......@@ -74,24 +74,24 @@ int utime(const char *path, const struct utimbuf *ptimes)
/* Get the vnode for this file */
VnodeHold();
ret = VnodeLookup(fullpath, &vnode, 0);
ret = VnodeLookup(fullpath, &vnode, 0);//找到vnode节点
if (ret != LOS_OK) {
VnodeDrop();
goto errout_with_path;
}
if (vnode->vop && vnode->vop->Chattr) {
if (ptimes == NULL) {
if (vnode->vop && vnode->vop->Chattr) {//验证接口都已经实现
if (ptimes == NULL) {//参数没有给时间
/* get current seconds */
cur_sec = time(NULL);
attr.attr_chg_atime = cur_sec;
attr.attr_chg_mtime = cur_sec;
} else {
attr.attr_chg_atime = ptimes->actime;
cur_sec = time(NULL);//获取当前秒
attr.attr_chg_atime = cur_sec;//更新访问时间
attr.attr_chg_mtime = cur_sec;//更新修改时间
} else {//采用参数时间
attr.attr_chg_atime = ptimes->actime;//更新访问时间
attr.attr_chg_mtime = ptimes->modtime;
}
attr.attr_chg_valid = CHG_ATIME | CHG_MTIME;
ret = vnode->vop->Chattr(vnode, &attr);
attr.attr_chg_valid = CHG_ATIME | CHG_MTIME;//更新了两个时间
ret = vnode->vop->Chattr(vnode, &attr);//调用接口更新数据
if (ret != OK) {
VnodeDrop();
goto errout_with_path;
......
......@@ -665,7 +665,7 @@ static inline void print_statfs_usage(void)
}
/*****************************************************************
命令功能
statfs命令用来打印文件系统的信息,如该文件系统类型、总大小、可用大小等信息。
statfs 命令用来打印文件系统的信息,如该文件系统类型、总大小、可用大小等信息。
命令格式
statfs [directory]
参数说明
......@@ -695,7 +695,7 @@ int osShellCmdStatfs(int argc, const char **argv)
result = vfs_normalize_path(shell_working_directory, filename, &fullpath);
ERROR_OUT_IF(result < 0, set_err(-result, "statfs error"), return -1);
result = statfs(fullpath, &sfs);
result = statfs(fullpath, &sfs);//命令实现体
free(fullpath);
if (result != 0 || sfs.f_type == 0)
......
......@@ -122,7 +122,7 @@ typedef struct ProcessCB {
#ifdef LOSCFG_DRIVERS_TZDRIVER
struct file *execFile; /**< Exec bin of the process */
#endif
mode_t umask;
mode_t umask;//umask(user file-creatiopn mode mask)为用户文件创建掩码,是创建文件或文件夹时默认权限的基础。
#ifdef LOSCFG_KERNEL_CPUP
OsCpupBase processCpup; /**< Process cpu usage */
#endif
......@@ -422,25 +422,25 @@ STATIC INLINE User *OsCurrUserGet(VOID)//获取当前进程的所属用户
/*
* Wait for any child process to finish
*/
#define OS_PROCESS_WAIT_ANY OS_TASK_WAIT_ANYPROCESS
#define OS_PROCESS_WAIT_ANY OS_TASK_WAIT_ANYPROCESS //等待任意子进程完成
/*
* Wait for the child process specified by the pid to finish
*/
#define OS_PROCESS_WAIT_PRO OS_TASK_WAIT_PROCESS
#define OS_PROCESS_WAIT_PRO OS_TASK_WAIT_PROCESS //等待pid指定的子进程完成
/*
* Waits for any child process in the specified process group to finish.
*/
#define OS_PROCESS_WAIT_GID OS_TASK_WAIT_GID
#define OS_PROCESS_WAIT_GID OS_TASK_WAIT_GID //等待指定进程组中的任意子进程完成
#define OS_PROCESS_INFO_ALL 1
#define OS_PROCESS_DEFAULT_UMASK 0022
#define OS_PROCESS_DEFAULT_UMASK 0022 //系统默认的用户掩码(umask),大多数的Linux系统的默认掩码为022。
//用户掩码的作用是用户在创建文件时从文件的默认权限中去除掩码中的权限。所以文件创建之后的权限实际为:创建文件的权限为:0666-0022=0644。创建文件夹的权限为:0777-0022=0755
extern UINTPTR __user_init_entry; // 第一个用户态任务的入口地址 查看 LITE_USER_SEC_ENTRY
extern UINTPTR __user_init_bss; // 查看 LITE_USER_SEC_BSS
extern UINTPTR __user_init_end; //
extern UINTPTR __user_init_load_addr;
extern UINTPTR __user_init_end; // 用户空间结束虚拟地址
extern UINTPTR __user_init_load_addr;//用户空间加载地址
extern UINT32 OsSystemProcessCreate(VOID);
extern VOID OsProcessCBRecyleToFree(VOID);
extern VOID OsProcessResourcesToFree(LosProcessCB *processCB);
......
git add -A
git commit -m '对 file ,fd rootfs 模块的注解
git commit -m '理解 进程文件描述符 和 系统文件描述 是理解FD的关键.
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
国内:https://weharmony.gitee.io
国外:https://weharmony.github.io
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册