RT-Thread RTOS 1.2.0
An open source embedded real-time operating system
载入中...
搜索中...
未找到
dfs_dentry.c 文件参考
#include <rtthread.h>
#include "dfs.h"
#include "dfs_file.h"
#include "dfs_private.h"
#include "dfs_dentry.h"
#include "dfs_mnt.h"
#include <rtdbg.h>
+ dfs_dentry.c 的引用(Include)关系图:

浏览该文件的源代码.

宏定义

#define DBG_TAG   "DFS.dentry"
 
#define DBG_LVL   DBG_WARNING
 
#define DFS_DENTRY_HASH_NR   32
 

函数

struct dfs_dentrydfs_dentry_create (struct dfs_mnt *mnt, char *fullpath)
 
struct dfs_dentrydfs_dentry_create_rela (struct dfs_mnt *mnt, char *rela_path)
 
struct dfs_dentrydfs_dentry_ref (struct dfs_dentry *dentry)
 
struct dfs_dentrydfs_dentry_unref (struct dfs_dentry *dentry)
 
void dfs_dentry_insert (struct dfs_dentry *dentry)
 
struct dfs_dentrydfs_dentry_lookup (struct dfs_mnt *mnt, const char *path, uint32_t flags)
 
char * dfs_dentry_full_path (struct dfs_dentry *dentry)
 
char * dfs_dentry_pathname (struct dfs_dentry *dentry)
 
uint32_t dfs_dentry_full_path_crc32 (struct dfs_dentry *dentry)
 
int dfs_dentry_init (void)
 
int dfs_dentry_dump (int argc, char **argv)
 
 MSH_CMD_EXPORT_ALIAS (dfs_dentry_dump, dentry_dump, dump dentry in the system)
 

宏定义说明

◆ DBG_TAG

#define DBG_TAG   "DFS.dentry"

在文件 dfs_dentry.c18 行定义.

◆ DBG_LVL

#define DBG_LVL   DBG_WARNING

在文件 dfs_dentry.c19 行定义.

◆ DFS_DENTRY_HASH_NR

#define DFS_DENTRY_HASH_NR   32

在文件 dfs_dentry.c22 行定义.

函数说明

◆ dfs_dentry_create()

struct dfs_dentry * dfs_dentry_create ( struct dfs_mnt * mnt,
char * fullpath )

在文件 dfs_dentry.c78 行定义.

79{
80 return _dentry_create(mnt, fullpath, RT_FALSE);
81}
#define RT_FALSE

引用了 dfs_dentry::mnt , 以及 RT_FALSE.

+ 这是这个函数的调用关系图:

◆ dfs_dentry_create_rela()

struct dfs_dentry * dfs_dentry_create_rela ( struct dfs_mnt * mnt,
char * rela_path )

在文件 dfs_dentry.c83 行定义.

84{
85 return _dentry_create(mnt, rela_path, RT_TRUE);;
86}
#define RT_TRUE

引用了 dfs_dentry::mnt , 以及 RT_TRUE.

+ 这是这个函数的调用关系图:

◆ dfs_dentry_ref()

struct dfs_dentry * dfs_dentry_ref ( struct dfs_dentry * dentry)

在文件 dfs_dentry.c88 行定义.

89{
90 if (dentry)
91 {
92 int ret = dfs_file_lock();
93 if (ret == RT_EOK)
94 {
95 rt_atomic_add(&(dentry->ref_count), 1);
96 if (dentry->vnode)
97 {
98 rt_atomic_add(&(dentry->vnode->ref_count), 1);
99 }
101 }
102 }
103
104 return dentry;
105}
void dfs_file_unlock(void)
定义 dfs.c:164
rt_err_t dfs_file_lock(void)
定义 dfs.c:147
#define rt_atomic_add(ptr, v)
rt_atomic_t ref_count
struct dfs_vnode * vnode
rt_atomic_t ref_count

引用了 dfs_file_lock(), dfs_file_unlock(), dfs_dentry::ref_count, dfs_vnode::ref_count, rt_atomic_add , 以及 dfs_dentry::vnode.

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ dfs_dentry_unref()

struct dfs_dentry * dfs_dentry_unref ( struct dfs_dentry * dentry)

在文件 dfs_dentry.c107 行定义.

108{
109 rt_err_t ret = RT_EOK;
110
111 if (dentry)
112 {
113 ret = dfs_file_lock();
114 if (ret == RT_EOK)
115 {
116 if (dentry->flags & DENTRY_IS_ALLOCED)
117 {
118 rt_atomic_sub(&(dentry->ref_count), 1);
119 }
120
121 if (rt_atomic_load(&(dentry->ref_count)) == 0)
122 {
123 DLOG(msg, "dentry", "dentry", DLOG_MSG, "free dentry, ref_count=0");
124 if (dentry->flags & DENTRY_IS_ADDHASH)
125 {
126 rt_list_remove(&dentry->hashlist);
127 }
128
129 /* release vnode */
130 if (dentry->vnode)
131 {
132 dfs_vnode_unref(dentry->vnode);
133 }
134
135 /* release mnt */
136 DLOG(msg, "dentry", "mnt", DLOG_MSG, "dfs_mnt_unref(dentry->mnt)");
137 if (dentry->mnt)
138 {
139 dfs_mnt_unref(dentry->mnt);
140 }
141
143
144 LOG_I("free a dentry: %p", dentry);
145 rt_free(dentry->pathname);
146 rt_free(dentry);
147 dentry = RT_NULL;
148 }
149 else
150 {
151 if (dentry->vnode)
152 {
153 rt_atomic_sub(&(dentry->vnode->ref_count), 1);
154 }
156 DLOG(note, "dentry", "dentry ref_count=%d", rt_atomic_load(&(dentry->ref_count)));
157 }
158 }
159 }
160
161 return dentry;
162}
#define DENTRY_IS_ADDHASH
#define DENTRY_IS_ALLOCED
int dfs_mnt_unref(struct dfs_mnt *mnt)
void dfs_vnode_unref(struct dfs_vnode *vnode)
rt_inline void rt_list_remove(rt_list_t *n)
remove node from list.
rt_weak void rt_free(void *ptr)
This function will release the previously allocated memory block by rt_malloc. The released memory bl...
#define rt_atomic_sub(ptr, v)
#define rt_atomic_load(ptr)
#define DLOG(...)
定义 rtdbg.h:53
#define LOG_I(...)
rt_base_t rt_err_t
#define RT_NULL
rt_list_t hashlist
struct dfs_mnt * mnt

引用了 DENTRY_IS_ADDHASH, DENTRY_IS_ALLOCED, dfs_file_lock(), dfs_file_unlock(), dfs_mnt_unref(), dfs_vnode_unref(), DLOG, dfs_dentry::flags, dfs_dentry::hashlist, LOG_I, dfs_dentry::mnt, dfs_dentry::pathname, dfs_dentry::ref_count, dfs_vnode::ref_count, rt_atomic_load, rt_atomic_sub, rt_free(), rt_list_remove(), RT_NULL , 以及 dfs_dentry::vnode.

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ dfs_dentry_insert()

void dfs_dentry_insert ( struct dfs_dentry * dentry)

在文件 dfs_dentry.c188 行定义.

189{
191 rt_list_insert_after(&hash_head.head[_dentry_hash(dentry->mnt, dentry->pathname)], &dentry->hashlist);
192 dentry->flags |= DENTRY_IS_ADDHASH;
194}
rt_inline void rt_list_insert_after(rt_list_t *l, rt_list_t *n)
insert a node after a list

引用了 DENTRY_IS_ADDHASH, dfs_file_lock(), dfs_file_unlock(), dfs_dentry::flags, dfs_dentry::hashlist, dfs_dentry::mnt, dfs_dentry::pathname , 以及 rt_list_insert_after().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ dfs_dentry_lookup()

struct dfs_dentry * dfs_dentry_lookup ( struct dfs_mnt * mnt,
const char * path,
uint32_t flags )

在文件 dfs_dentry.c199 行定义.

200{
201 struct dfs_dentry *dentry;
202 struct dfs_vnode *vnode = RT_NULL;
203 int mntpoint_len = strlen(mnt->fullpath);
204
205 if (rt_strncmp(mnt->fullpath, path, mntpoint_len) == 0)
206 {
207 path += mntpoint_len;
208 if ((*path) == '\0')
209 {
210 /* root */
211 path = "/";
212 }
213 }
215 dentry = _dentry_hash_lookup(mnt, path);
216 if (!dentry)
217 {
218 if (mnt->fs_ops->lookup)
219 {
220 DLOG(activate, "dentry");
221 /* not in hash table, create it */
222 DLOG(msg, "dentry", "dentry", DLOG_MSG, "dfs_dentry_create_rela(mnt=%s, path=%s)", mnt->fullpath, path);
223 dentry = dfs_dentry_create_rela(mnt, (char*)path);
224 if (dentry)
225 {
226 DLOG(msg, "dentry", mnt->fs_ops->name, DLOG_MSG, "vnode=fs_ops->lookup(dentry)");
227
228 if (dfs_is_mounted(mnt) == 0)
229 {
230 vnode = mnt->fs_ops->lookup(dentry);
231 }
232
233 if (vnode)
234 {
235 DLOG(msg, mnt->fs_ops->name, "dentry", DLOG_MSG_RET, "return vnode");
236 dentry->vnode = vnode; /* the refcount of created vnode is 1. no need to reference */
238 rt_list_insert_after(&hash_head.head[_dentry_hash(mnt, path)], &dentry->hashlist);
239 dentry->flags |= DENTRY_IS_ADDHASH;
241
243 && !(dentry->flags & DENTRY_IS_OPENED))
244 {
245 rt_err_t ret = dfs_file_lock();
246 if (ret == RT_EOK)
247 {
248 dentry->flags |= DENTRY_IS_OPENED;
250 }
251 }
252 }
253 else
254 {
255 DLOG(msg, mnt->fs_ops->name, "dentry", DLOG_MSG_RET, "no dentry");
256
257 DLOG(msg, "dentry", "dentry", DLOG_MSG, "dfs_dentry_unref(dentry)");
258 dfs_dentry_unref(dentry);
259 dentry = RT_NULL;
260 }
261 }
262 DLOG(deactivate, "dentry");
263 }
264 }
265 else
266 {
267 DLOG(note, "dentry", "found dentry");
268 }
270 return dentry;
271}
struct dfs_dentry * dfs_dentry_unref(struct dfs_dentry *dentry)
struct dfs_dentry * dfs_dentry_create_rela(struct dfs_mnt *mnt, char *rela_path)
#define DENTRY_IS_OPENED
int dfs_is_mounted(struct dfs_mnt *mnt)
struct dfs_vnode *(* lookup)(struct dfs_dentry *dentry)
const char * name
char * fullpath
const struct dfs_filesystem_ops * fs_ops
struct dfs_mnt * mnt

引用了 DENTRY_IS_ADDHASH, DENTRY_IS_ALLOCED, DENTRY_IS_OPENED, dfs_dentry_create_rela(), dfs_dentry_unref(), dfs_file_lock(), dfs_file_unlock(), dfs_is_mounted(), DLOG, dfs_dentry::flags, dfs_mnt::fs_ops, dfs_mnt::fullpath, dfs_dentry::hashlist, dfs_filesystem_ops::lookup, dfs_vnode::mnt, dfs_filesystem_ops::name, rt_list_insert_after(), RT_NULL , 以及 dfs_dentry::vnode.

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ dfs_dentry_full_path()

char * dfs_dentry_full_path ( struct dfs_dentry * dentry)

在文件 dfs_dentry.c273 行定义.

274{
275 char *path = NULL;
276
277 if (dentry && dentry->mnt)
278 {
279 int mnt_len = strlen(dentry->mnt->fullpath);
280 int path_len = strlen(dentry->pathname);
281
282 path = (char *) rt_malloc(mnt_len + path_len + 3);
283 if (path)
284 {
285 if (dentry->pathname[0] == '/' || dentry->mnt->fullpath[mnt_len - 1] == '/')
286 {
287 rt_snprintf(path, mnt_len + path_len + 2, "%s%s", dentry->mnt->fullpath,
288 dentry->pathname);
289 }
290 else
291 {
292 rt_snprintf(path, mnt_len + path_len + 2, "%s/%s", dentry->mnt->fullpath,
293 dentry->pathname);
294 }
295 }
296 }
297
298 return path;
299}
rt_weak void * rt_malloc(rt_size_t size)
Allocate a block of memory with a minimum of 'size' bytes.

引用了 dfs_mnt::fullpath, dfs_dentry::mnt, dfs_dentry::pathname , 以及 rt_malloc().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ dfs_dentry_pathname()

char * dfs_dentry_pathname ( struct dfs_dentry * dentry)

在文件 dfs_dentry.c301 行定义.

302{
303 char *pathname = RT_NULL;
304 char *index = RT_NULL;
305
306 index = strrchr(dentry->pathname, '/');
307 if (index)
308 {
309 int length = index - dentry->pathname;
310 int path_length = strlen(dentry->mnt->fullpath) + length + 3;
311
312 pathname = (char*) rt_malloc(path_length);
313 if (pathname)
314 {
315 if (dentry->pathname[0] == '/')
316 {
317 rt_snprintf(pathname, path_length - 1, "%s%.*s", dentry->mnt->fullpath,
318 length, dentry->pathname);
319 }
320 else
321 {
322 rt_snprintf(pathname, path_length - 1, "%s/%.*s", dentry->mnt->fullpath,
323 length, dentry->pathname);
324 }
325 }
326 }
327 else
328 {
329 pathname = rt_strdup(dentry->mnt->fullpath);
330 }
331
332 return pathname;
333}

引用了 dfs_mnt::fullpath, dfs_dentry::mnt, dfs_dentry::pathname, rt_malloc() , 以及 RT_NULL.

+ 函数调用图:

◆ dfs_dentry_full_path_crc32()

uint32_t dfs_dentry_full_path_crc32 ( struct dfs_dentry * dentry)

在文件 dfs_dentry.c335 行定义.

336{
337 uint32_t crc32 = 0xFFFFFFFF;
338 char *fullpath = dfs_dentry_full_path(dentry);
339 if (fullpath)
340 {
341 int i = 0;
342
343 while(fullpath[i] != '\0')
344 {
345 for (uint8_t b = 1; b; b <<= 1)
346 {
347 crc32 ^= (fullpath[i] & b) ? 1 : 0;
348 crc32 = (crc32 & 1) ? crc32 >> 1 ^ 0xEDB88320 : crc32 >> 1;
349 }
350 i ++;
351 }
352 rt_free(fullpath);
353 }
354 return crc32;
355}
char * dfs_dentry_full_path(struct dfs_dentry *dentry)

引用了 dfs_dentry_full_path() , 以及 rt_free().

+ 函数调用图:

◆ dfs_dentry_init()

int dfs_dentry_init ( void )

在文件 dfs_dentry.c357 行定义.

358{
359 int i = 0;
360
361 for(i = 0; i < DFS_DENTRY_HASH_NR; i++)
362 {
363 rt_list_init(&hash_head.head[i]);
364 }
365
366 return 0;
367}
#define DFS_DENTRY_HASH_NR
rt_inline void rt_list_init(rt_list_t *l)
initialize a list

引用了 DFS_DENTRY_HASH_NR , 以及 rt_list_init().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ dfs_dentry_dump()

int dfs_dentry_dump ( int argc,
char ** argv )

在文件 dfs_dentry.c369 行定义.

370{
371 int index = 0;
372 struct dfs_dentry *entry = RT_NULL;
373
374 dfs_lock();
375 for (index = 0; index < DFS_DENTRY_HASH_NR; index ++)
376 {
377 rt_list_for_each_entry(entry, &hash_head.head[index], hashlist)
378 {
379 printf("dentry: %s%s @ %p, ref_count = %zd\n", entry->mnt->fullpath, entry->pathname, entry, (size_t)rt_atomic_load(&entry->ref_count));
380 }
381 }
382 dfs_unlock();
383
384 return 0;
385}
rt_err_t dfs_lock(void)
定义 dfs.c:120
void dfs_unlock(void)
定义 dfs.c:137
#define rt_list_for_each_entry(pos, head, member)

引用了 DFS_DENTRY_HASH_NR, dfs_lock(), dfs_unlock(), dfs_mnt::fullpath, dfs_dentry::hashlist, dfs_dentry::mnt, dfs_dentry::pathname, dfs_dentry::ref_count, rt_atomic_load, rt_list_for_each_entry , 以及 RT_NULL.

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ MSH_CMD_EXPORT_ALIAS()

MSH_CMD_EXPORT_ALIAS ( dfs_dentry_dump ,
dentry_dump ,
dump dentry in the system )

引用了 dfs_dentry_dump().

+ 函数调用图: