RT-Thread RTOS 1.2.0
An open source embedded real-time operating system
载入中...
搜索中...
未找到
dfs_file.h 文件参考
#include <dfs.h>
#include <dfs_fs.h>
+ dfs_file.h 的引用(Include)关系图:
+ 此图展示该文件被哪些文件直接或间接地引用了:

浏览该文件的源代码.

结构体

struct  dfs_file_ops
 
struct  dfs_vnode
 
struct  dfs_file
 

宏定义

#define STDIN_FILENO   0 /* standard input file descriptor */
 
#define STDOUT_FILENO   1 /* standard output file descriptor */
 
#define STDERR_FILENO   2 /* standard error file descriptor */
 
#define DFS_FD_MAGIC   0xfdfd
 
#define DFS_FILE_POS(dfs_file)
 
#define FMODE_READ   0x1
 
#define FMODE_WRITE   0x2
 
#define FMODE_LSEEK   0x4
 
#define FMODE_PREAD   0x8
 
#define FMODE_PWRITE   0x10
 
#define FMODE_EXEC   0x20
 
#define FMODE_NDELAY   0x40
 
#define FMODE_EXCL   0x80
 
#define RT_FIOFTRUNCATE   0x52540000U
 
#define RT_FIOGETADDR   0x52540001U
 
#define RT_FIOMMAP2   0x52540002U
 
#define DFS_REALPATH_EXCEPT_LAST   0
 
#define DFS_REALPATH_EXCEPT_NONE   1
 
#define DFS_REALPATH_ONLY_LAST   3
 

函数

int dfs_vnode_init (struct dfs_vnode *vnode, int type, const struct dfs_file_ops *fops)
 
struct dfs_vnodedfs_vnode_create (void)
 
int dfs_vnode_destroy (struct dfs_vnode *vnode)
 
struct dfs_vnodedfs_vnode_ref (struct dfs_vnode *vnode)
 
void dfs_vnode_unref (struct dfs_vnode *vnode)
 
void dfs_file_init (struct dfs_file *file)
 
void dfs_file_deinit (struct dfs_file *file)
 
int dfs_file_open (struct dfs_file *file, const char *path, int flags, mode_t mode)
 
int dfs_file_close (struct dfs_file *file)
 
off_t dfs_file_get_fpos (struct dfs_file *file)
 
void dfs_file_set_fpos (struct dfs_file *file, off_t fpos)
 
ssize_t dfs_file_pread (struct dfs_file *file, void *buf, size_t len, off_t offset)
 
ssize_t dfs_file_read (struct dfs_file *file, void *buf, size_t len)
 
ssize_t dfs_file_pwrite (struct dfs_file *file, const void *buf, size_t len, off_t offset)
 
ssize_t dfs_file_write (struct dfs_file *file, const void *buf, size_t len)
 
off_t generic_dfs_lseek (struct dfs_file *file, off_t offset, int whence)
 
off_t dfs_file_lseek (struct dfs_file *file, off_t offset, int wherece)
 
int dfs_file_stat (const char *path, struct stat *buf)
 
int dfs_file_lstat (const char *path, struct stat *buf)
 
int dfs_file_setattr (const char *path, struct dfs_attr *attr)
 
int dfs_file_fstat (struct dfs_file *file, struct stat *buf)
 
int dfs_file_ioctl (struct dfs_file *file, int cmd, void *args)
 
int dfs_file_fcntl (int fd, int cmd, unsigned long arg)
 
int dfs_file_fsync (struct dfs_file *file)
 
int dfs_file_unlink (const char *path)
 
int dfs_file_link (const char *oldname, const char *newname)
 
int dfs_file_symlink (const char *oldname, const char *name)
 
int dfs_file_readlink (const char *path, char *buf, int bufsize)
 
int dfs_file_rename (const char *old_file, const char *new_file)
 
int dfs_file_ftruncate (struct dfs_file *file, off_t length)
 
int dfs_file_getdents (struct dfs_file *file, struct dirent *dirp, size_t nbytes)
 
int dfs_file_mkdir (const char *path, mode_t mode)
 
int dfs_file_rmdir (const char *pathname)
 
int dfs_file_isdir (const char *path)
 
int dfs_file_access (const char *path, mode_t mode)
 
int dfs_file_chdir (const char *path)
 
char * dfs_file_getcwd (char *buf, size_t size)
 
char * dfs_file_realpath (struct dfs_mnt **mnt, const char *fullpath, int mode)
 

宏定义说明

◆ STDIN_FILENO

#define STDIN_FILENO   0 /* standard input file descriptor */

在文件 dfs_file.h23 行定义.

◆ STDOUT_FILENO

#define STDOUT_FILENO   1 /* standard output file descriptor */

在文件 dfs_file.h24 行定义.

◆ STDERR_FILENO

#define STDERR_FILENO   2 /* standard error file descriptor */

在文件 dfs_file.h25 行定义.

◆ DFS_FD_MAGIC

#define DFS_FD_MAGIC   0xfdfd

在文件 dfs_file.h84 行定义.

◆ DFS_FILE_POS

#define DFS_FILE_POS ( dfs_file)
值:

在文件 dfs_file.h104 行定义.

◆ FMODE_READ

#define FMODE_READ   0x1

在文件 dfs_file.h107 行定义.

◆ FMODE_WRITE

#define FMODE_WRITE   0x2

在文件 dfs_file.h109 行定义.

◆ FMODE_LSEEK

#define FMODE_LSEEK   0x4

在文件 dfs_file.h111 行定义.

◆ FMODE_PREAD

#define FMODE_PREAD   0x8

在文件 dfs_file.h113 行定义.

◆ FMODE_PWRITE

#define FMODE_PWRITE   0x10

在文件 dfs_file.h115 行定义.

◆ FMODE_EXEC

#define FMODE_EXEC   0x20

在文件 dfs_file.h117 行定义.

◆ FMODE_NDELAY

#define FMODE_NDELAY   0x40

在文件 dfs_file.h119 行定义.

◆ FMODE_EXCL

#define FMODE_EXCL   0x80

在文件 dfs_file.h121 行定义.

◆ RT_FIOFTRUNCATE

#define RT_FIOFTRUNCATE   0x52540000U

在文件 dfs_file.h188 行定义.

◆ RT_FIOGETADDR

#define RT_FIOGETADDR   0x52540001U

在文件 dfs_file.h189 行定义.

◆ RT_FIOMMAP2

#define RT_FIOMMAP2   0x52540002U

在文件 dfs_file.h190 行定义.

◆ DFS_REALPATH_EXCEPT_LAST

#define DFS_REALPATH_EXCEPT_LAST   0

在文件 dfs_file.h193 行定义.

◆ DFS_REALPATH_EXCEPT_NONE

#define DFS_REALPATH_EXCEPT_NONE   1

在文件 dfs_file.h194 行定义.

◆ DFS_REALPATH_ONLY_LAST

#define DFS_REALPATH_ONLY_LAST   3

在文件 dfs_file.h195 行定义.

函数说明

◆ dfs_vnode_init()

int dfs_vnode_init ( struct dfs_vnode * vnode,
int type,
const struct dfs_file_ops * fops )

在文件 dfs_vnode.c21 行定义.

22{
23 if (vnode)
24 {
25 rt_memset(vnode, 0, sizeof(struct dfs_vnode));
26
27 vnode->type = type;
28 rt_atomic_store(&(vnode->ref_count), 1);
29 vnode->mnt = RT_NULL;
30 vnode->fops = fops;
31 }
32
33 return 0;
34}
#define rt_atomic_store(ptr, v)
#define RT_NULL
struct dfs_mnt * mnt
const struct dfs_file_ops * fops
rt_atomic_t ref_count

引用了 dfs_vnode::fops, dfs_vnode::mnt, dfs_vnode::ref_count, rt_atomic_store, RT_NULL , 以及 dfs_vnode::type.

◆ dfs_vnode_create()

struct dfs_vnode * dfs_vnode_create ( void )

在文件 dfs_vnode.c36 行定义.

37{
38 struct dfs_vnode *vnode = rt_calloc(1, sizeof(struct dfs_vnode));
39 if (!vnode)
40 {
41 LOG_E("create a vnode failed.");
42 return RT_NULL;
43 }
44
45 rt_atomic_store(&(vnode->ref_count), 1);
46
47 LOG_I("create a vnode: %p", vnode);
48
49 return vnode;
50}
rt_weak void * rt_calloc(rt_size_t count, rt_size_t size)
This function will contiguously allocate enough space for count objects that are size bytes of memory...
#define LOG_E(fmt,...)
#define LOG_I(...)

引用了 LOG_E, LOG_I, dfs_vnode::ref_count, rt_atomic_store, rt_calloc() , 以及 RT_NULL.

+ 函数调用图:

◆ dfs_vnode_destroy()

int dfs_vnode_destroy ( struct dfs_vnode * vnode)

在文件 dfs_vnode.c52 行定义.

53{
54 rt_err_t ret = RT_EOK;
55
56 if (vnode)
57 {
58 ret = dfs_file_lock();
59 if (ret == RT_EOK)
60 {
61 if (rt_atomic_load(&(vnode->ref_count)) == 1)
62 {
63 LOG_I("free a vnode: %p", vnode);
64#ifdef RT_USING_PAGECACHE
65 if (vnode->aspace)
66 {
67 dfs_aspace_destroy(vnode->aspace);
68 }
69#endif
70 if (vnode->mnt)
71 {
72 DLOG(msg, "vnode", vnode->mnt->fs_ops->name, DLOG_MSG, "fs_ops->free_vnode");
73 vnode->mnt->fs_ops->free_vnode(vnode);
74 }
75 else
76 {
77 DLOG(msg, "vnode", "vnode", DLOG_MSG, "destroy vnode(mnt=NULL)");
78 }
79
81
82 rt_free(vnode);
83 }
84 else
85 {
87 }
88 }
89 }
90
91 return 0;
92}
void dfs_file_unlock(void)
定义 dfs.c:164
rt_err_t dfs_file_lock(void)
定义 dfs.c:147
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_load(ptr)
#define DLOG(...)
定义 rtdbg.h:53
rt_base_t rt_err_t
int(* free_vnode)(struct dfs_vnode *vnode)
const char * name
const struct dfs_filesystem_ops * fs_ops
struct dfs_aspace * aspace

引用了 dfs_vnode::aspace, dfs_file_lock(), dfs_file_unlock(), DLOG, dfs_filesystem_ops::free_vnode, dfs_mnt::fs_ops, LOG_I, dfs_vnode::mnt, dfs_filesystem_ops::name, dfs_vnode::ref_count, rt_atomic_load , 以及 rt_free().

+ 函数调用图:

◆ dfs_vnode_ref()

struct dfs_vnode * dfs_vnode_ref ( struct dfs_vnode * vnode)

在文件 dfs_vnode.c94 行定义.

95{
96 if (vnode)
97 {
98 rt_atomic_add(&(vnode->ref_count), 1);
99
100 DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count)));
101 }
102
103 return vnode;
104}
#define rt_atomic_add(ptr, v)

引用了 DLOG, dfs_vnode::ref_count, rt_atomic_add , 以及 rt_atomic_load.

◆ dfs_vnode_unref()

void dfs_vnode_unref ( struct dfs_vnode * vnode)

在文件 dfs_vnode.c106 行定义.

107{
108 rt_err_t ret = RT_EOK;
109
110 if (vnode)
111 {
112 ret = dfs_file_lock();
113 if (ret == RT_EOK)
114 {
115 rt_atomic_sub(&(vnode->ref_count), 1);
116 DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count)));
117#ifdef RT_USING_PAGECACHE
118 if (vnode->aspace)
119 {
120 dfs_aspace_destroy(vnode->aspace);
121 }
122#endif
123 if (rt_atomic_load(&(vnode->ref_count)) == 0)
124 {
125 LOG_I("free a vnode: %p", vnode);
126 DLOG(msg, "vnode", "vnode", DLOG_MSG, "free vnode, ref_count=0");
127
128 if (vnode->mnt)
129 {
130 DLOG(msg, "vnode", vnode->mnt->fs_ops->name, DLOG_MSG, "fs_ops->free_vnode");
131 vnode->mnt->fs_ops->free_vnode(vnode);
132 }
133
135
136 rt_free(vnode);
137 }
138 else
139 {
141 DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count)));
142 }
143 }
144 }
145
146 return;
147}
#define rt_atomic_sub(ptr, v)

引用了 dfs_vnode::aspace, dfs_file_lock(), dfs_file_unlock(), DLOG, dfs_filesystem_ops::free_vnode, dfs_mnt::fs_ops, LOG_I, dfs_vnode::mnt, dfs_filesystem_ops::name, dfs_vnode::ref_count, rt_atomic_load, rt_atomic_sub , 以及 rt_free().

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

◆ dfs_file_init()

void dfs_file_init ( struct dfs_file * file)

在文件 dfs_file.c189 行定义.

190{
191 if (file)
192 {
193 rt_memset(file, 0x00, sizeof(struct dfs_file));
194 file->magic = DFS_FD_MAGIC;
195 rt_mutex_init(&file->pos_lock, "fpos", RT_IPC_FLAG_PRIO);
196 rt_atomic_store(&(file->ref_count), 1);
197 }
198}
#define DFS_FD_MAGIC
#define RT_IPC_FLAG_PRIO
rt_err_t rt_mutex_init(rt_mutex_t mutex, const char *name, rt_uint8_t flag)
Initialize a static mutex object.
定义 ipc.c:1007
uint16_t magic
struct rt_mutex pos_lock
rt_atomic_t ref_count

引用了 DFS_FD_MAGIC, dfs_file::magic, dfs_file::pos_lock, dfs_file::ref_count, rt_atomic_store, RT_IPC_FLAG_PRIO , 以及 rt_mutex_init().

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

◆ dfs_file_deinit()

void dfs_file_deinit ( struct dfs_file * file)

在文件 dfs_file.c200 行定义.

201{
202 if (file)
203 {
205 }
206}
rt_err_t rt_mutex_detach(rt_mutex_t mutex)
This function will detach a static mutex object.
定义 ipc.c:1054

引用了 dfs_file::pos_lock , 以及 rt_mutex_detach().

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

◆ dfs_file_open()

int dfs_file_open ( struct dfs_file * file,
const char * path,
int oflags,
mode_t mode )

this function will open a file which specified by path with specified oflags.

参数
fdthe file descriptor pointer to return the corresponding result.
paththe specified file path.
oflagsthe oflags for open operator.
返回
0 on successful, -1 on failed.

在文件 dfs_file.c409 行定义.

410{
411 int ret = -RT_ERROR;
412 char *fullpath = RT_NULL;
413 struct dfs_dentry *dentry = RT_NULL;
414 int fflags = dfs_fflags(oflags);
415
416 if (mode == 0)
417 {
418 mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); /* 0666 */
419 }
420
421 if (file && path)
422 {
423 fullpath = dfs_normalize_path(NULL, path);
424 if (fullpath)
425 {
426 struct dfs_mnt *mnt = RT_NULL;
427
428 DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath);
430 if (mnt)
431 {
433 if (tmp)
434 {
436 fullpath = tmp;
437 }
438
439 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_lookup(mnt, %s)", fullpath);
440 dentry = dfs_dentry_lookup(mnt, fullpath, oflags);
441 if (dentry && dentry->vnode->type == FT_SYMLINK)
442 {
443 /* it's a symbol link but not follow */
444 if (oflags & O_NOFOLLOW)
445 {
446 /* no follow symbol link */
447 dfs_dentry_unref(dentry);
448 dentry = RT_NULL;
449 }
450 else
451 {
452 struct dfs_dentry *target_dentry = RT_NULL;
453 char *path = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_ONLY_LAST);
454 if (path)
455 {
456 target_dentry = dfs_dentry_lookup(mnt, path, oflags);
457 rt_free(path);
458 }
459 dfs_dentry_unref(dentry);
460 dentry = target_dentry;
461 }
462 }
463
464 if (dentry)
465 {
466 if (oflags & O_DIRECTORY)
467 {
468 if (dentry->vnode->type != FT_DIRECTORY)
469 {
470 dfs_dentry_unref(dentry);
471 dentry = RT_NULL;
472 }
473 }
474 else if (dentry->vnode->type == FT_DIRECTORY)
475 {
476 if (fflags & (DFS_F_FWRITE))
477 {
478 dfs_dentry_unref(dentry);
479 dentry = RT_NULL;
480 }
481 else
482 {
483 oflags |= O_DIRECTORY;
484 }
485 }
486 }
487
488 if (oflags & O_CREAT)
489 {
490 if (dentry)
491 {
492 oflags &= ~O_CREAT;
493
494 if (oflags & O_EXCL)
495 {
496 oflags &= ~O_EXCL;
497 /* the dentry already exists */
498 dfs_dentry_unref(dentry);
499 ret = -EEXIST;
500 goto _ERR_RET;
501 }
502 }
503 else
504 {
505 /* create file/directory */
506 if (mnt->fs_ops->create_vnode)
507 {
508 struct dfs_vnode *vnode = RT_NULL;
509
510 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_create(%s)", fullpath);
512 dentry = dfs_dentry_create(mnt, fullpath);
513 if (dentry)
514 {
515 DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->create_vnode");
516
517 if (dfs_is_mounted(mnt) == 0)
518 {
519 vnode = mnt->fs_ops->create_vnode(dentry, oflags & O_DIRECTORY ? FT_DIRECTORY:FT_REGULAR, mode);
520 }
521
522 if (vnode)
523 {
524 /* set vnode */
525 dentry->vnode = vnode; /* the refcount of created vnode is 1. no need to reference */
526 dfs_dentry_insert(dentry);
527 }
528 else
529 {
530 DLOG(msg, mnt->fs_ops->name, "dfs_file", DLOG_MSG_RET, "create failed.");
531 dfs_dentry_unref(dentry);
532 dentry = RT_NULL;
533 }
534 }
536 }
537 }
538 }
539
540 if (dentry)
541 {
542 rt_bool_t permission = RT_TRUE;
543 file->dentry = dentry;
544 file->vnode = dentry->vnode;
545 file->fops = dentry->mnt->fs_ops->default_fops;
546 file->flags = oflags;
547
548 /* check permission */
549 if (!(oflags & O_CREAT))
550 {
551 if (fflags & DFS_F_FWRITE)
552 {
553 if (!(file->vnode->mode & S_IWUSR))
554 {
555 permission = RT_FALSE;
556 }
557 }
558
559 if (fflags & DFS_F_FREAD)
560 {
561 if (!(file->vnode->mode & S_IRUSR))
562 {
563 permission = RT_FALSE;
564 }
565 }
566
567 if (oflags & O_EXEC)
568 {
569 if (!(file->vnode->mode & S_IXUSR))
570 {
571 permission = RT_FALSE;
572 }
573 }
574 }
575
576 if (permission && file->fops->open)
577 {
578 DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fops->open(file)");
579
580 if (dfs_is_mounted(file->vnode->mnt) == 0)
581 {
583 ret = file->fops->open(file);
585 }
586 else
587 {
588 ret = -EINVAL;
589 }
590
591 if (ret < 0)
592 {
593 LOG_I("open %s failed in file system: %s", path, dentry->mnt->fs_ops->name);
594 DLOG(msg, mnt->fs_ops->name, "dfs_file", DLOG_MSG_RET, "open failed.");
595 dfs_file_unref(file);
596 }
597 else
598 {
599 /* for char/block device */
600 if ((S_ISCHR(file->vnode->mode)) || (S_ISBLK(file->vnode->mode)))
601 {
602 file->fops = file->vnode->fops;
603 }
604 }
605 }
606 else
607 {
608 DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "no permission or fops->open");
609 dfs_file_unref(file);
610 ret = -EPERM;
611 }
612 }
613 else
614 {
615 LOG_I("lookup file:%s failed in file system", path);
616 ret = -ENOENT;
617 }
618 }
619 }
620
621 if (ret >= 0 && (oflags & O_TRUNC))
622 {
623 /* trunc file */
624 if (!(fflags & DFS_F_FWRITE) || file->vnode->type == FT_DIRECTORY)
625 {
626 /* truncate on read a only file or a directory */
627 DLOG(msg, "dfs_file", "dfs_file", DLOG_MSG, "dfs_file_unref(file), trunc on RDOnly or directory");
628 ret = -RT_ERROR;
629 }
630 else
631 {
632 if (file->fops->truncate)
633 {
634 DLOG(msg, "dfs_file", dentry->mnt->fs_ops->name, DLOG_MSG, "fops->truncate(file, 0)");
635
636 if (dfs_is_mounted(file->vnode->mnt) == 0)
637 {
638#ifdef RT_USING_PAGECACHE
639 if (file->vnode->aspace)
640 {
641 dfs_aspace_clean(file->vnode->aspace);
642 }
643#endif
644 ret = file->fops->truncate(file, 0);
645 }
646 else
647 {
648 ret = -EINVAL;
649 }
650 }
651 }
652
653 if (ret < 0)
654 {
655 dfs_file_unref(file);
656 }
657
658 file->flags &= ~O_TRUNC;
659 }
660 }
661
662_ERR_RET:
663 if (fullpath != NULL)
664 {
665 rt_free(fullpath);
666 }
667 return ret;
668}
#define DFS_F_FWRITE
定义 dfs.h:84
#define DFS_F_FREAD
定义 dfs.h:83
rt_inline int dfs_fflags(int oflags)
定义 dfs.h:90
struct dfs_dentry * dfs_dentry_create(struct dfs_mnt *mnt, char *fullpath)
struct dfs_dentry * dfs_dentry_lookup(struct dfs_mnt *mnt, const char *path, uint32_t flags)
struct dfs_dentry * dfs_dentry_unref(struct dfs_dentry *dentry)
void dfs_dentry_insert(struct dfs_dentry *dentry)
char * dfs_file_realpath(struct dfs_mnt **mnt, const char *fullpath, int mode)
#define DFS_REALPATH_ONLY_LAST
#define DFS_REALPATH_EXCEPT_LAST
int dfs_is_mounted(struct dfs_mnt *mnt)
struct dfs_mnt * dfs_mnt_lookup(const char *fullpath)
char * dfs_normalize_path(const char *directory, const char *filename)
定义 dfs.c:779
int rt_bool_t
#define RT_TRUE
#define RT_FALSE
struct dfs_mnt * mnt
struct dfs_vnode * vnode
int(* truncate)(struct dfs_file *file, off_t offset)
int(* open)(struct dfs_file *file)
struct dfs_vnode * vnode
struct dfs_dentry * dentry
const struct dfs_file_ops * fops
uint32_t flags
const struct dfs_file_ops * default_fops
struct dfs_vnode *(* create_vnode)(struct dfs_dentry *dentry, int type, mode_t mode)
char * fullpath
uint32_t mode

引用了 dfs_vnode::aspace, dfs_filesystem_ops::create_vnode, dfs_filesystem_ops::default_fops, dfs_file::dentry, dfs_dentry_create(), dfs_dentry_insert(), dfs_dentry_lookup(), dfs_dentry_unref(), DFS_F_FREAD, DFS_F_FWRITE, dfs_fflags(), dfs_file_lock(), dfs_file_realpath(), dfs_file_unlock(), dfs_is_mounted(), dfs_mnt_lookup(), dfs_normalize_path(), DFS_REALPATH_EXCEPT_LAST, DFS_REALPATH_ONLY_LAST, DLOG, dfs_file::flags, dfs_file::fops, dfs_vnode::fops, dfs_mnt::fs_ops, dfs_mnt::fullpath, LOG_I, dfs_dentry::mnt, dfs_vnode::mnt, dfs_vnode::mode, dfs_filesystem_ops::name, dfs_file_ops::open, RT_FALSE, rt_free(), RT_NULL, RT_TRUE, dfs_file_ops::truncate, dfs_vnode::type, dfs_dentry::vnode , 以及 dfs_file::vnode.

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

◆ dfs_file_close()

int dfs_file_close ( struct dfs_file * file)

在文件 dfs_file.c670 行定义.

671{
672 int ret = -RT_ERROR;
673
674 if (file)
675 {
676 if (dfs_file_lock() == RT_EOK)
677 {
678 rt_atomic_t ref_count = rt_atomic_load(&(file->ref_count));
679
680 if (ref_count == 1 && file->fops && file->fops->close)
681 {
682 DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "fops->close(file)");
683#ifdef RT_USING_PAGECACHE
684 if (file->vnode->aspace)
685 {
686 dfs_aspace_flush(file->vnode->aspace);
687 }
688#endif
689 ret = file->fops->close(file);
690
691 if (ret == 0) /* close file sucessfully */
692 {
693 DLOG(msg, "dfs_file", "dfs_file", DLOG_MSG, "dfs_file_unref(file)");
694 dfs_file_unref(file);
695 }
696 else
697 {
698 LOG_W("close file:%s failed on low level file system", file->dentry->pathname);
699 }
700 }
701 else
702 {
703 DLOG(msg, "dfs_file", "dfs_file", DLOG_MSG, "dfs_file_unref(file)");
704 dfs_file_unref(file);
705 ret = 0;
706 }
708 }
709 }
710
711 return ret;
712}
#define LOG_W(...)
rt_base_t rt_atomic_t
int(* close)(struct dfs_file *file)

引用了 dfs_vnode::aspace, dfs_file_ops::close, dfs_file::dentry, dfs_file_lock(), dfs_file_unlock(), DLOG, dfs_file::fops, dfs_mnt::fs_ops, LOG_W, dfs_dentry::mnt, dfs_filesystem_ops::name, dfs_dentry::pathname, dfs_file::ref_count, dfs_vnode::ref_count, rt_atomic_load , 以及 dfs_file::vnode.

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

◆ dfs_file_get_fpos()

off_t dfs_file_get_fpos ( struct dfs_file * file)

在文件 dfs_file.c162 行定义.

163{
164 if (file)
165 {
166 if (file->vnode->type == FT_REGULAR)
167 {
169 }
170 return file->fpos;
171 }
172
173 return 0;
174}
#define RT_WAITING_FOREVER
rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time)
定义 ipc.c:1537

引用了 dfs_file::fpos, dfs_file::pos_lock, rt_mutex_take(), RT_WAITING_FOREVER, dfs_vnode::type , 以及 dfs_file::vnode.

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

◆ dfs_file_set_fpos()

void dfs_file_set_fpos ( struct dfs_file * file,
off_t fpos )

在文件 dfs_file.c176 行定义.

177{
178 if (file)
179 {
180 if (file->vnode->type != FT_REGULAR)
181 {
183 }
184 file->fpos = fpos;
186 }
187}
rt_err_t rt_mutex_release(rt_mutex_t mutex)
This function will release a mutex. If there is thread suspended on the mutex, the thread will be res...
定义 ipc.c:1589

引用了 dfs_file::fpos, dfs_file::pos_lock, rt_mutex_release(), rt_mutex_take(), RT_WAITING_FOREVER, dfs_vnode::type , 以及 dfs_file::vnode.

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

◆ dfs_file_pread()

ssize_t dfs_file_pread ( struct dfs_file * file,
void * buf,
size_t len,
off_t offset )

在文件 dfs_file.c714 行定义.

715{
716 ssize_t ret = -EBADF;
717
718 if (file)
719 {
720 /* check whether read */
721 if (!(dfs_fflags(file->flags) & DFS_F_FREAD))
722 {
723 ret = -EPERM;
724 }
725 else if (!file->fops || !file->fops->read)
726 {
727 ret = -ENOSYS;
728 }
729 else if (file->vnode && file->vnode->type != FT_DIRECTORY)
730 {
731 off_t pos = offset;
732
733 ret = rw_verify_area(file, &pos, len);
734 if (ret > 0)
735 {
736 len = ret;
737
738 if (dfs_is_mounted(file->vnode->mnt) == 0)
739 {
740#ifdef RT_USING_PAGECACHE
741 if (file->vnode->aspace && !(file->flags & O_DIRECT))
742 {
743 ret = dfs_aspace_read(file, buf, len, &pos);
744 }
745 else
746#endif
747 {
748 ret = file->fops->read(file, buf, len, &pos);
749 }
750 }
751 else
752 {
753 ret = -EINVAL;
754 }
755 }
756 }
757 }
758
759 return ret;
760}
ssize_t rw_verify_area(struct dfs_file *file, off_t *ppos, size_t count)
ssize_t(* read)(struct dfs_file *file, void *buf, size_t count, off_t *pos)

引用了 dfs_vnode::aspace, DFS_F_FREAD, dfs_fflags(), dfs_is_mounted(), dfs_file::flags, dfs_file::fops, dfs_vnode::mnt, dfs_file_ops::read, rw_verify_area(), dfs_vnode::type , 以及 dfs_file::vnode.

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

◆ dfs_file_read()

ssize_t dfs_file_read ( struct dfs_file * file,
void * buf,
size_t len )

在文件 dfs_file.c762 行定义.

763{
764 ssize_t ret = -EBADF;
765
766 if (file)
767 {
768 /* check whether read */
769 if (!(dfs_fflags(file->flags) & DFS_F_FREAD))
770 {
771 ret = -EPERM;
772 }
773 else if (!file->fops || !file->fops->read)
774 {
775 ret = -ENOSYS;
776 }
777 else if (file->vnode && file->vnode->type != FT_DIRECTORY)
778 {
779 /* fpos lock */
780 off_t pos = dfs_file_get_fpos(file);
781
782 ret = rw_verify_area(file, &pos, len);
783 if (ret > 0)
784 {
785 len = ret;
786
787 if (dfs_is_mounted(file->vnode->mnt) == 0)
788 {
789#ifdef RT_USING_PAGECACHE
790 if (file->vnode->aspace && !(file->flags & O_DIRECT))
791 {
792 ret = dfs_aspace_read(file, buf, len, &pos);
793 }
794 else
795#endif
796 {
797 ret = file->fops->read(file, buf, len, &pos);
798 }
799 }
800 else
801 {
802 ret = -EINVAL;
803 }
804 }
805 /* fpos unlock */
806 dfs_file_set_fpos(file, pos);
807 }
808 }
809
810 return ret;
811}
off_t dfs_file_get_fpos(struct dfs_file *file)
void dfs_file_set_fpos(struct dfs_file *file, off_t fpos)

引用了 dfs_vnode::aspace, DFS_F_FREAD, dfs_fflags(), dfs_file_get_fpos(), dfs_file_set_fpos(), dfs_is_mounted(), dfs_file::flags, dfs_file::fops, dfs_vnode::mnt, dfs_file_ops::read, rw_verify_area(), dfs_vnode::type , 以及 dfs_file::vnode.

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

◆ dfs_file_pwrite()

ssize_t dfs_file_pwrite ( struct dfs_file * file,
const void * buf,
size_t len,
off_t offset )

在文件 dfs_file.c813 行定义.

814{
815 ssize_t ret = -EBADF;
816
817 if (file)
818 {
819 if (!(dfs_fflags(file->flags) & DFS_F_FWRITE))
820 {
821 LOG_W("bad write flags.");
822 ret = -EBADF;
823 }
824 else if (!file->fops || !file->fops->write)
825 {
826 LOG_W("no fops write.");
827 ret = -ENOSYS;
828 }
829 else if (file->vnode && file->vnode->type != FT_DIRECTORY)
830 {
831 off_t pos = offset;
832
833 ret = rw_verify_area(file, &pos, len);
834 if (ret > 0)
835 {
836 len = ret;
837 DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG,
838 "dfs_file_write(fd, buf, %d)", len);
839
840 if (dfs_is_mounted(file->vnode->mnt) == 0)
841 {
842#ifdef RT_USING_PAGECACHE
843 if (file->vnode->aspace && !(file->flags & O_DIRECT))
844 {
845 ret = dfs_aspace_write(file, buf, len, &pos);
846 }
847 else
848#endif
849 {
850 ret = file->fops->write(file, buf, len, &pos);
851 }
852
853 if (file->flags & O_SYNC)
854 {
855 file->fops->flush(file);
856 }
857 }
858 else
859 {
860 ret = -EINVAL;
861 }
862 }
863 }
864 }
865
866 return ret;
867}
ssize_t(* write)(struct dfs_file *file, const void *buf, size_t count, off_t *pos)
int(* flush)(struct dfs_file *file)

引用了 dfs_vnode::aspace, dfs_file::dentry, DFS_F_FWRITE, dfs_fflags(), dfs_is_mounted(), DLOG, dfs_file::flags, dfs_file_ops::flush, dfs_file::fops, dfs_mnt::fs_ops, LOG_W, dfs_dentry::mnt, dfs_vnode::mnt, dfs_filesystem_ops::name, rw_verify_area(), dfs_vnode::type, dfs_file::vnode , 以及 dfs_file_ops::write.

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

◆ dfs_file_write()

ssize_t dfs_file_write ( struct dfs_file * file,
const void * buf,
size_t len )

在文件 dfs_file.c869 行定义.

870{
871 ssize_t ret = -EBADF;
872
873 if (file)
874 {
875 if (!(dfs_fflags(file->flags) & DFS_F_FWRITE))
876 {
877 LOG_W("bad write flags.");
878 ret = -EBADF;
879 }
880 else if (!file->fops || !file->fops->write)
881 {
882 LOG_W("no fops write.");
883 ret = -ENOSYS;
884 }
885 else if (file->vnode && file->vnode->type != FT_DIRECTORY)
886 {
887 off_t pos;
888
889 if (!(file->flags & O_APPEND))
890 {
891 /* fpos lock */
892 pos = dfs_file_get_fpos(file);
893 }
894 else
895 {
896 pos = file->vnode->size;
897 }
898
899 ret = rw_verify_area(file, &pos, len);
900 if (ret > 0)
901 {
902 len = ret;
903 DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG,
904 "dfs_file_write(fd, buf, %d)", len);
905
906 if (dfs_is_mounted(file->vnode->mnt) == 0)
907 {
908#ifdef RT_USING_PAGECACHE
909 if (file->vnode->aspace && !(file->flags & O_DIRECT))
910 {
911 ret = dfs_aspace_write(file, buf, len, &pos);
912 }
913 else
914#endif
915 {
916 ret = file->fops->write(file, buf, len, &pos);
917 }
918
919 if (file->flags & O_SYNC)
920 {
921 file->fops->flush(file);
922 }
923 }
924 else
925 {
926 ret = -EINVAL;
927 }
928 }
929 if (!(file->flags & O_APPEND))
930 {
931 /* fpos unlock */
932 dfs_file_set_fpos(file, pos);
933 }
934 }
935 }
936
937 return ret;
938}

引用了 dfs_vnode::aspace, dfs_file::dentry, DFS_F_FWRITE, dfs_fflags(), dfs_file_get_fpos(), dfs_file_set_fpos(), dfs_is_mounted(), DLOG, dfs_file::flags, dfs_file_ops::flush, dfs_file::fops, dfs_mnt::fs_ops, LOG_W, dfs_dentry::mnt, dfs_vnode::mnt, dfs_filesystem_ops::name, rw_verify_area(), dfs_vnode::size, dfs_vnode::type, dfs_file::vnode , 以及 dfs_file_ops::write.

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

◆ generic_dfs_lseek()

off_t generic_dfs_lseek ( struct dfs_file * file,
off_t offset,
int whence )

在文件 dfs_file.c940 行定义.

941{
942 off_t foffset;
943
944 if (whence == SEEK_SET)
945 foffset = offset;
946 else if (whence == SEEK_CUR)
947 foffset = file->fpos + offset;
948 else if (whence == SEEK_END)
949 foffset = file->vnode->size + offset;
950 else
951 return -EINVAL;
952
953 return foffset;
954}

引用了 dfs_file::fpos, dfs_vnode::size , 以及 dfs_file::vnode.

◆ dfs_file_lseek()

off_t dfs_file_lseek ( struct dfs_file * file,
off_t offset,
int wherece )

在文件 dfs_file.c956 行定义.

957{
958 off_t retval = -EINVAL;
959
960 if (file && file->fops->lseek)
961 {
962 if (dfs_is_mounted(file->vnode->mnt) == 0)
963 {
964 /* fpos lock */
965 off_t pos = dfs_file_get_fpos(file);
966 retval = file->fops->lseek(file, offset, wherece);
967 if (retval >= 0)
968 {
969 pos = retval;
970 }
971 /* fpos unlock */
972 dfs_file_set_fpos(file, pos);
973 }
974 }
975
976 return retval;
977}
off_t(* lseek)(struct dfs_file *file, off_t offset, int wherece)

引用了 dfs_file_get_fpos(), dfs_file_set_fpos(), dfs_is_mounted(), dfs_file::fops, dfs_file_ops::lseek, dfs_vnode::mnt , 以及 dfs_file::vnode.

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

◆ dfs_file_stat()

int dfs_file_stat ( const char * path,
struct stat * buf )

在文件 dfs_file.c979 行定义.

980{
981 int ret = -ENOENT;
982 char *fullpath = RT_NULL;
983 struct dfs_mnt *mnt = RT_NULL;
984 struct dfs_dentry *dentry = RT_NULL;
985
986 fullpath = dfs_normalize_path(NULL, path);
987 if (fullpath)
988 {
989 DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath);
990 mnt = dfs_mnt_lookup(fullpath);
991 if (mnt)
992 {
993 char *tmp = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_EXCEPT_NONE);
994 if (tmp)
995 {
996 rt_free(fullpath);
997 fullpath = tmp;
998 }
999
1000 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dentry = dfs_dentry_lookup(mnt, %s)", fullpath);
1001 dentry = dfs_dentry_lookup(mnt, fullpath, 0);
1002 if (dentry)
1003 {
1004 DLOG(msg, "dentry", "dfs_file", DLOG_MSG_RET, "return dentry");
1005 if (mnt->fs_ops->stat)
1006 {
1007 DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->stat(dentry, buf)");
1008
1009 if (dfs_is_mounted(mnt) == 0)
1010 {
1011 ret = mnt->fs_ops->stat(dentry, buf);
1012 }
1013 }
1014
1015 /* unref dentry */
1016 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_unref(dentry)");
1017 dfs_dentry_unref(dentry);
1018 dentry = RT_NULL;
1019 }
1020 }
1021
1022 rt_free(fullpath);
1023 fullpath = RT_NULL;
1024 }
1025 else
1026 {
1027 ret = -ENOMEM;
1028 }
1029
1030 return ret;
1031}
#define DFS_REALPATH_EXCEPT_NONE
int(* stat)(struct dfs_dentry *dentry, struct stat *buf)

引用了 dfs_dentry_lookup(), dfs_dentry_unref(), dfs_file_realpath(), dfs_is_mounted(), dfs_mnt_lookup(), dfs_normalize_path(), DFS_REALPATH_EXCEPT_NONE, DLOG, dfs_mnt::fs_ops, dfs_dentry::mnt, dfs_filesystem_ops::name, rt_free(), RT_NULL, dfs_filesystem_ops::stat , 以及 stat().

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

◆ dfs_file_lstat()

int dfs_file_lstat ( const char * path,
struct stat * buf )

在文件 dfs_file.c1033 行定义.

1034{
1035 int ret = -ENOENT;
1036 char *fullpath = RT_NULL;
1037 struct dfs_mnt *mnt = RT_NULL;
1038 struct dfs_dentry *dentry = RT_NULL;
1039
1040 fullpath = dfs_normalize_path(NULL, path);
1041 if (fullpath)
1042 {
1043 DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath);
1044 mnt = dfs_mnt_lookup(fullpath);
1045 if (mnt)
1046 {
1047 char *tmp = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_EXCEPT_LAST);
1048 if (tmp)
1049 {
1050 rt_free(fullpath);
1051 fullpath = tmp;
1052 }
1053
1054 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dentry = dfs_dentry_lookup(mnt, %s)", fullpath);
1055 dentry = dfs_dentry_lookup(mnt, fullpath, 0);
1056 if (dentry)
1057 {
1058 DLOG(msg, "dentry", "dfs_file", DLOG_MSG_RET, "return dentry");
1059 if (mnt->fs_ops->stat)
1060 {
1061 DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->stat(dentry, buf)");
1062
1063 if (dfs_is_mounted(mnt) == 0)
1064 {
1065 ret = mnt->fs_ops->stat(dentry, buf);
1066 }
1067 }
1068
1069 /* unref dentry */
1070 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_unref(dentry)");
1071 dfs_dentry_unref(dentry);
1072 dentry = RT_NULL;
1073 }
1074 }
1075
1076 rt_free(fullpath);
1077 fullpath = RT_NULL;
1078 }
1079 else
1080 {
1081 ret = -ENOMEM;
1082 }
1083
1084 rt_set_errno(-ret);
1085
1086 return ret;
1087}

引用了 dfs_dentry_lookup(), dfs_dentry_unref(), dfs_file_realpath(), dfs_is_mounted(), dfs_mnt_lookup(), dfs_normalize_path(), DFS_REALPATH_EXCEPT_LAST, DLOG, dfs_mnt::fs_ops, dfs_dentry::mnt, dfs_filesystem_ops::name, rt_free(), RT_NULL, dfs_filesystem_ops::stat , 以及 stat().

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

◆ dfs_file_setattr()

int dfs_file_setattr ( const char * path,
struct dfs_attr * attr )

在文件 dfs_file.c1112 行定义.

1113{
1114 int ret = -RT_ERROR;
1115 char *fullpath = RT_NULL;
1116 struct dfs_mnt *mnt = RT_NULL;
1117 struct dfs_dentry *dentry = RT_NULL;
1118
1119 fullpath = dfs_normalize_path(NULL, path);
1120 if (fullpath)
1121 {
1122 DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath);
1123 mnt = dfs_mnt_lookup(fullpath);
1124 if (mnt)
1125 {
1126 char *tmp = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_EXCEPT_LAST);
1127 if (tmp)
1128 {
1129 rt_free(fullpath);
1130 fullpath = tmp;
1131 }
1132
1133 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dentry = dfs_dentry_lookup(mnt, %s)", fullpath);
1134 dentry = dfs_dentry_lookup(mnt, fullpath, 0);
1135 if (dentry)
1136 {
1137 DLOG(msg, "dentry", "dfs_file", DLOG_MSG_RET, "return dentry");
1138 if (mnt->fs_ops->setattr)
1139 {
1140 DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->setattr(dentry, attr)");
1141
1142 if (dfs_is_mounted(mnt) == 0)
1143 {
1144 ret = mnt->fs_ops->setattr(dentry, attr);
1145 }
1146 }
1147
1148 /* unref dentry */
1149 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_unref(dentry)");
1150 dfs_dentry_unref(dentry);
1151 dentry = RT_NULL;
1152 }
1153 }
1154
1155 rt_free(fullpath);
1156 fullpath = RT_NULL;
1157 }
1158
1159 return ret;
1160}
int(* setattr)(struct dfs_dentry *dentry, struct dfs_attr *attr)

引用了 dfs_dentry_lookup(), dfs_dentry_unref(), dfs_file_realpath(), dfs_is_mounted(), dfs_mnt_lookup(), dfs_normalize_path(), DFS_REALPATH_EXCEPT_LAST, DLOG, dfs_mnt::fs_ops, dfs_dentry::mnt, dfs_filesystem_ops::name, rt_free(), RT_NULL , 以及 dfs_filesystem_ops::setattr.

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

◆ dfs_file_fstat()

int dfs_file_fstat ( struct dfs_file * file,
struct stat * buf )

在文件 dfs_file.c1089 行定义.

1090{
1091 size_t ret = -EBADF;
1092
1093 if (file)
1094 {
1095 if (file->fops && file->fops->ioctl)
1096 {
1097 // ret = file->fops->fstat(file, buf);
1098 }
1099 else
1100 {
1101 ret = -ENOSYS;
1102 }
1103 }
1104 else
1105 {
1106 ret = -EBADF;
1107 }
1108
1109 return ret;
1110}
int(* ioctl)(struct dfs_file *file, int cmd, void *arg)

引用了 dfs_file::fops, dfs_file_ops::ioctl , 以及 stat().

+ 函数调用图:

◆ dfs_file_ioctl()

int dfs_file_ioctl ( struct dfs_file * file,
int cmd,
void * args )

在文件 dfs_file.c1162 行定义.

1163{
1164 size_t ret = 0;
1165
1166 if (file)
1167 {
1168 if (file->fops && file->fops->ioctl)
1169 {
1170 if (dfs_is_mounted(file->vnode->mnt) == 0)
1171 {
1172 ret = file->fops->ioctl(file, cmd, args);
1173 }
1174 else
1175 {
1176 ret = -EINVAL;
1177 }
1178 }
1179 else
1180 {
1181 ret = -ENOSYS;
1182 }
1183 }
1184 else
1185 {
1186 ret = -EBADF;
1187 }
1188
1189 return ret;
1190}

引用了 dfs_is_mounted(), dfs_file::fops, dfs_file_ops::ioctl, dfs_vnode::mnt , 以及 dfs_file::vnode.

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

◆ dfs_file_fcntl()

int dfs_file_fcntl ( int fd,
int cmd,
unsigned long arg )

在文件 dfs_file.c1192 行定义.

1193{
1194 int ret = 0;
1195 struct dfs_file *file;
1196
1197 file = fd_get(fd);
1198 if (file)
1199 {
1200 switch (cmd)
1201 {
1202 case F_DUPFD:
1203 ret = dfs_dup(fd, arg);
1204 break;
1205 case F_GETFD:
1206 ret = file->mode;
1207 break;
1208 case F_SETFD:
1209 file->mode = arg;
1210 break;
1211 case F_GETFL:
1212 ret = file->flags;
1213 break;
1214 case F_SETFL:
1215 {
1216 int flags = (int)(rt_base_t)arg;
1217 int mask =
1218#ifdef O_ASYNC
1219 O_ASYNC |
1220#endif
1221#ifdef O_DIRECT
1222 O_DIRECT |
1223#endif
1224#ifdef O_NOATIME
1225 O_NOATIME |
1226#endif
1227 O_APPEND | O_NONBLOCK;
1228
1229 flags &= mask;
1230 file->flags &= ~mask;
1231 file->flags |= flags;
1232 break;
1233 }
1234 case F_GETLK:
1235 break;
1236 case F_SETLK:
1237 case F_SETLKW:
1238 break;
1239#ifdef RT_USING_MUSLLIBC
1240 case F_DUPFD_CLOEXEC:
1241 ret = -EINVAL;
1242 break;
1243#endif
1244 default:
1245 ret = -EPERM;
1246 break;
1247 }
1248 }
1249 else
1250 {
1251 ret = -EBADF;
1252 }
1253
1254 return ret;
1255}
int dfs_dup(int oldfd, int startfd)
定义 dfs.c:526
struct dfs_file * fd_get(int fd)
定义 dfs.c:367
rt_int32_t rt_base_t
uint16_t mode

引用了 dfs_dup(), fd_get(), dfs_file::flags , 以及 dfs_file::mode.

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

◆ dfs_file_fsync()

int dfs_file_fsync ( struct dfs_file * file)

在文件 dfs_file.c1257 行定义.

1258{
1259 int ret = -EBADF;
1260
1261 if (file)
1262 {
1263 if (file->fops->flush)
1264 {
1265 if (dfs_is_mounted(file->vnode->mnt) == 0)
1266 {
1267#ifdef RT_USING_PAGECACHE
1268 if (file->vnode->aspace)
1269 {
1270 dfs_aspace_flush(file->vnode->aspace);
1271 }
1272#endif
1273 ret = file->fops->flush(file);
1274 }
1275 else
1276 {
1277 ret = -EINVAL;
1278 }
1279 }
1280 }
1281
1282 return ret;
1283}

引用了 dfs_vnode::aspace, dfs_is_mounted(), dfs_file_ops::flush, dfs_file::fops, dfs_vnode::mnt , 以及 dfs_file::vnode.

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

◆ dfs_file_unlink()

int dfs_file_unlink ( const char * path)

在文件 dfs_file.c1285 行定义.

1286{
1287 int ret = -RT_ERROR;
1288 char *fullpath = RT_NULL;
1289 struct dfs_mnt *mnt = RT_NULL;
1290 struct dfs_dentry *dentry = RT_NULL;
1291
1292 fullpath = dfs_normalize_path(NULL, path);
1293 if (fullpath)
1294 {
1295 DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath);
1296 mnt = dfs_mnt_lookup(fullpath);
1297 if (mnt)
1298 {
1299 char *tmp = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_EXCEPT_LAST);
1300 if (tmp)
1301 {
1302 rt_free(fullpath);
1303 fullpath = tmp;
1304 }
1305
1306 if (strcmp(mnt->fullpath, fullpath) != 0)
1307 {
1308 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_lookup(mnt, %s)", fullpath);
1309 dentry = dfs_dentry_lookup(mnt, fullpath, 0);
1310 if (dentry)
1311 {
1312 rt_bool_t has_child = RT_FALSE;
1313
1314 has_child = dfs_mnt_has_child_mnt(mnt, fullpath);
1315#ifdef RT_USING_PAGECACHE
1316 if (dentry->vnode->aspace)
1317 {
1318 dfs_aspace_clean(dentry->vnode->aspace);
1319 }
1320#endif
1321 dfs_file_lock();
1322
1323 if (has_child == RT_FALSE)
1324 {
1325 /* no child mnt point, unlink it */
1326 ret = -RT_ERROR;
1327
1328 if (mnt->fs_ops->unlink)
1329 {
1330 if (dfs_is_mounted(mnt) == 0)
1331 {
1332 ret = mnt->fs_ops->unlink(dentry);
1333 }
1334 }
1335 }
1336 else
1337 {
1338 ret = -EBUSY;
1339 }
1341
1342 /* release this dentry */
1343 dfs_dentry_unref(dentry);
1344 }
1345 else
1346 {
1347 /* no this entry */
1348 ret = -ENOENT;
1349 }
1350 }
1351 else
1352 {
1353 /* it's a mount point, failed for busy */
1354 ret = -EBUSY;
1355 }
1356 }
1357 else
1358 {
1359 ret = -ENOENT;
1360 }
1361
1362 /* release fullpath */
1363 rt_free(fullpath);
1364 }
1365 else
1366 {
1367 ret = -ENOMEM;
1368 }
1369
1370 return ret;
1371}
rt_bool_t dfs_mnt_has_child_mnt(struct dfs_mnt *mnt, const char *fullpath)
int(* unlink)(struct dfs_dentry *dentry)

引用了 dfs_vnode::aspace, dfs_dentry_lookup(), dfs_dentry_unref(), dfs_file_lock(), dfs_file_realpath(), dfs_file_unlock(), dfs_is_mounted(), dfs_mnt_has_child_mnt(), dfs_mnt_lookup(), dfs_normalize_path(), DFS_REALPATH_EXCEPT_LAST, DLOG, dfs_mnt::fs_ops, dfs_mnt::fullpath, dfs_dentry::mnt, RT_FALSE, rt_free(), RT_NULL, dfs_filesystem_ops::unlink , 以及 dfs_dentry::vnode.

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

◆ dfs_file_link()

int dfs_file_link ( const char * oldname,
const char * newname )

在文件 dfs_file.c1373 行定义.

1374{
1375 int ret = -1;
1376 struct stat stat;
1377 struct dfs_mnt *mnt = RT_NULL;
1378 char *old_fullpath, *new_fullpath;
1379
1380 if (dfs_file_isdir(oldname) == 0)
1381 {
1382 rt_set_errno(-EPERM);
1383 return ret;
1384 }
1385
1386 if (dfs_file_lstat(newname, &stat) >= 0)
1387 {
1388 return ret;
1389 }
1390
1391 old_fullpath = dfs_normalize_path(NULL, oldname);
1392 if (old_fullpath)
1393 {
1394 DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", old_fullpath);
1395 mnt = dfs_mnt_lookup(old_fullpath);
1396 if (mnt == RT_NULL)
1397 {
1398 rt_free(old_fullpath);
1399 return -1;
1400 }
1401
1402 char *tmp = dfs_file_realpath(&mnt, old_fullpath, DFS_REALPATH_EXCEPT_LAST);
1403 if (tmp)
1404 {
1405 rt_free(old_fullpath);
1406 old_fullpath = tmp;
1407 }
1408 }
1409
1410 new_fullpath = dfs_normalize_path(NULL, newname);
1411 if (new_fullpath)
1412 {
1413 char *tmp = dfs_file_realpath(&mnt, new_fullpath, DFS_REALPATH_EXCEPT_LAST);
1414 if (tmp)
1415 {
1416 rt_free(new_fullpath);
1417 new_fullpath = tmp;
1418 }
1419 }
1420
1421 if (old_fullpath && new_fullpath)
1422 {
1423 struct dfs_dentry *old_dentry, *new_dentry;
1424
1425 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_lookup(mnt, %s)", old_fullpath);
1426 old_dentry = dfs_dentry_lookup(mnt, old_fullpath, 0);
1427 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_create(%s)", new_fullpath);
1428 new_dentry = dfs_dentry_create(mnt, new_fullpath);
1429
1430 if (old_dentry && new_dentry)
1431 {
1432 if (mnt->fs_ops->link)
1433 {
1434 if (dfs_is_mounted(mnt) == 0)
1435 {
1436 ret = mnt->fs_ops->link(old_dentry, new_dentry);
1437 }
1438 }
1439 }
1440
1441 dfs_dentry_unref(old_dentry);
1442 dfs_dentry_unref(new_dentry);
1443 }
1444
1445 if (old_fullpath)
1446 {
1447 rt_free(old_fullpath);
1448 }
1449
1450 if (new_fullpath)
1451 {
1452 rt_free(new_fullpath);
1453 }
1454
1455 return ret;
1456}
int dfs_file_lstat(const char *path, struct stat *buf)
int dfs_file_isdir(const char *path)
int stat(const char *file, struct stat *buf)
int(* link)(struct dfs_dentry *src_dentry, struct dfs_dentry *dst_dentry)

引用了 dfs_dentry_create(), dfs_dentry_lookup(), dfs_dentry_unref(), dfs_file_isdir(), dfs_file_lstat(), dfs_file_realpath(), dfs_is_mounted(), dfs_mnt_lookup(), dfs_normalize_path(), DFS_REALPATH_EXCEPT_LAST, DLOG, dfs_mnt::fs_ops, dfs_filesystem_ops::link, dfs_dentry::mnt, rt_free(), RT_NULL , 以及 stat().

+ 函数调用图:

◆ dfs_file_symlink()

int dfs_file_symlink ( const char * oldname,
const char * name )

在文件 dfs_file.c1459 行定义.

1460{
1461 int ret = -RT_ERROR;
1462 char *fullpath = RT_NULL, *parent = RT_NULL;
1463 struct dfs_mnt *mnt = RT_NULL;
1464 struct dfs_dentry *dentry = RT_NULL;
1465
1466 if (target && linkpath)
1467 {
1468 if (linkpath[0] != '/')
1469 {
1470 fullpath = dfs_normalize_path(NULL, linkpath);
1471 }
1472 else
1473 {
1474 fullpath = (char*)linkpath;
1475 }
1476
1477 /* linkpath should be not exist */
1478 if (dfs_file_access(fullpath, O_RDONLY) != 0)
1479 {
1480 char *index;
1481
1482 /* get parent path */
1483 index = strrchr(fullpath, '/');
1484 if (index)
1485 {
1486 int length = index - fullpath;
1487 if (length > 0)
1488 {
1489 parent = (char*) rt_malloc (length + 1);
1490 if (parent)
1491 {
1492 memcpy(parent, fullpath, length);
1493 parent[length] = '\0';
1494 }
1495 }
1496 else
1497 {
1498 parent = (char*) rt_malloc (1 + 1);
1499 if (parent)
1500 {
1501 parent[0] = '/';
1502 parent[1] = '\0';
1503 }
1504 }
1505 }
1506
1507 if (parent)
1508 {
1509 DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath);
1510 mnt = dfs_mnt_lookup(parent);
1511 if (mnt)
1512 {
1513 char *tmp = dfs_file_realpath(&mnt, parent, DFS_REALPATH_EXCEPT_LAST);
1514 if (tmp)
1515 {
1516 rt_free(parent);
1517 parent = tmp;
1518 }
1519
1520 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_lookup(mnt, %s)", fullpath);
1522 if (dentry)
1523 {
1524 if (dentry->mnt->fs_ops->symlink)
1525 {
1526 char *path = dfs_normalize_path(parent, target);
1527 if (path)
1528 {
1529 ret = rt_strncmp(parent, path, strlen(parent));
1530 if (ret == 0)
1531 {
1532 tmp = path + strlen(parent);
1533 if (*tmp == '/')
1534 {
1535 tmp ++;
1536 }
1537 }
1538 else
1539 {
1540 tmp = path;
1541 }
1542
1543 if (dfs_is_mounted(mnt) == 0)
1544 {
1545 ret = mnt->fs_ops->symlink(dentry, tmp, index + 1);
1546 }
1547
1548 rt_free(path);
1549 }
1550 }
1551 else
1552 {
1553 ret = -ENOSYS;
1554 }
1555
1556 dfs_dentry_unref(dentry);
1557 }
1558 else
1559 {
1560 ret = -ENOENT;
1561 }
1562 }
1563 else
1564 {
1565 ret = -ENOENT;
1566 }
1567
1568 rt_free(parent);
1569 }
1570 }
1571 else
1572 {
1573 rt_set_errno(-EPERM);
1574 }
1575
1576 if (fullpath != linkpath)
1577 rt_free(fullpath);
1578 }
1579 else
1580 {
1581 ret = -EINVAL;
1582 }
1583
1584 return ret;
1585}
int dfs_file_access(const char *path, mode_t mode)
rt_weak void * rt_malloc(rt_size_t size)
Allocate a block of memory with a minimum of 'size' bytes.
int(* symlink)(struct dfs_dentry *parent_dentry, const char *target, const char *newpath)

引用了 dfs_dentry_lookup(), dfs_dentry_unref(), dfs_file_access(), dfs_file_realpath(), dfs_is_mounted(), dfs_mnt_lookup(), dfs_normalize_path(), DFS_REALPATH_EXCEPT_LAST, DLOG, dfs_mnt::fs_ops, dfs_dentry::mnt, rt_free(), rt_malloc(), RT_NULL , 以及 dfs_filesystem_ops::symlink.

+ 函数调用图:

◆ dfs_file_readlink()

int dfs_file_readlink ( const char * path,
char * buf,
int bufsize )

在文件 dfs_file.c1587 行定义.

1588{
1589 int ret = -RT_ERROR;
1590 char *fullpath = RT_NULL;
1591 struct dfs_mnt *mnt = RT_NULL;
1592 struct dfs_dentry *dentry = RT_NULL;
1593
1594 fullpath = dfs_normalize_path(NULL, path);
1595 if (fullpath)
1596 {
1597 DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath);
1598 mnt = dfs_mnt_lookup(fullpath);
1599 if (mnt)
1600 {
1601 char *tmp = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_EXCEPT_LAST);
1602 if (tmp)
1603 {
1604 rt_free(fullpath);
1605 fullpath = tmp;
1606 }
1607
1608 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_lookup(mnt, %s)", fullpath);
1609 dentry = dfs_dentry_lookup(mnt, fullpath, 0);
1610 if (dentry)
1611 {
1612 if (mnt->fs_ops->readlink)
1613 {
1614 if (dfs_is_mounted(mnt) == 0)
1615 {
1616 ret = mnt->fs_ops->readlink(dentry, buf, bufsize);
1617 }
1618 }
1619 else
1620 {
1621 ret = -ENOSYS;
1622 }
1623
1624 /* release this dentry */
1625 dfs_dentry_unref(dentry);
1626 }
1627 else
1628 {
1629 /* no this entry */
1630 ret = -ENOENT;
1631 }
1632 }
1633 else
1634 {
1635 ret = -ENOENT;
1636 }
1637
1638 /* release fullpath */
1639 rt_free(fullpath);
1640 }
1641 else
1642 {
1643 ret = -ENOMEM;
1644 }
1645
1646 return ret;
1647}
int(* readlink)(struct dfs_dentry *dentry, char *buf, int len)

引用了 dfs_dentry_lookup(), dfs_dentry_unref(), dfs_file_realpath(), dfs_is_mounted(), dfs_mnt_lookup(), dfs_normalize_path(), DFS_REALPATH_EXCEPT_LAST, DLOG, dfs_mnt::fs_ops, dfs_dentry::mnt, dfs_filesystem_ops::readlink, rt_free() , 以及 RT_NULL.

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

◆ dfs_file_rename()

int dfs_file_rename ( const char * old_file,
const char * new_file )

在文件 dfs_file.c1649 行定义.

1650{
1651 int ret = -1;
1652 struct dfs_mnt *mnt = RT_NULL;
1653 char *old_fullpath, *new_fullpath;
1654
1655 old_fullpath = dfs_normalize_path(NULL, old_file);
1656 if (old_fullpath)
1657 {
1658 DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", old_fullpath);
1659 mnt = dfs_mnt_lookup(old_fullpath);
1660 if (mnt == RT_NULL)
1661 {
1662 rt_free(old_fullpath);
1663 return -1;
1664 }
1665
1666 char *tmp = dfs_file_realpath(&mnt, old_fullpath, DFS_REALPATH_EXCEPT_LAST);
1667 if (tmp)
1668 {
1669 rt_free(old_fullpath);
1670 old_fullpath = tmp;
1671 }
1672 }
1673
1674 new_fullpath = dfs_normalize_path(NULL, new_file);
1675 if (new_fullpath)
1676 {
1677 char *tmp = dfs_file_realpath(&mnt, new_fullpath, DFS_REALPATH_EXCEPT_LAST);
1678 if (tmp)
1679 {
1680 rt_free(new_fullpath);
1681 new_fullpath = tmp;
1682 }
1683 }
1684
1685 if (old_fullpath && new_fullpath)
1686 {
1687 struct dfs_dentry *old_dentry, *new_dentry;
1688
1689 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_lookup(mnt, %s)", old_fullpath);
1690 old_dentry = dfs_dentry_lookup(mnt, old_fullpath, 0);
1691 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_create(%s)", new_fullpath);
1692 new_dentry = dfs_dentry_create(mnt, new_fullpath);
1693
1694 if (old_dentry && new_dentry)
1695 {
1696 if (mnt->fs_ops->rename)
1697 {
1698 if (dfs_is_mounted(mnt) == 0)
1699 {
1700#ifdef RT_USING_PAGECACHE
1701 if (old_dentry->vnode->aspace)
1702 {
1703 dfs_aspace_clean(old_dentry->vnode->aspace);
1704 }
1705#endif
1706 ret = mnt->fs_ops->rename(old_dentry, new_dentry);
1707 }
1708 }
1709 }
1710
1711 dfs_dentry_unref(old_dentry);
1712 dfs_dentry_unref(new_dentry);
1713 }
1714
1715 if (old_fullpath)
1716 {
1717 rt_free(old_fullpath);
1718 }
1719
1720 if (new_fullpath)
1721 {
1722 rt_free(new_fullpath);
1723 }
1724
1725 return ret;
1726}
int(* rename)(struct dfs_dentry *old_dentry, struct dfs_dentry *new_dentry)

引用了 dfs_vnode::aspace, dfs_dentry_create(), dfs_dentry_lookup(), dfs_dentry_unref(), dfs_file_realpath(), dfs_is_mounted(), dfs_mnt_lookup(), dfs_normalize_path(), DFS_REALPATH_EXCEPT_LAST, DLOG, dfs_mnt::fs_ops, dfs_dentry::mnt, dfs_filesystem_ops::rename, rt_free(), RT_NULL , 以及 dfs_dentry::vnode.

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

◆ dfs_file_ftruncate()

int dfs_file_ftruncate ( struct dfs_file * file,
off_t length )

在文件 dfs_file.c1728 行定义.

1729{
1730 int ret = 0;
1731
1732 if (file)
1733 {
1734 if (file->fops->truncate)
1735 {
1736 if (dfs_is_mounted(file->vnode->mnt) == 0)
1737 {
1738#ifdef RT_USING_PAGECACHE
1739 if (file->vnode->aspace)
1740 {
1741 dfs_aspace_clean(file->vnode->aspace);
1742 }
1743#endif
1744 ret = file->fops->truncate(file, length);
1745 }
1746 else
1747 {
1748 ret = -EINVAL;
1749 }
1750 }
1751 else
1752 {
1753 ret = -ENOSYS;
1754 }
1755 }
1756 else
1757 {
1758 ret = -EBADF;
1759 }
1760
1761 return ret;
1762}

引用了 dfs_vnode::aspace, dfs_is_mounted(), dfs_file::fops, dfs_vnode::mnt, dfs_file_ops::truncate , 以及 dfs_file::vnode.

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

◆ dfs_file_getdents()

int dfs_file_getdents ( struct dfs_file * file,
struct dirent * dirp,
size_t nbytes )

在文件 dfs_file.c1800 行定义.

1801{
1802 int ret = -RT_ERROR;
1803
1804 if (file)
1805 {
1806 if (file->vnode && S_ISDIR(file->vnode->mode))
1807 {
1808 if (file->fops && file->fops->getdents)
1809 {
1810 DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "fops->getdents()");
1811
1812 if (dfs_is_mounted(file->vnode->mnt) == 0)
1813 {
1814 ret = file->fops->getdents(file, dirp, nbytes);
1815 }
1816 else
1817 {
1818 ret = -EINVAL;
1819 }
1820 }
1821 }
1822 }
1823 else
1824 {
1825 ret = -EBADF;
1826 }
1827
1828 return ret;
1829}
int(* getdents)(struct dfs_file *file, struct dirent *dirp, uint32_t count)

引用了 dfs_file::dentry, dfs_is_mounted(), DLOG, dfs_file::fops, dfs_mnt::fs_ops, dfs_file_ops::getdents, dfs_dentry::mnt, dfs_vnode::mnt, dfs_vnode::mode, dfs_filesystem_ops::name , 以及 dfs_file::vnode.

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

◆ dfs_file_mkdir()

int dfs_file_mkdir ( const char * path,
mode_t mode )

◆ dfs_file_rmdir()

int dfs_file_rmdir ( const char * pathname)

◆ dfs_file_isdir()

int dfs_file_isdir ( const char * path)

this function will check the path is it a directory.

参数
paththe file path.
返回
0 on is dir, -1 on not dir.

在文件 dfs_file.c1838 行定义.

1839{
1840 int ret = -RT_ERROR;
1841 char *fullpath = RT_NULL;
1842 struct dfs_mnt *mnt = RT_NULL;
1843 struct dfs_dentry *dentry = RT_NULL;
1844
1845 fullpath = dfs_normalize_path(NULL, path);
1846 if (fullpath)
1847 {
1848 DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath);
1849 mnt = dfs_mnt_lookup(fullpath);
1850 if (mnt)
1851 {
1852 char *tmp = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_EXCEPT_NONE);
1853 if (tmp)
1854 {
1855 rt_free(fullpath);
1856 fullpath = tmp;
1857 }
1858
1859 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dentry = dfs_dentry_lookup(mnt, %s)", fullpath);
1860 dentry = dfs_dentry_lookup(mnt, fullpath, 0);
1861 if (dentry)
1862 {
1863 DLOG(msg, "dentry", "dfs_file", DLOG_MSG_RET, "return dentry");
1864 if (mnt->fs_ops->stat)
1865 {
1866 struct stat stat = {0};
1867 DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->stat(dentry, buf)");
1868
1869 if (dfs_is_mounted(mnt) == 0)
1870 {
1871 ret = mnt->fs_ops->stat(dentry, &stat);
1872 }
1873
1874 if (ret == RT_EOK && S_ISDIR(stat.st_mode))
1875 {
1876 ret = RT_EOK;
1877 }
1878 else
1879 {
1880 ret = -RT_ERROR;
1881 }
1882 }
1883
1884 /* unref dentry */
1885 DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_unref(dentry)");
1886 dfs_dentry_unref(dentry);
1887 dentry = RT_NULL;
1888 }
1889 }
1890
1891 rt_free(fullpath);
1892 fullpath = RT_NULL;
1893 }
1894
1895 return ret;
1896}

引用了 dfs_dentry_lookup(), dfs_dentry_unref(), dfs_file_realpath(), dfs_is_mounted(), dfs_mnt_lookup(), dfs_normalize_path(), DFS_REALPATH_EXCEPT_NONE, DLOG, dfs_mnt::fs_ops, dfs_dentry::mnt, dfs_filesystem_ops::name, rt_free(), RT_NULL, dfs_filesystem_ops::stat , 以及 stat().

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

◆ dfs_file_access()

int dfs_file_access ( const char * path,
mode_t mode )

在文件 dfs_file.c1898 行定义.

1899{
1900 int ret;
1901 struct dfs_file file;
1902
1903 dfs_file_init(&file);
1904
1905 if (dfs_file_open(&file, path, O_RDONLY, mode) >= 0)
1906 {
1907 ret = 0;
1908 dfs_file_close(&file);
1909 }
1910 else
1911 {
1912 ret = -1;
1913 }
1914
1915 dfs_file_deinit(&file);
1916
1917 return ret;
1918}
void dfs_file_init(struct dfs_file *file)
int dfs_file_close(struct dfs_file *file)
int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mode)
void dfs_file_deinit(struct dfs_file *file)

引用了 dfs_file_close(), dfs_file_deinit(), dfs_file_init(), dfs_file_open() , 以及 dfs_file::mode.

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

◆ dfs_file_chdir()

int dfs_file_chdir ( const char * path)

◆ dfs_file_getcwd()

char * dfs_file_getcwd ( char * buf,
size_t size )

◆ dfs_file_realpath()

char * dfs_file_realpath ( struct dfs_mnt ** mnt,
const char * fullpath,
int mode )

在文件 dfs_file.c253 行定义.

254{
255 int path_len = 0, index = 0;
256 char *path = RT_NULL, *link_fn, *tmp_path;
257 struct dfs_mnt *tmp_mnt;
258
259 if (*mnt && fullpath)
260 {
261 int len, link_len;
262
263 path = (char *)rt_malloc((DFS_PATH_MAX * 3) + 3); // path + \0 + link_fn + \0 + tmp_path + \0
264 if (!path)
265 {
266 return RT_NULL;
267 }
268
269 link_fn = path + DFS_PATH_MAX + 1;
270 tmp_path = link_fn + (DFS_PATH_MAX + 1);
271
272 len = rt_strlen(fullpath);
273 if (len > DFS_PATH_MAX)
274 {
275 goto _ERR_RET;
276 }
277
278 index = (DFS_PATH_MAX - len);
279 rt_strcpy(tmp_path + index, fullpath);
280
281 if (mode == DFS_REALPATH_ONLY_LAST)
282 {
283 path_len = _get_parent_path(fullpath, path);
284 index += path_len;
285 }
286
287 while ((len = _first_path_len(tmp_path + index)) > 0)
288 {
289 if (len + path_len > DFS_PATH_MAX)
290 {
291 goto _ERR_RET;
292 }
293
294 rt_memcpy(path + path_len, tmp_path + index, len);
295 path[path_len + len] = '\0';
296 index += len;
297
298 tmp_mnt = dfs_mnt_lookup(path);
299 if (tmp_mnt == RT_NULL)
300 {
301 goto _ERR_RET;
302 }
303
304 *mnt = tmp_mnt;
305
306 /* the last should by mode process. */
307 if ((tmp_path[index] == '\0') && (mode == DFS_REALPATH_EXCEPT_LAST))
308 {
309 break;
310 }
311
312 link_len = _try_readlink(path, *mnt, link_fn);
313 if (link_len > 0)
314 {
315 if (link_fn[0] == '/')
316 {
317 int ret = _insert_link_path(link_fn, link_len, tmp_path, &index);
318 if (ret < 0)
319 {
320 goto _ERR_RET;
321 }
322 path_len = 0;
323 }
324 else
325 {
326 char *fp = _dfs_normalize_path(path, path_len, link_fn, link_len);
327 if (fp)
328 {
329 int pos = rt_strncmp(path, fp, path_len);
330 if (pos == 0)
331 {
332 int ret = _insert_link_path(fp + path_len, rt_strlen(fp + path_len), tmp_path, &index);
333 if (ret < 0)
334 {
335 rt_free(fp);
336 goto _ERR_RET;
337 }
338 }
339 else
340 {
341 int pos;
342
343 while(1)
344 {
345 while(path_len > 0 && path[path_len] != '/')
346 {
347 path_len--;
348 }
349
350 if (path_len > 0)
351 {
352 pos = rt_strncmp(path, fp, path_len);
353 }
354 else
355 {
356 pos = -1;
357 }
358
359 if (pos == 0 || path_len == 0)
360 {
361 int ret;
362
363 ret = _insert_link_path(fp + path_len, rt_strlen(fp + path_len), tmp_path, &index);
364 if (ret < 0)
365 {
366 rt_free(fp);
367 goto _ERR_RET;
368 }
369 else
370 {
371 break;
372 }
373 }
374 else
375 {
376 path_len--;
377 }
378 }
379 }
380 rt_free(fp);
381 }
382 }
383 }
384 else
385 {
386 path_len += len;
387 }
388 }
389
390 return path;
391
392_ERR_RET:
393 rt_free(path);
394 path = RT_NULL;
395 }
396
397 return path;
398}
#define DFS_PATH_MAX
定义 dfs.h:72
rt_inline int _first_path_len(const char *path)

引用了 _first_path_len(), dfs_mnt_lookup(), DFS_PATH_MAX, DFS_REALPATH_EXCEPT_LAST, DFS_REALPATH_ONLY_LAST, dfs_mnt::fullpath, rt_free(), rt_malloc() , 以及 RT_NULL.

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