Skip to content

Commit e85582d

Browse files
committed
components: dfs_v2: add proc
This patch may need rework. Specially I see laster master has added support for proc, see RT-Thread#9206. Signed-off-by: Wang Chen <[email protected]>
1 parent 3157035 commit e85582d

File tree

5 files changed

+411
-12
lines changed

5 files changed

+411
-12
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from building import *
2+
3+
cwd = GetCurrentDir()
4+
src = Glob('*.c')
5+
CPPPATH = [cwd]
6+
7+
group = DefineGroup('Filesystem', src, depend = ['RT_USING_PROC', 'RT_USING_DFS', 'RT_USING_DFS_PROCFS'], CPPPATH = CPPPATH)
8+
9+
Return('group')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,350 @@
1+
/* Copyright (c) 2022, Canaan Bright Sight Co., Ltd
2+
*
3+
*/
4+
5+
#include <rtthread.h>
6+
#include <rttypes.h>
7+
#include <rtservice.h>
8+
#include <dfs.h>
9+
#include <dfs_fs.h>
10+
#include <dfs_mnt.h>
11+
#include <dfs_file.h>
12+
#include <dfs_dentry.h>
13+
#include <dfs_posix.h>
14+
#include "dfs_procfs.h"
15+
16+
static RT_DEFINE_SPINLOCK(procfs_lock);
17+
static struct rt_proc_entry procfs_root =
18+
{
19+
.parent.list = RT_LIST_OBJECT_INIT(procfs_root.parent.list),
20+
#if defined(RT_USING_POSIX_FS)
21+
.fops = 0,
22+
#endif
23+
};
24+
25+
rt_proc_entry_t rt_proc_entry_find(const char *name)
26+
{
27+
rt_base_t level;
28+
rt_object_t object;
29+
rt_proc_entry_t entry = RT_NULL;
30+
31+
level = rt_spin_lock_irqsave(&procfs_lock);
32+
rt_list_for_each_entry(object, &(procfs_root.parent.list), list)
33+
{
34+
if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
35+
{
36+
entry = (rt_proc_entry_t)object;
37+
break;
38+
}
39+
}
40+
rt_spin_unlock_irqrestore(&procfs_lock, level);
41+
42+
return entry;
43+
}
44+
45+
rt_err_t rt_proc_entry_register(rt_proc_entry_t entry, const char *name)
46+
{
47+
if (entry == RT_NULL)
48+
return -RT_EINVAL;
49+
50+
if (rt_proc_entry_find(name) != RT_NULL)
51+
return -RT_ERROR;
52+
53+
rt_base_t level;
54+
level = rt_spin_lock_irqsave(&procfs_lock);
55+
rt_strncpy(entry->parent.name, name, RT_NAME_MAX);
56+
rt_list_insert_after(&(procfs_root.parent.list), &(entry->parent.list));
57+
rt_spin_unlock_irqrestore(&procfs_lock, level);
58+
59+
#if defined(RT_USING_POSIX_FS)
60+
entry->fops = NULL;
61+
#endif
62+
63+
return RT_EOK;
64+
}
65+
66+
rt_err_t rt_proc_entry_unregister(rt_proc_entry_t entry)
67+
{
68+
if (entry == RT_NULL)
69+
return -RT_EINVAL;
70+
71+
rt_base_t level;
72+
level = rt_spin_lock_irqsave(&procfs_lock);
73+
rt_list_remove(&(entry->parent.list));
74+
rt_spin_unlock_irqrestore(&procfs_lock, level);
75+
76+
return RT_EOK;
77+
}
78+
79+
rt_proc_entry_t rt_proc_entry_create(int type, int attach_size)
80+
{
81+
int size;
82+
rt_proc_entry_t entry;
83+
84+
size = RT_ALIGN(sizeof(struct rt_proc_entry), RT_ALIGN_SIZE);
85+
attach_size = RT_ALIGN(attach_size, RT_ALIGN_SIZE);
86+
/* use the total size */
87+
size += attach_size;
88+
89+
entry = (rt_proc_entry_t)rt_malloc(size);
90+
if (entry)
91+
{
92+
rt_memset(entry, 0x0, sizeof(struct rt_proc_entry));
93+
entry->type = (enum rt_proc_class_type)type;
94+
}
95+
96+
return entry;
97+
}
98+
99+
void rt_proc_entry_destory(rt_proc_entry_t entry)
100+
{
101+
RT_ASSERT(entry != RT_NULL);
102+
103+
rt_free(entry);
104+
}
105+
106+
static int dfs_procfs_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void *data)
107+
{
108+
return RT_EOK;
109+
}
110+
111+
static int dfs_procfs_stat(struct dfs_dentry *dentry, struct stat *buf)
112+
{
113+
/* stat root directory */
114+
if ((dentry->pathname[0] == '/') && (dentry->pathname[1] == '\0'))
115+
{
116+
buf->st_dev = 0;
117+
buf->st_mode = S_IRUSR | S_IRGRP | S_IROTH |
118+
S_IWUSR | S_IWGRP | S_IWOTH |
119+
S_IXUSR | S_IXGRP | S_IXOTH |
120+
S_IFDIR;
121+
buf->st_size = 0;
122+
return RT_EOK;
123+
}
124+
else
125+
{
126+
rt_proc_entry_t entry_id;
127+
entry_id = rt_proc_entry_find(&dentry->pathname[1]);
128+
if (entry_id != RT_NULL)
129+
{
130+
buf->st_dev = 0;
131+
buf->st_mode = S_IRUSR | S_IRGRP | S_IROTH |
132+
S_IWUSR | S_IWGRP | S_IWOTH |
133+
S_IFREG;
134+
buf->st_size = 0;
135+
return RT_EOK;
136+
}
137+
}
138+
return -ENOENT;
139+
}
140+
141+
static struct dfs_vnode *dfs_procfs_lookup(struct dfs_dentry *dentry)
142+
{
143+
struct stat st;
144+
struct dfs_vnode *vnode;
145+
146+
if (dentry == NULL || dentry->mnt == NULL)
147+
{
148+
return NULL;
149+
}
150+
151+
if (dfs_procfs_stat(dentry, &st) != 0)
152+
{
153+
return RT_NULL;
154+
}
155+
156+
vnode = dfs_vnode_create();
157+
if (vnode)
158+
{
159+
vnode->mnt = dentry->mnt;
160+
vnode->size = st.st_size;
161+
vnode->mode = st.st_mode;
162+
if (S_ISDIR(st.st_mode))
163+
{
164+
vnode->type = FT_DIRECTORY;
165+
}
166+
else
167+
{
168+
vnode->type = FT_REGULAR;
169+
}
170+
vnode->data = NULL;
171+
}
172+
173+
return vnode;
174+
}
175+
176+
static int dfs_procfs_free_vnode(struct dfs_vnode *vnode)
177+
{
178+
return RT_EOK;
179+
}
180+
181+
static ssize_t dfs_proc_fops_read(struct dfs_file *file, void *buf, size_t count, off_t *pos)
182+
{
183+
rt_proc_entry_t entry;
184+
ssize_t result;
185+
186+
RT_ASSERT(file != RT_NULL);
187+
188+
if (file->vnode && file->vnode->data)
189+
{
190+
entry = file->vnode->data;
191+
#ifdef RT_USING_POSIX_FS
192+
if (entry->fops)
193+
{
194+
if (entry->fops->read)
195+
{
196+
result = entry->fops->read(file, buf, count, pos);
197+
if (result == RT_EOK || result == -RT_ENOSYS)
198+
{
199+
return 0;
200+
}
201+
}
202+
}
203+
#endif
204+
}
205+
206+
return -RT_EIO;
207+
}
208+
209+
static int dfs_proc_fops_close(struct dfs_file *file)
210+
{
211+
rt_err_t result = RT_EOK;
212+
rt_proc_entry_t entry;
213+
214+
RT_ASSERT(file != RT_NULL);
215+
RT_ASSERT(file->vnode->ref_count > 0);
216+
217+
if (file->vnode->ref_count > 1)
218+
{
219+
return 0;
220+
}
221+
222+
if (file->vnode && file->vnode->data)
223+
{
224+
entry = file->vnode->data;
225+
#ifdef RT_USING_POSIX_FS
226+
if (entry->fops)
227+
{
228+
if (entry->fops->close)
229+
{
230+
result = entry->fops->close(file);
231+
}
232+
}
233+
#endif
234+
}
235+
236+
file->vnode->data = RT_NULL;
237+
238+
return result;
239+
}
240+
241+
static int dfs_proc_fops_open(struct dfs_file *file)
242+
{
243+
rt_err_t result = RT_EOK;
244+
rt_proc_entry_t entry;
245+
rt_base_t level;
246+
RT_ASSERT(file->vnode->ref_count > 0);
247+
248+
if (file->vnode->ref_count > 1)
249+
{
250+
file->fpos = 0;
251+
return 0;
252+
}
253+
254+
/* open root directory */
255+
if ((file->dentry->pathname[0] == '/') && (file->dentry->pathname[1] == '\0') &&
256+
(file->flags & O_DIRECTORY))
257+
{
258+
file->vnode->data = &procfs_root;
259+
return RT_EOK;
260+
}
261+
262+
entry = rt_proc_entry_find(&file->dentry->pathname[1]);
263+
if (entry == RT_NULL)
264+
{
265+
return -ENODEV;
266+
}
267+
268+
file->vnode->data = entry;
269+
#ifdef RT_USING_POSIX_FS
270+
if (entry->fops)
271+
{
272+
if (entry->fops->open)
273+
{
274+
result = entry->fops->open(file);
275+
}
276+
}
277+
#endif
278+
279+
return result;
280+
}
281+
282+
static int dfs_proc_fops_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
283+
{
284+
rt_base_t level;
285+
rt_object_t object;
286+
rt_proc_entry_t dir;
287+
struct dirent *d;
288+
uint32_t index = 0, offset;
289+
290+
dir = (rt_proc_entry_t)file->vnode->data;
291+
RT_ASSERT(dir != RT_NULL);
292+
293+
count = (count / sizeof(struct dirent));
294+
if (count == 0)
295+
return -EINVAL;
296+
297+
offset = file->fpos / sizeof(struct dirent);
298+
level = rt_spin_lock_irqsave(&procfs_lock);
299+
rt_list_for_each_entry(object, &(dir->parent.list), list)
300+
{
301+
if (offset) {
302+
offset--;
303+
continue;
304+
}
305+
if (index >= count)
306+
break;
307+
d = dirp + index;
308+
d->d_type = DT_REG;
309+
d->d_namlen = RT_NAME_MAX;
310+
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
311+
rt_strncpy(d->d_name, object->name, RT_NAME_MAX);
312+
index++;
313+
}
314+
rt_spin_unlock_irqrestore(&procfs_lock, level);
315+
file->fpos += index * sizeof(struct dirent);
316+
317+
return index * sizeof(struct dirent);
318+
}
319+
320+
static const struct dfs_file_ops _procfs_fops =
321+
{
322+
.open = dfs_proc_fops_open,
323+
.close = dfs_proc_fops_close,
324+
.read = dfs_proc_fops_read,
325+
.getdents = dfs_proc_fops_getdents,
326+
};
327+
328+
static const struct dfs_filesystem_ops _procfs_fsops =
329+
{
330+
.name = "procfs",
331+
.flags = DFS_FS_FLAG_DEFAULT,
332+
.default_fops = &_procfs_fops,
333+
.mount = dfs_procfs_mount,
334+
.stat = dfs_procfs_stat,
335+
.lookup = dfs_procfs_lookup,
336+
.free_vnode = dfs_procfs_free_vnode,
337+
};
338+
339+
static struct dfs_filesystem_type _procfs =
340+
{
341+
&_procfs_fsops,
342+
};
343+
344+
static int procfs_init(void)
345+
{
346+
dfs_register(&_procfs);
347+
348+
return RT_EOK;
349+
}
350+
INIT_COMPONENT_EXPORT(procfs_init);

0 commit comments

Comments
 (0)