更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
proc_vfs.c 文件参考

浏览源代码.

函数

static struct ProcDirEntryVnodeToEntry (struct Vnode *node)
 通过节点获取私有内存对象,注意要充分理解 node->data 的作用,那是个可以通天的神奇变量. 更多...
 
static struct VnodeEntryToVnode (struct ProcDirEntry *entry)
 创建节点,通过实体对象转成vnode节点,如此达到统一管理的目的. 更多...
 
static int EntryMatch (const char *name, int len, const struct ProcDirEntry *pn)
 实体匹配,通过名称匹配 更多...
 
int VfsProcfsTruncate (struct Vnode *pVnode, off_t len)
 
int VfsProcfsCreate (struct Vnode *parent, const char *name, int mode, struct Vnode **vnode)
 创建vnode节点,并绑定私有内容项 更多...
 
int VfsProcfsRead (struct file *filep, char *buffer, size_t buflen)
 
int VfsProcfsWrite (struct file *filep, const char *buffer, size_t buflen)
 
int VfsProcfsLookup (struct Vnode *parent, const char *name, int len, struct Vnode **vpp)
 
int VfsProcfsMount (struct Mount *mnt, struct Vnode *device, const void *data)
 挂s载实现,找个vnode节点挂上去 更多...
 
int VfsProcfsUnmount (void *handle, struct Vnode **blkdriver)
 
int VfsProcfsStat (struct Vnode *node, struct stat *buf)
 
int VfsProcfsReaddir (struct Vnode *node, struct fs_dirent_s *dir)
 
int VfsProcfsOpendir (struct Vnode *node, struct fs_dirent_s *dir)
 proc 打开目录 更多...
 
int VfsProcfsOpen (struct file *filep)
 proc 打开文件 更多...
 
int VfsProcfsClose (struct file *filep)
 
int VfsProcfsStatfs (struct Mount *mnt, struct statfs *buf)
 统计信息接口,简单实现 更多...
 
int VfsProcfsClosedir (struct Vnode *vp, struct fs_dirent_s *dir)
 
 FSMAP_ENTRY (procfs_fsmap, "procfs", procfs_operations, FALSE, FALSE)
 

变量

static struct VnodeOps g_procfsVops
 
static struct file_operations_vfs g_procfsFops
 proc 文件系统 更多...
 
const struct MountOps procfs_operations
 proc 对 MountOps 接口实现 更多...
 

函数说明

◆ EntryMatch()

static int EntryMatch ( const char *  name,
int  len,
const struct ProcDirEntry pn 
)
static

实体匹配,通过名称匹配

在文件 proc_vfs.c85 行定义.

86{
87 if (len != pn->nameLen) {
88 return 0;
89 }
90 return !strncmp(name, pn->name, len);
91}
int nameLen
Definition: proc_fs.h:112
char name[NAME_MAX]
Definition: proc_fs.h:114
这是这个函数的调用关系图:

◆ EntryToVnode()

static struct Vnode * EntryToVnode ( struct ProcDirEntry entry)
static

创建节点,通过实体对象转成vnode节点,如此达到统一管理的目的.

在文件 proc_vfs.c71 行定义.

72{
73 struct Vnode *node = NULL;
74
75 (void)VnodeAlloc(&g_procfsVops, &node);//申请一个 vnode节点,并设置节点操作
76 node->fop = &g_procfsFops;//设置文件操作系列函数
77 node->data = entry;//绑定实体
78 node->type = entry->type;//实体类型 (文件|目录)
79 node->uid = entry->uid; //用户ID
80 node->gid = entry->gid; //组ID
81 node->mode = entry->mode;//读/写/执行模式
82 return node;
83}
static struct file_operations_vfs g_procfsFops
proc 文件系统
Definition: proc_vfs.c:63
static struct VnodeOps g_procfsVops
Definition: proc_vfs.c:62
uint uid
Definition: proc_fs.h:102
enum VnodeType type
节点类型
Definition: proc_fs.h:115
mode_t mode
模式(读|写...)
Definition: proc_fs.h:104
uint gid
Definition: proc_fs.h:103
vnode并不包含文件名,因为 vnode和文件名是 1:N 的关系
Definition: vnode.h:164
uint gid
Definition: vnode.h:169
enum VnodeType type
Definition: vnode.h:165
mode_t mode
Definition: vnode.h:170
void * data
Definition: vnode.h:176
struct file_operations_vfs * fop
Definition: vnode.h:175
uint uid
Definition: vnode.h:168
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 void
int VnodeAlloc(struct VnodeOps *vop, struct Vnode **vnode)
申请分配一个 vnode 节点,vop为操作节点的驱动程序
Definition: vnode.c:166
函数调用图:
这是这个函数的调用关系图:

◆ FSMAP_ENTRY()

FSMAP_ENTRY ( procfs_fsmap  ,
"procfs"  ,
procfs_operations  ,
FALSE  ,
FALSE   
)

◆ VfsProcfsClose()

int VfsProcfsClose ( struct file filep)

在文件 proc_vfs.c325 行定义.

326{
327 int result = 0;
328 if (filep == NULL) {
329 return -EINVAL;
330 }
331 struct Vnode *node = filep->f_vnode;
332 struct ProcDirEntry *pde = VnodeToEntry(node);
333 pde->pf->fPos = 0;
334 if ((pde->procFileOps != NULL) && (pde->procFileOps->release != NULL)) {
335 result = pde->procFileOps->release((struct Vnode *)pde, pde->pf);
336 }
337 LosBufRelease(pde->pf->sbuf);
338 pde->pf->sbuf = NULL;
339
340 return result;
341}
int LosBufRelease(struct SeqBuf *seqBuf)
释放 seq buf
Definition: los_seq_buf.c:145
static struct ProcDirEntry * VnodeToEntry(struct Vnode *node)
通过节点获取私有内存对象,注意要充分理解 node->data 的作用,那是个可以通天的神奇变量.
Definition: proc_vfs.c:66
proc 目录/文件项, @notethinking 直接叫 ProcEntry不香吗 ? 操作 /proc的 真正结构体
Definition: proc_fs.h:101
struct ProcFile * pf
proc文件指针
Definition: proc_fs.h:107
const struct ProcFileOperations * procFileOps
驱动程序,每个 /proc 下目录的驱动程序都不一样
Definition: proc_fs.h:106
loff_t fPos
文件操作偏移位
Definition: proc_fs.h:128
struct SeqBuf * sbuf
序列号BUF
Definition: proc_fs.h:125
int(* release)(struct Vnode *vnode, struct ProcFile *pf)
Definition: proc_fs.h:93
函数调用图:

◆ VfsProcfsClosedir()

int VfsProcfsClosedir ( struct Vnode vp,
struct fs_dirent_s *  dir 
)

在文件 proc_vfs.c351 行定义.

352{
353 return LOS_OK;
354}

◆ VfsProcfsCreate()

int VfsProcfsCreate ( struct Vnode parent,
const char *  name,
int  mode,
struct Vnode **  vnode 
)

创建vnode节点,并绑定私有内容项

在文件 proc_vfs.c98 行定义.

99{
100 int ret;
101 struct Vnode *vp = NULL;
102 struct ProcDirEntry *curEntry = NULL;
103
104 struct ProcDirEntry *parentEntry = VnodeToEntry(parent);
105 if (parentEntry == NULL) {
106 return -ENODATA;
107 }
108
109 ret = VnodeAlloc(&g_procfsVops, &vp);
110 if (ret != 0) {
111 return -ENOMEM;
112 }
113
114 curEntry = ProcCreate(name, mode, parentEntry, NULL);
115 if (curEntry == NULL) {
116 VnodeFree(vp);
117 return -ENODATA;
118 }
119
120 vp->data = curEntry;
121 vp->type = curEntry->type;
122 if (vp->type == VNODE_TYPE_DIR) {
123 vp->mode = S_IFDIR | PROCFS_DEFAULT_MODE;
124 } else {
125 vp->mode = S_IFREG | PROCFS_DEFAULT_MODE;
126 }
127
128 vp->vop = parent->vop;
129 vp->fop = parent->fop;
130 vp->parent = parent;
131 vp->originMount = parent->originMount;
132
133 *vnode = vp;
134
135 return LOS_OK;
136}
struct ProcDirEntry * ProcCreate(const char *name, mode_t mode, struct ProcDirEntry *parent, const struct ProcFileOperations *procFops)
create a proc node
Definition: proc_file.c:457
struct ProcDirEntry * parent
Definition: proc_fs.h:108
struct VnodeOps * vop
Definition: vnode.h:174
struct Mount * originMount
Definition: vnode.h:180
struct Vnode * parent
Definition: vnode.h:173
@ VNODE_TYPE_DIR
Definition: vnode.h:137
int VnodeFree(struct Vnode *vnode)
是否 vnode 节点
Definition: vnode.c:212
函数调用图:

◆ VfsProcfsLookup()

int VfsProcfsLookup ( struct Vnode parent,
const char *  name,
int  len,
struct Vnode **  vpp 
)

在文件 proc_vfs.c168 行定义.

169{
170 if (parent == NULL || name == NULL || len <= 0 || vpp == NULL) {
171 return -EINVAL;
172 }
173 struct ProcDirEntry *entry = VnodeToEntry(parent);
174 if (entry == NULL) {
175 return -ENODATA;
176 }
177 entry = entry->subdir;
178 while (1) {
179 if (entry == NULL) {
180 return -ENOENT;
181 }
182 if (EntryMatch(name, len, entry)) {
183 break;
184 }
185 entry = entry->next;
186 }
187
188 *vpp = EntryToVnode(entry);
189 if ((*vpp) == NULL) {
190 return -ENOMEM;
191 }
192 (*vpp)->originMount = parent->originMount;//继承挂载信息
193 (*vpp)->parent = parent;
194 return LOS_OK;
195}
static struct Vnode * EntryToVnode(struct ProcDirEntry *entry)
创建节点,通过实体对象转成vnode节点,如此达到统一管理的目的.
Definition: proc_vfs.c:71
static int EntryMatch(const char *name, int len, const struct ProcDirEntry *pn)
实体匹配,通过名称匹配
Definition: proc_vfs.c:85
struct ProcDirEntry * next
Definition: proc_fs.h:108
struct ProcDirEntry * subdir
当前目录项的关系项
Definition: proc_fs.h:108
函数调用图:

◆ VfsProcfsMount()

int VfsProcfsMount ( struct Mount mnt,
struct Vnode device,
const void data 
)

挂s载实现,找个vnode节点挂上去

在文件 proc_vfs.c197 行定义.

198{
199 struct Vnode *vp = NULL;
200 int ret;
201
202 spin_lock_init(&procfsLock);
203 procfsInit = true; //已初始化 /proc 模块
204
205 ret = VnodeAlloc(&g_procfsVops, &vp);//分配一个节点
206 if (ret != 0) {
207 return -ENOMEM;
208 }
209
210 struct ProcDirEntry *root = GetProcRootEntry();
211 vp->data = root;
212 vp->originMount = mnt;//绑定mount
213 vp->fop = &g_procfsFops;//指定文件系统
214 mnt->data = NULL;
215 mnt->vnodeCovered = vp;
216 vp->type = root->type;
217 if (vp->type == VNODE_TYPE_DIR) {//目录节点
218 vp->mode = S_IFDIR | PROCFS_DEFAULT_MODE;//贴上目录标签
219 } else {
220 vp->mode = S_IFREG | PROCFS_DEFAULT_MODE;//贴上文件标签
221 }
222
223 return LOS_OK;
224}
spinlock_t procfsLock
bool procfsInit
Definition: proc_file.c:44
struct ProcDirEntry * GetProcRootEntry(void)
Definition: proc_file.c:688
void * data
Definition: mount.h:78
struct Vnode * vnodeCovered
Definition: mount.h:72
函数调用图:

◆ VfsProcfsOpen()

int VfsProcfsOpen ( struct file filep)

proc 打开文件

在文件 proc_vfs.c304 行定义.

305{
306 if (filep == NULL) {
307 return -EINVAL;
308 }
309 struct Vnode *node = filep->f_vnode;//找到vnode节点
310 struct ProcDirEntry *pde = VnodeToEntry(node);//拿到私有数据(内存对象)
311 if (ProcOpen(pde->pf) != OK) {
312 return -ENOMEM;
313 }
314 if (S_ISREG(pde->mode) && (pde->procFileOps != NULL) && (pde->procFileOps->open != NULL)) {
315 (void)pde->procFileOps->open((struct Vnode *)pde, pde->pf);
316 }
317 if (S_ISDIR(pde->mode)) {
318 pde->pdirCurrent = pde->subdir;
319 pde->pf->fPos = 0;
320 }
321 filep->f_priv = (void *)pde;
322 return LOS_OK;
323}
int ProcOpen(struct ProcFile *procFile)
打开 pro
Definition: proc_file.c:503
struct ProcDirEntry * pdirCurrent
当前目录
Definition: proc_fs.h:113
int(* open)(struct Vnode *vnode, struct ProcFile *pf)
Definition: proc_fs.h:92
void * f_priv
函数调用图:

◆ VfsProcfsOpendir()

int VfsProcfsOpendir ( struct Vnode node,
struct fs_dirent_s *  dir 
)

proc 打开目录

在文件 proc_vfs.c292 行定义.

293{
294 struct ProcDirEntry *pde = VnodeToEntry(node);
295 if (pde == NULL) {
296 return -EINVAL;
297 }
298 pde->pdirCurrent = pde->subdir;
299 pde->pf->fPos = 0;
300
301 return LOS_OK;
302}
函数调用图:

◆ VfsProcfsRead()

int VfsProcfsRead ( struct file filep,
char *  buffer,
size_t  buflen 
)

在文件 proc_vfs.c138 行定义.

139{
140 ssize_t size;
141 struct ProcDirEntry *entry = NULL;
142 if ((filep == NULL) || (filep->f_vnode == NULL) || (buffer == NULL)) {
143 return -EINVAL;
144 }
145
146 entry = VnodeToEntry(filep->f_vnode);
147 size = (ssize_t)ReadProcFile(entry, (void *)buffer, buflen);
148 filep->f_pos = entry->pf->fPos;
149
150 return size;
151}
INT64 ssize_t
Definition: los_typedef.h:79
int ReadProcFile(struct ProcDirEntry *pde, void *buf, size_t len)
read a proc node
Definition: proc_file.c:584
loff_t f_pos
函数调用图:

◆ VfsProcfsReaddir()

int VfsProcfsReaddir ( struct Vnode node,
struct fs_dirent_s *  dir 
)

在文件 proc_vfs.c243 行定义.

244{
245 int result;
246 char *buffer = NULL;
247 int buflen = NAME_MAX;
248 unsigned int min_size;
249 unsigned int dst_name_size;
250 struct ProcDirEntry *pde = NULL;
251 int i = 0;
252
253 if (dir == NULL) {
254 return -EINVAL;
255 }
256 if (node->type != VNODE_TYPE_DIR) {
257 return -ENOTDIR;
258 }
259 pde = VnodeToEntry(node);
260
261 while (i < dir->read_cnt) {
262 buffer = (char *)zalloc(sizeof(char) * NAME_MAX);
263 if (buffer == NULL) {
264 PRINT_ERR("malloc failed\n");
265 return -ENOMEM;
266 }
267
268 result = ReadProcFile(pde, (void *)buffer, buflen);
269 if (result != ENOERR) {
270 free(buffer);
271 break;
272 }
273 dst_name_size = sizeof(dir->fd_dir[i].d_name);
274 min_size = (dst_name_size < NAME_MAX) ? dst_name_size : NAME_MAX;
275 result = strncpy_s(dir->fd_dir[i].d_name, dst_name_size, buffer, min_size);
276 if (result != EOK) {
277 free(buffer);
278 return -ENAMETOOLONG;
279 }
280 dir->fd_dir[i].d_name[dst_name_size - 1] = '\0';
281 dir->fd_position++;
282 dir->fd_dir[i].d_off = dir->fd_position;
283 dir->fd_dir[i].d_reclen = (uint16_t)sizeof(struct dirent);
284
285 i++;
286 free(buffer);
287 }
288
289 return i;
290}
void * zalloc(size_t size)
Definition: malloc.c:91
void free(void *ptr)
释放ptr所指向的内存空间
Definition: malloc.c:66
函数调用图:

◆ VfsProcfsStat()

int VfsProcfsStat ( struct Vnode node,
struct stat *  buf 
)

在文件 proc_vfs.c233 行定义.

234{
235 struct ProcDirEntry *entry = VnodeToEntry(node);
236
237 (void)memset_s(buf, sizeof(struct stat), 0, sizeof(struct stat));
238 buf->st_mode = entry->mode;
239
240 return LOS_OK;
241}
函数调用图:

◆ VfsProcfsStatfs()

int VfsProcfsStatfs ( struct Mount mnt,
struct statfs *  buf 
)

统计信息接口,简单实现

在文件 proc_vfs.c343 行定义.

344{
345 (void)memset_s(buf, sizeof(struct statfs), 0, sizeof(struct statfs));
346 buf->f_type = PROCFS_MAGIC;
347
348 return LOS_OK;
349}

◆ VfsProcfsTruncate()

int VfsProcfsTruncate ( struct Vnode pVnode,
off_t  len 
)

在文件 proc_vfs.c93 行定义.

94{
95 return 0;
96}

◆ VfsProcfsUnmount()

int VfsProcfsUnmount ( void handle,
struct Vnode **  blkdriver 
)

在文件 proc_vfs.c226 行定义.

227{
228 (void)handle;
229 (void)blkdriver;
230 return -EPERM;
231}

◆ VfsProcfsWrite()

int VfsProcfsWrite ( struct file filep,
const char *  buffer,
size_t  buflen 
)

在文件 proc_vfs.c153 行定义.

154{
155 ssize_t size;
156 struct ProcDirEntry *entry = NULL;
157 if ((filep == NULL) || (filep->f_vnode == NULL) || (buffer == NULL)) {
158 return -EINVAL;
159 }
160
161 entry = VnodeToEntry(filep->f_vnode);
162 size = (ssize_t)WriteProcFile(entry, (void *)buffer, buflen);
163 filep->f_pos = entry->pf->fPos;
164
165 return size;
166}
int WriteProcFile(struct ProcDirEntry *pde, const void *buf, size_t len)
write a proc node
Definition: proc_file.c:601
函数调用图:

◆ VnodeToEntry()

static struct ProcDirEntry * VnodeToEntry ( struct Vnode node)
static

通过节点获取私有内存对象,注意要充分理解 node->data 的作用,那是个可以通天的神奇变量.

在文件 proc_vfs.c66 行定义.

67{
68 return (struct ProcDirEntry *)(node->data);
69}
这是这个函数的调用关系图:

变量说明

◆ g_procfsFops

static struct file_operations_vfs g_procfsFops
static
初始值:
= {
.read = VfsProcfsRead,
.write = VfsProcfsWrite,
.open = VfsProcfsOpen,
.close = VfsProcfsClose
}
int VfsProcfsRead(struct file *filep, char *buffer, size_t buflen)
Definition: proc_vfs.c:138
int VfsProcfsOpen(struct file *filep)
proc 打开文件
Definition: proc_vfs.c:304
int VfsProcfsWrite(struct file *filep, const char *buffer, size_t buflen)
Definition: proc_vfs.c:153
int VfsProcfsClose(struct file *filep)
Definition: proc_vfs.c:325

proc 文件系统

在文件 proc_vfs.c63 行定义.

◆ g_procfsVops

static struct VnodeOps g_procfsVops
static
初始值:
= {
.Lookup = VfsProcfsLookup,
.Getattr = VfsProcfsStat,
.Readdir = VfsProcfsReaddir,
.Opendir = VfsProcfsOpendir,
.Closedir = VfsProcfsClosedir,
.Truncate = VfsProcfsTruncate
}
int VfsProcfsTruncate(struct Vnode *pVnode, off_t len)
Definition: proc_vfs.c:93
int VfsProcfsClosedir(struct Vnode *vp, struct fs_dirent_s *dir)
Definition: proc_vfs.c:351
int VfsProcfsOpendir(struct Vnode *node, struct fs_dirent_s *dir)
proc 打开目录
Definition: proc_vfs.c:292
int VfsProcfsReaddir(struct Vnode *node, struct fs_dirent_s *dir)
Definition: proc_vfs.c:243
int VfsProcfsStat(struct Vnode *node, struct stat *buf)
Definition: proc_vfs.c:233
int VfsProcfsLookup(struct Vnode *parent, const char *name, int len, struct Vnode **vpp)
Definition: proc_vfs.c:168
鸿蒙的/proc目录是一种文件系统,即proc文件系统。与其它常见的文件系统不同的是,/proc是一种伪文件系统(也即虚拟文件系统),
存储的是当前内核运行状态的一系列特殊文件,用户可以通过这些文件查看有关系统硬件及当前正在运行进程的信息,
甚至可以通过更改其中某些文件来改变内核的运行状态。

基于/proc文件系统如上所述的特殊性,其内的文件也常被称作虚拟文件,并具有一些独特的特点。
例如,其中有些文件虽然使用查看命令查看时会返回大量信息,但文件本身的大小却会显示为0字节。
此外,这些特殊文件中大多数文件的时间及日期属性通常为当前系统时间和日期,这跟它们随时会被刷新(存储于RAM中)有关。

为了查看及使用上的方便,这些文件通常会按照相关性进行分类存储于不同的目录甚至子目录中,
如/proc/mounts 目录中存储的就是当前系统上所有装载点的相关信息,

大多数虚拟文件可以使用文件查看命令如cat、more或者less进行查看,有些文件信息表述的内容可以一目了然,
 * 

在文件 proc_vfs.c62 行定义.

◆ procfs_operations

const struct MountOps procfs_operations
初始值:
= {
.Mount = VfsProcfsMount,
.Unmount = NULL,
.Statfs = VfsProcfsStatfs,
}
int VfsProcfsMount(struct Mount *mnt, struct Vnode *device, const void *data)
挂s载实现,找个vnode节点挂上去
Definition: proc_vfs.c:197
int VfsProcfsStatfs(struct Mount *mnt, struct statfs *buf)
统计信息接口,简单实现
Definition: proc_vfs.c:343

proc 对 MountOps 接口实现

在文件 proc_vfs.c356 行定义.