1 /*
2  * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3  */
4 
5 #include <stdint.h>
6 #include <stddef.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <sys/stat.h>
10 #include <unistd.h>
11 #include <aos/errno.h>
12 
13 #include "vfs_types.h"
14 #include "vfs_api.h"
15 #include "vfs_conf.h"
16 
17 #include "vfs_inode.h"
18 #include "vfs_file.h"
19 #include "vfs_adapt.h"
20 
21 #ifdef IO_NEED_TRAP
22 #include "vfs_trap.h"
23 #endif
24 
25 static uint8_t  g_vfs_init     = 0;
26 static void    *g_vfs_lock_ptr = NULL;
27 static void    *g_stdio_lock_ptr = NULL;
28 static int32_t  stdio_redirect_fd[3] = {-1, -1, -1}; // 0: stdin, 1: stdout, 2: stderr
29 
30 int32_t vfs_inode_list(vfs_list_type_t type);
31 int vfs_inode_get_names(const char *path, char names[][64], uint32_t* size);
32 
33 #if (CURRENT_WORKING_DIRECTORY_ENABLE > 0)
34 char g_current_working_directory[VFS_PATH_MAX];
35 #endif
36 
37 extern int uring_fifo_push_s(const void* buf, const uint16_t len);
write_stdout(const void * buf,uint32_t nbytes)38 static int32_t write_stdout(const void *buf, uint32_t nbytes)
39 {
40     uring_fifo_push_s(buf, nbytes);
41     return nbytes;
42 }
43 
is_stdio_fd(int32_t fd)44 static int is_stdio_fd(int32_t fd)
45 {
46     return fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO? 1 : 0;
47 }
48 
find_stdio_redirect_fd(int32_t fd)49 static int32_t find_stdio_redirect_fd(int32_t fd)
50 {
51     int32_t rfd = -1;
52 
53     if (vfs_lock(g_stdio_lock_ptr) != VFS_OK) {
54         return -1;
55     }
56 
57     if (fd == STDIN_FILENO) {
58         rfd = stdio_redirect_fd[0];
59     } else if (fd == STDOUT_FILENO) {
60         rfd = stdio_redirect_fd[1];
61     } else if (fd == STDERR_FILENO) {
62         rfd = stdio_redirect_fd[2];
63     }
64 
65     vfs_unlock(g_stdio_lock_ptr);
66 
67     return rfd;
68 }
69 
set_stdio_redirect_fd(int32_t sfd,int32_t rfd)70 static int32_t set_stdio_redirect_fd(int32_t sfd, int32_t rfd)
71 {
72     int ret = 0, real_rfd = rfd - VFS_FD_OFFSET;
73 
74     if (vfs_lock(g_stdio_lock_ptr) != VFS_OK) {
75         return -1;
76     }
77 
78     if (real_rfd < 0 || real_rfd >= VFS_MAX_FILE_NUM || !vfs_fd_is_open(rfd)) {
79         vfs_unlock(g_vfs_lock_ptr);
80         return -1;
81     }
82 
83     if (sfd == STDIN_FILENO) {
84         stdio_redirect_fd[0] = rfd;
85     } else if (sfd == STDOUT_FILENO) {
86         stdio_redirect_fd[1] = rfd;
87     } else if (sfd == STDERR_FILENO) {
88         stdio_redirect_fd[2] = rfd;
89     } else {
90         ret = -1;
91     }
92 
93     vfs_unlock(g_stdio_lock_ptr);
94 
95     return ret;
96 }
97 
clear_stdio_redirect_fd(int fd)98 static int clear_stdio_redirect_fd(int fd)
99 {
100     int ret = 0;
101 
102     if (vfs_lock(g_stdio_lock_ptr) != VFS_OK) {
103         return -1;
104     }
105 
106     if (fd == STDIN_FILENO) {
107         stdio_redirect_fd[0] = -1;
108     } else if (fd == STDOUT_FILENO) {
109         stdio_redirect_fd[1] = -1;
110     } else if (fd == STDERR_FILENO) {
111         stdio_redirect_fd[2] = -1;
112     } else {
113         ret = -1;
114     }
115 
116     vfs_unlock(g_stdio_lock_ptr);
117 
118     return ret;
119 }
120 
vfs_close_without_glock(int32_t fd)121 static int32_t vfs_close_without_glock(int32_t fd)
122 {
123     int32_t ret = VFS_OK;
124     vfs_file_t *f;
125     vfs_inode_t *node;
126 
127     f = vfs_file_get(fd);
128     if (f == NULL) return VFS_ERR_NOENT;
129 
130     node = f->node;
131     assert(node != (vfs_inode_t *)(-1));
132 
133     if (vfs_lock(node->lock) != VFS_OK) {
134         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
135         return VFS_ERR_LOCK;
136     }
137 
138     if (node->status != VFS_INODE_VALID) {
139         vfs_unlock(node->lock);
140         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
141         goto end;
142     }
143 
144     if (INODE_IS_FS(node)) {
145         if ((node->ops.i_fops->close) != NULL) {
146             ret = (node->ops.i_fops->close)(f);
147         }
148     } else {
149         if ((node->ops.i_ops->close) != NULL) {
150             ret = (node->ops.i_ops->close)(f);
151         }
152     }
153 
154     vfs_unlock(node->lock);
155 
156 end:
157     vfs_fd_mark_close(fd);
158     vfs_file_del(f);
159     return ret;
160 }
161 
set_normal_redirect_fd(int32_t oldfd,int32_t newfd)162 static int32_t set_normal_redirect_fd(int32_t oldfd, int32_t newfd)
163 {
164     int ret = -1, realold = oldfd - VFS_FD_OFFSET;
165     vfs_file_t *f;
166 
167     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
168         return -1;
169     }
170 
171     if (realold < 0 || realold >= VFS_MAX_FILE_NUM || !vfs_fd_is_open(oldfd)) {
172         vfs_unlock(g_vfs_lock_ptr);
173         return -1;
174     }
175 
176     if (vfs_fd_is_open(newfd)) {
177        if (vfs_close_without_glock(newfd) != VFS_OK) {
178            goto end;
179        }
180     }
181 
182     f = vfs_file_get2(newfd);
183     if (!f) goto end;
184 
185     f->redirect_fd = oldfd;
186     /* -1 as *node, just for NULL check, do NOT really use it! */
187     f->node = (vfs_inode_t *)(-1);
188     vfs_fd_mark_open(newfd);
189     ret = newfd;
190 
191 end:
192     vfs_unlock(g_vfs_lock_ptr);
193     return ret;
194 }
195 
clear_normal_redirect_fd(int32_t fd)196 static int clear_normal_redirect_fd(int32_t fd)
197 {
198     int ret = -1;
199     vfs_file_t *f;
200 
201     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
202         return VFS_ERR_LOCK;
203     }
204 
205     if (!vfs_fd_is_open(fd)) {
206         goto end;
207     }
208 
209     f = vfs_file_get2(fd);
210     if (!f) goto end;
211 
212     f->redirect_fd = -1;
213     /* -1 as *node, just for NULL check, do NOT really use it! */
214     f->node = NULL;
215     vfs_fd_mark_close(fd);
216     vfs_file_del(f);
217     ret = 0;
218 
219 end:
220     vfs_unlock(g_vfs_lock_ptr);
221     return ret;
222 }
223 
vfs_init(void)224 int32_t vfs_init(void)
225 {
226     if (g_vfs_init == 1) {
227         return VFS_OK;
228     }
229 
230     g_vfs_lock_ptr = vfs_lock_create();
231     if (g_vfs_lock_ptr == NULL) {
232         return VFS_ERR_NOMEM;
233     }
234 
235     g_stdio_lock_ptr = vfs_lock_create();
236     if (g_stdio_lock_ptr == NULL) {
237         vfs_lock_free(g_vfs_lock_ptr);
238         return VFS_ERR_NOMEM;
239     }
240 
241     vfs_inode_init();
242 
243 #if (CURRENT_WORKING_DIRECTORY_ENABLE > 0)
244     /* init current working directory */
245     memset(g_current_working_directory, 0, sizeof(g_current_working_directory));
246 #ifdef VFS_CONFIG_ROOTFS
247     strcpy(g_current_working_directory, "/");
248 #else
249     strncpy(g_current_working_directory, "/default", strlen("/default") + 1);
250 #endif
251 #endif
252 
253     g_vfs_init = 1;
254 
255     return VFS_OK;
256 }
257 
vfs_open(const char * path,int32_t flags)258 int32_t vfs_open(const char *path, int32_t flags)
259 {
260     int32_t len = 0;
261     int32_t ret = VFS_OK;
262 
263     vfs_file_t  *f;
264     vfs_inode_t *node;
265 
266     if (path == NULL) {
267         return VFS_ERR_INVAL;
268     }
269 
270     len = strlen(path);
271     if (len > VFS_PATH_MAX) {
272         return VFS_ERR_NAMETOOLONG;
273     }
274 
275     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
276         return VFS_ERR_LOCK;
277     }
278 
279     node = vfs_inode_open(path);
280 
281     if (node == NULL) {
282         vfs_unlock(g_vfs_lock_ptr);
283 
284 #ifdef IO_NEED_TRAP
285         return trap_open(path, flags);
286 #else
287         return VFS_ERR_NOENT;
288 #endif
289     }
290 
291     f = vfs_file_new(node);
292 
293     vfs_unlock(g_vfs_lock_ptr);
294 
295     if (f == NULL) {
296         return VFS_ERR_ENFILE;
297     }
298 
299 #ifdef CONFIG_VFS_LSOPEN
300     strncpy(f->filename, path, sizeof(f->filename) - 1);
301 #endif
302 
303     if (vfs_lock(node->lock) != VFS_OK) {
304         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
305         ret = VFS_ERR_LOCK;
306         goto end;
307     }
308 
309     if (node->status != VFS_INODE_VALID) {
310         vfs_unlock(node->lock);
311         VFS_ERROR("%s node %p is invalid now, %d!\n\r", __func__, node, node->status);
312         ret = VFS_ERR_NOENT;
313         goto end;
314     }
315 
316     node->i_flags = flags;
317 
318     if (INODE_IS_FS(node)) {
319         if ((node->ops.i_fops->open) != NULL) {
320             ret = (node->ops.i_fops->open)(f, path, flags);
321         }
322     } else {
323         if ((node->ops.i_ops->open) != NULL) {
324             ret = (node->ops.i_ops->open)(node, f);
325         }
326     }
327 
328     vfs_unlock(node->lock);
329 
330 end:
331     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
332         return VFS_ERR_LOCK;
333     }
334 
335     if (ret != VFS_OK) {
336         vfs_file_del(f);
337     } else {
338         ret = vfs_fd_get(f);
339         vfs_fd_mark_open(ret);
340     }
341 
342     vfs_unlock(g_vfs_lock_ptr);
343 
344     return ret;
345 }
346 
vfs_close(int32_t fd)347 int32_t vfs_close(int32_t fd)
348 {
349     int32_t ret = VFS_OK;
350 
351     vfs_file_t *f;
352     vfs_inode_t *node;
353 
354     /* handle special case forstdio */
355     if (is_stdio_fd(fd)) {
356         return clear_stdio_redirect_fd(fd) == 0 ? VFS_OK : VFS_ERR_GENERAL;
357     }
358 
359     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
360         return VFS_ERR_LOCK;
361     }
362 
363     /* check if redirect or not first */
364     f = vfs_file_get2(fd);
365     if (f == NULL) {
366         vfs_unlock(g_vfs_lock_ptr);
367         return VFS_ERR_NOENT;
368     } else {
369         if (f->redirect_fd >= 0) {
370             vfs_unlock(g_vfs_lock_ptr);
371             return clear_normal_redirect_fd(fd) == 0 ? VFS_OK : VFS_ERR_GENERAL;
372         }
373     }
374 
375     f = vfs_file_get(fd);
376 
377     vfs_unlock(g_vfs_lock_ptr);
378 
379     if (f == NULL) {
380 #ifdef IO_NEED_TRAP
381         return trap_close(fd);
382 #else
383         return VFS_ERR_NOENT;
384 #endif
385     }
386 
387     node = f->node;
388 
389     if (vfs_lock(node->lock) != VFS_OK) {
390         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
391         return VFS_ERR_LOCK;
392     }
393 
394     if (node->status != VFS_INODE_VALID) {
395         vfs_unlock(node->lock);
396         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
397         goto end;
398     }
399 
400     if (INODE_IS_FS(node)) {
401         if ((node->ops.i_fops->close) != NULL) {
402             ret = (node->ops.i_fops->close)(f);
403         }
404     } else {
405         if ((node->ops.i_ops->close) != NULL) {
406             ret = (node->ops.i_ops->close)(f);
407         }
408     }
409 
410     vfs_unlock(node->lock);
411 
412 end:
413     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
414         return VFS_ERR_LOCK;
415     }
416 
417     vfs_fd_mark_close(fd);
418     vfs_file_del(f);
419 
420     vfs_unlock(g_vfs_lock_ptr);
421 
422     return ret;
423 }
424 
vfs_read(int32_t fd,void * buf,uint32_t nbytes)425 int32_t vfs_read(int32_t fd, void *buf, uint32_t nbytes)
426 {
427     int32_t nread = -1;
428 
429     vfs_file_t  *f;
430     vfs_inode_t *node;
431 
432     f = vfs_file_get(fd);
433 
434     if (f == NULL) {
435 #ifdef IO_NEED_TRAP
436         return trap_read(fd, buf, nbytes);
437 #else
438         return VFS_ERR_NOENT;
439 #endif
440     }
441 
442     node = f->node;
443 
444     if(node == NULL) {
445         return VFS_ERR_NOENT;
446     }
447 
448     if (vfs_lock(node->lock) != VFS_OK) {
449         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
450         return VFS_ERR_LOCK;
451     }
452 
453     if (node->status != VFS_INODE_VALID) {
454         vfs_unlock(node->lock);
455         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
456         goto ret;
457     }
458 
459     if (INODE_IS_FS(node)) {
460         if ((node->ops.i_fops->read) != NULL) {
461             nread = (node->ops.i_fops->read)(f, buf, nbytes);
462         }
463     } else {
464         if ((node->ops.i_ops->read) != NULL) {
465             nread = (node->ops.i_ops->read)(f, buf, nbytes);
466         }
467     }
468 
469 ret:
470     if (vfs_unlock(node->lock) != VFS_OK) {
471         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
472         return VFS_ERR_LOCK;
473     }
474 
475     return nread;
476 }
477 
vfs_write(int32_t fd,const void * buf,uint32_t nbytes)478 int32_t vfs_write(int32_t fd, const void *buf, uint32_t nbytes)
479 {
480     int32_t nwrite = -1, rfd = -1;
481 
482     vfs_file_t  *f;
483     vfs_inode_t *node;
484 
485     /* handle special case for stdout and stderr */
486     if ((fd == STDOUT_FILENO) || (fd == STDERR_FILENO)) {
487         if ((rfd = find_stdio_redirect_fd(fd)) >= 0) {
488             fd = rfd;
489         } else {
490             return write_stdout(buf, nbytes);
491         }
492     }
493 
494     f = vfs_file_get(fd);
495 
496     if (f == NULL) {
497 #ifdef IO_NEED_TRAP
498         return trap_write(fd, buf, nbytes);
499 #else
500         return VFS_ERR_NOENT;
501 #endif
502     }
503 
504     node = f->node;
505 
506     if(node == NULL) {
507         return VFS_ERR_NOENT;
508     }
509 
510     if (vfs_lock(node->lock) != VFS_OK) {
511         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
512         return VFS_ERR_LOCK;
513     }
514 
515     if (node->status != VFS_INODE_VALID) {
516         vfs_unlock(node->lock);
517         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
518         goto ret;
519     }
520 
521     if (INODE_IS_FS(node)) {
522         if ((node->ops.i_fops) != NULL) {
523             if ((node->ops.i_fops->write) != NULL) {
524                 nwrite = (node->ops.i_fops->write)(f, buf, nbytes);
525             }
526         }
527     } else {
528         if ((node->ops.i_ops) != NULL) {
529             if ((node->ops.i_ops->write) != NULL) {
530                 nwrite = (node->ops.i_ops->write)(f, buf, nbytes);
531             }
532         }
533     }
534 
535 ret:
536     if (vfs_unlock(node->lock) != VFS_OK) {
537         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
538         return VFS_ERR_LOCK;
539     }
540 
541     return nwrite;
542 }
543 
vfs_ioctl(int32_t fd,int32_t cmd,uint32_t arg)544 int32_t vfs_ioctl(int32_t fd, int32_t cmd, uint32_t arg)
545 {
546     int32_t ret = VFS_ERR_NOSYS;
547 
548     vfs_file_t  *f;
549     vfs_inode_t *node;
550 
551     if (fd < 0) {
552         return VFS_ERR_INVAL;
553     }
554 
555     f = vfs_file_get(fd);
556     if (f == NULL) {
557         return VFS_ERR_NOENT;
558     }
559 
560     node = f->node;
561 
562     if(node == NULL) {
563         return VFS_ERR_NOENT;
564     }
565 
566     if (vfs_lock(node->lock) != VFS_OK) {
567         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
568         return VFS_ERR_LOCK;
569     }
570 
571     if (node->status != VFS_INODE_VALID) {
572         vfs_unlock(node->lock);
573         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
574         goto ret;
575     }
576 
577     if (INODE_IS_FS(node)) {
578         if ((node->ops.i_fops->ioctl) != NULL) {
579             ret = (node->ops.i_fops->ioctl)(f, cmd, arg);
580         }
581     } else {
582         if ((node->ops.i_ops->ioctl) != NULL) {
583             ret = (node->ops.i_ops->ioctl)(f, cmd, arg);
584         }
585     }
586 
587 ret:
588     if (vfs_unlock(node->lock) != VFS_OK) {
589         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
590         return VFS_ERR_LOCK;
591     }
592 
593     return ret;
594 }
595 
vfs_do_pollfd(int32_t fd,int32_t flag,vfs_poll_notify_t notify,void * fds,void * arg)596 int32_t vfs_do_pollfd(int32_t fd, int32_t flag, vfs_poll_notify_t notify,
597                       void *fds, void *arg)
598 {
599     int32_t ret = VFS_ERR_NOSYS;
600 
601     vfs_file_t  *f;
602     vfs_inode_t *node;
603 
604 #if 0
605 #ifdef WITH_LWIP
606     if ((fd >= FD_AOS_SOCKET_OFFSET) &&
607         (fd <= (FD_AOS_EVENT_OFFSET + FD_AOS_NUM_EVENTS - 1))) {
608         return lwip_poll(fd, flag, notify, fds, arg);
609     }
610 
611     if ((fd >= FD_UDS_SOCKET_OFFSET) &&
612         (fd < FD_UDS_SOCKET_OFFSET + FD_UDS_SOCKET_NUM)) {
613         return uds_poll(fd, flag, notify, fds, arg);
614     }
615 #endif
616 #endif
617     f = vfs_file_get(fd);
618     if (f == NULL) {
619         return VFS_ERR_NOENT;
620     }
621 
622     node = f->node;
623 
624     if (vfs_lock(node->lock) != VFS_OK) {
625         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
626         return VFS_ERR_LOCK;
627     }
628 
629     if (node->status != VFS_INODE_VALID) {
630         vfs_unlock(node->lock);
631         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
632         return VFS_ERR_NOENT;
633     }
634 
635     if (!INODE_IS_FS(node)) {
636         if ((node->ops.i_ops->poll) != NULL) {
637             ret = (node->ops.i_ops->poll)(f, flag, notify, fds, arg);
638         }
639     }
640 
641     if (vfs_unlock(node->lock) != VFS_OK) {
642         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
643         return VFS_ERR_LOCK;
644     }
645 
646     return ret;
647 }
648 
vfs_lseek(int32_t fd,int64_t offset,int32_t whence)649 uint32_t vfs_lseek(int32_t fd, int64_t offset, int32_t whence)
650 {
651     int32_t ret = VFS_ERR_NOSYS;
652 
653     vfs_file_t  *f;
654     vfs_inode_t *node;
655 
656     f = vfs_file_get(fd);
657     if (f == NULL) {
658         return VFS_ERR_NOENT;
659     }
660 
661     node = f->node;
662 
663     if (vfs_lock(node->lock) != VFS_OK) {
664         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
665         return VFS_ERR_LOCK;
666     }
667 
668     if (node->status != VFS_INODE_VALID) {
669         vfs_unlock(node->lock);
670         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
671         return VFS_ERR_NOENT;
672     }
673 
674     if (INODE_IS_FS(node)) {
675         if ((node->ops.i_fops->lseek) != NULL) {
676             ret = (node->ops.i_fops->lseek)(f, offset, whence);
677         }
678     } else {
679         if ((node->ops.i_ops->lseek) != NULL) {
680             ret = (node->ops.i_ops->lseek)(f, offset, whence);
681         }
682     }
683 
684     if (vfs_unlock(node->lock) != VFS_OK) {
685         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
686         return VFS_ERR_LOCK;
687     }
688 
689     return ret;
690 }
691 
vfs_sync(int32_t fd)692 int32_t vfs_sync(int32_t fd)
693 {
694     int32_t ret = VFS_ERR_NOSYS;
695 
696     vfs_file_t  *f;
697     vfs_inode_t *node;
698 
699     f = vfs_file_get(fd);
700     if (f == NULL) {
701         return VFS_ERR_NOENT;
702     }
703 
704     node = f->node;
705 
706     if (vfs_lock(node->lock) != VFS_OK) {
707         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
708         return VFS_ERR_LOCK;
709     }
710 
711     if (node->status != VFS_INODE_VALID) {
712         vfs_unlock(node->lock);
713         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
714         return VFS_ERR_NOENT;
715     }
716 
717     if (INODE_IS_FS(node)) {
718         if ((node->ops.i_fops->sync) != NULL) {
719             ret = (node->ops.i_fops->sync)(f);
720         }
721     }
722 
723     if (vfs_unlock(node->lock) != VFS_OK) {
724         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
725         return VFS_ERR_LOCK;
726     }
727 
728     return ret;
729 }
730 
vfs_allsync(void)731 void vfs_allsync(void)
732 {
733     int i;
734     int32_t fd;
735 
736     /**
737      * prevent other threads from closing
738      * the file while syncing it
739      */
740     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
741         return;
742     }
743 
744     for (i = 0; i < VFS_MAX_FILE_NUM; i++) {
745         fd = VFS_FD_OFFSET + i;
746         if (vfs_fd_is_open(fd)) {
747             vfs_sync(fd);
748         }
749     }
750     vfs_unlock(g_vfs_lock_ptr);
751 }
752 
vfs_stat(const char * path,vfs_stat_t * st)753 int32_t vfs_stat(const char *path, vfs_stat_t *st)
754 {
755     int32_t ret = VFS_ERR_NOSYS;
756 
757     vfs_file_t  *f;
758     vfs_inode_t *node;
759 
760     if (path == NULL) {
761         return VFS_ERR_INVAL;
762     }
763 
764     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
765         return VFS_ERR_LOCK;
766     }
767 
768     node = vfs_inode_open(path);
769 
770     if (node == NULL) {
771         vfs_unlock(g_vfs_lock_ptr);
772         return VFS_ERR_NODEV;
773     }
774 
775     f = vfs_file_new(node);
776 
777     vfs_unlock(g_vfs_lock_ptr);
778 
779     if (f == NULL) {
780         return VFS_ERR_NOENT;
781     }
782 
783 #ifdef CONFIG_VFS_LSOPEN
784     strncpy(f->filename, path, sizeof(f->filename) - 1);
785 #endif
786 
787     if (vfs_lock(node->lock) != VFS_OK) {
788         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
789         ret = VFS_ERR_LOCK;
790         goto end;
791     }
792 
793     if (node->status != VFS_INODE_VALID) {
794         vfs_unlock(node->lock);
795         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
796         ret = VFS_ERR_NOENT;
797         goto end;
798     }
799 
800     if (INODE_IS_FS(node)) {
801         if ((node->ops.i_fops->stat) != NULL) {
802             ret = (node->ops.i_fops->stat)(f, path, st);
803         }
804     }
805     #if 0
806     else if (INODE_IS_CHAR(node) || INODE_IS_BLOCK(node)) {
807         if ((node->ops.i_ops->stat) != NULL) {
808             ret = (node->ops.i_ops->stat)(f, path, st);
809         } else {
810             ret = VFS_OK;
811 
812             if (INODE_IS_CHAR(node)) {
813                 st->st_mode &= ~S_IFMT;
814                 st->st_mode |= S_IFCHR;
815             }
816         }
817     }
818     #endif
819     if (vfs_unlock(node->lock) != VFS_OK) {
820         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
821         ret = VFS_ERR_LOCK;
822         goto end;
823     }
824 
825 end:
826     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
827         return VFS_ERR_LOCK;
828     }
829 
830     vfs_file_del(f);
831     vfs_unlock(g_vfs_lock_ptr);
832 
833     return ret;
834 }
835 
vfs_fstat(int fd,vfs_stat_t * st)836 int32_t vfs_fstat(int fd, vfs_stat_t *st)
837 {
838     int32_t ret = VFS_ERR_NOSYS;
839 
840     vfs_file_t  *f;
841     vfs_inode_t *node;
842 
843     f = vfs_file_get(fd);
844     if (f == NULL) {
845         return VFS_ERR_NOENT;
846     }
847 
848     node = f->node;
849 
850     if (vfs_lock(node->lock) != VFS_OK) {
851         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
852         return VFS_ERR_LOCK;
853     }
854 
855     if (node->status != VFS_INODE_VALID) {
856         vfs_unlock(node->lock);
857         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
858         return VFS_ERR_NOENT;
859     }
860 
861     if (INODE_IS_FS(node)) {
862         if ((node->ops.i_fops->fstat) != NULL) {
863             ret = (node->ops.i_fops->fstat)(f, st);
864         }
865     }
866 
867     if (vfs_unlock(node->lock) != VFS_OK) {
868         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
869         return VFS_ERR_LOCK;
870     }
871 
872     return ret;
873 }
874 
875 #ifdef AOS_PROCESS_SUPPORT
vfs_mmap(void * start,size_t len,int prot,int flags,int fd,off_t offset)876 void *vfs_mmap(void *start, size_t len, int prot, int flags, int fd, off_t offset)
877 {
878     void *ret = (void *)VFS_ERR_NOSYS;
879 
880     vfs_file_t  *f;
881     vfs_inode_t *node;
882 
883     f = vfs_file_get(fd);
884     if (f == NULL) {
885         return NULL;
886     }
887 
888     node = f->node;
889 
890     if (vfs_lock(node->lock) != VFS_OK) {
891         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
892         return NULL;
893     }
894 
895     if (node->status != VFS_INODE_VALID) {
896         vfs_unlock(node->lock);
897         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
898         return NULL;
899     }
900 
901     if (INODE_IS_CHAR(node) || INODE_IS_BLOCK(node)) {
902         if ((node->ops.i_ops->mmap) != NULL) {
903             ret = (node->ops.i_ops->mmap)(f, start, len, prot, flags, fd, offset);
904         }
905     }
906 
907     if (vfs_unlock(node->lock) != VFS_OK) {
908         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
909         return NULL;
910     }
911 
912     return ret;
913 }
914 #endif
915 
vfs_link(const char * oldpath,const char * newpath)916 int32_t vfs_link(const char *oldpath, const char *newpath)
917 {
918     int32_t ret = VFS_ERR_NOSYS;
919 
920     vfs_file_t  *f;
921     vfs_inode_t *node;
922 
923     if ((oldpath == NULL)||(newpath == NULL)) {
924         return VFS_ERR_INVAL;
925     }
926 
927     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
928         return VFS_ERR_LOCK;
929     }
930 
931     node = vfs_inode_open(oldpath);
932 
933     if (node == NULL) {
934         vfs_unlock(g_vfs_lock_ptr);
935         return VFS_ERR_NODEV;
936     }
937 
938     f = vfs_file_new(node);
939 
940     vfs_unlock(g_vfs_lock_ptr);
941 
942     if (f == NULL) {
943         return VFS_ERR_NOENT;
944     }
945 
946 #ifdef CONFIG_VFS_LSOPEN
947     strncpy(f->filename, oldpath, sizeof(f->filename) - 1);
948 #endif
949 
950     if (vfs_lock(node->lock) != VFS_OK) {
951         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
952         ret = VFS_ERR_LOCK;
953         goto end;
954     }
955 
956     if (node->status != VFS_INODE_VALID) {
957         vfs_unlock(node->lock);
958         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
959         ret = VFS_ERR_NOENT;
960         goto end;
961     }
962 
963     if (INODE_IS_FS(node)) {
964         if ((node->ops.i_fops->link) != NULL) {
965             ret = (node->ops.i_fops->link)(f, oldpath, newpath);
966         }
967     }
968 
969     if (vfs_unlock(node->lock) != VFS_OK) {
970         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
971         ret = VFS_ERR_LOCK;
972         goto end;
973     }
974 
975 end:
976     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
977         return VFS_ERR_LOCK;
978     }
979 
980     vfs_file_del(f);
981     vfs_unlock(g_vfs_lock_ptr);
982 
983     return ret;
984 }
985 
vfs_unlink(const char * path)986 int32_t vfs_unlink(const char *path)
987 {
988     int32_t ret = VFS_ERR_NOSYS;
989 
990     vfs_file_t  *f;
991     vfs_inode_t *node;
992 
993     if (path == NULL) {
994         return VFS_ERR_INVAL;
995     }
996 
997     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
998         return VFS_ERR_LOCK;
999     }
1000 
1001     node = vfs_inode_open(path);
1002 
1003     if (node == NULL) {
1004         vfs_unlock(g_vfs_lock_ptr);
1005         return VFS_ERR_NODEV;
1006     }
1007 
1008     f = vfs_file_new(node);
1009 
1010     vfs_unlock(g_vfs_lock_ptr);
1011 
1012     if (f == NULL) {
1013         return VFS_ERR_NOENT;
1014     }
1015 
1016 #ifdef CONFIG_VFS_LSOPEN
1017     strncpy(f->filename, path, sizeof(f->filename) - 1);
1018 #endif
1019 
1020     if (vfs_lock(node->lock) != VFS_OK) {
1021         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1022         ret = VFS_ERR_LOCK;
1023         goto end;
1024     }
1025 
1026     if (node->status != VFS_INODE_VALID) {
1027         vfs_unlock(node->lock);
1028         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1029         ret = VFS_ERR_NOENT;
1030         goto end;
1031     }
1032 
1033     if (INODE_IS_FS(node)) {
1034         if ((node->ops.i_fops->unlink) != NULL) {
1035             ret = (node->ops.i_fops->unlink)(f, path);
1036         }
1037     }
1038 
1039     if (vfs_unlock(node->lock) != VFS_OK) {
1040         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1041         ret = VFS_ERR_LOCK;
1042         goto end;
1043     }
1044 
1045 end:
1046     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1047         return VFS_ERR_LOCK;
1048     }
1049 
1050     vfs_file_del(f);
1051     vfs_unlock(g_vfs_lock_ptr);
1052 
1053     return ret;
1054 }
1055 
vfs_remove(const char * path)1056 int32_t vfs_remove(const char *path)
1057 {
1058     int32_t ret = VFS_ERR_NOSYS;
1059 
1060     vfs_file_t  *f;
1061     vfs_inode_t *node;
1062 
1063     if (path == NULL) {
1064         return VFS_ERR_INVAL;
1065     }
1066 
1067     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1068         return VFS_ERR_LOCK;
1069     }
1070 
1071     node = vfs_inode_open(path);
1072 
1073     if (node == NULL) {
1074         vfs_unlock(g_vfs_lock_ptr);
1075         return VFS_ERR_NODEV;
1076     }
1077 
1078     f = vfs_file_new(node);
1079 
1080     vfs_unlock(g_vfs_lock_ptr);
1081 
1082     if (f == NULL) {
1083         return VFS_ERR_NOENT;
1084     }
1085 
1086 #ifdef CONFIG_VFS_LSOPEN
1087     strncpy(f->filename, path, sizeof(f->filename) - 1);
1088 #endif
1089 
1090     if (vfs_lock(node->lock) != VFS_OK) {
1091         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1092         ret = VFS_ERR_LOCK;
1093         goto end;
1094     }
1095 
1096     if (node->status != VFS_INODE_VALID) {
1097         vfs_unlock(node->lock);
1098         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1099         ret = VFS_ERR_NOENT;
1100         goto end;
1101     }
1102 
1103     if (INODE_IS_FS(node)) {
1104         if ((node->ops.i_fops->remove) != NULL) {
1105             ret = (node->ops.i_fops->remove)(f, path);
1106         }
1107     }
1108 
1109     if (vfs_unlock(node->lock) != VFS_OK) {
1110         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1111         ret = VFS_ERR_LOCK;
1112         goto end;
1113     }
1114 
1115 end:
1116     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1117         return VFS_ERR_LOCK;
1118     }
1119 
1120     vfs_file_del(f);
1121     vfs_unlock(g_vfs_lock_ptr);
1122 
1123     return ret;
1124 }
1125 
vfs_rename(const char * oldpath,const char * newpath)1126 int32_t vfs_rename(const char *oldpath, const char *newpath)
1127 {
1128     int32_t ret = VFS_ERR_NOSYS;
1129 
1130     vfs_file_t  *f;
1131     vfs_inode_t *node;
1132 
1133     if ((oldpath == NULL) || (newpath == NULL)) {
1134         return VFS_ERR_INVAL;
1135     }
1136 
1137     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1138         return VFS_ERR_LOCK;
1139     }
1140 
1141     node = vfs_inode_open(oldpath);
1142 
1143     if (node == NULL) {
1144         vfs_unlock(g_vfs_lock_ptr);
1145         return VFS_ERR_NODEV;
1146     }
1147 
1148     f = vfs_file_new(node);
1149 
1150     vfs_unlock(g_vfs_lock_ptr);
1151 
1152     if (f == NULL) {
1153         return VFS_ERR_NOENT;
1154     }
1155 
1156 #ifdef CONFIG_VFS_LSOPEN
1157     strncpy(f->filename, oldpath, sizeof(f->filename) - 1);
1158 #endif
1159 
1160     if (vfs_lock(node->lock) != VFS_OK) {
1161         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1162         ret = VFS_ERR_LOCK;
1163         goto end;
1164     }
1165 
1166     if (node->status != VFS_INODE_VALID) {
1167         vfs_unlock(node->lock);
1168         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1169         ret = VFS_ERR_NOENT;
1170         goto end;
1171     }
1172 
1173     if (INODE_IS_FS(node)) {
1174         if ((node->ops.i_fops->rename) != NULL) {
1175             ret = (node->ops.i_fops->rename)(f, oldpath, newpath);
1176         }
1177     }
1178 
1179     if (vfs_unlock(node->lock) != VFS_OK) {
1180         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1181         ret = VFS_ERR_LOCK;
1182         goto end;
1183     }
1184 
1185 end:
1186     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1187         return VFS_ERR_LOCK;
1188     }
1189 
1190     vfs_file_del(f);
1191     vfs_unlock(g_vfs_lock_ptr);
1192 
1193     return ret;
1194 }
1195 
vfs_opendir(const char * path)1196 vfs_dir_t *vfs_opendir(const char *path)
1197 {
1198     vfs_dir_t *dp = NULL;
1199 
1200     vfs_file_t  *f;
1201     vfs_inode_t *node;
1202 
1203     if (path == NULL) {
1204         return NULL;
1205     }
1206 
1207     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1208         return NULL;
1209     }
1210 
1211     node = vfs_inode_open(path);
1212 
1213     if (node == NULL) {
1214         vfs_unlock(g_vfs_lock_ptr);
1215         return NULL;
1216     }
1217 
1218     f = vfs_file_new(node);
1219 
1220     vfs_unlock(g_vfs_lock_ptr);
1221 
1222     if (f == NULL) {
1223         return NULL;
1224     }
1225 
1226 #ifdef CONFIG_VFS_LSOPEN
1227     strncpy(f->filename, path, sizeof(f->filename) - 1);
1228 #endif
1229 
1230     if (vfs_lock(node->lock) != VFS_OK) {
1231         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1232         goto end;
1233     }
1234 
1235     if (node->status != VFS_INODE_VALID) {
1236         vfs_unlock(node->lock);
1237         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1238         goto end;
1239     }
1240 
1241     if (INODE_IS_FS(node)) {
1242         if ((node->ops.i_fops->opendir) != NULL) {
1243             dp = (node->ops.i_fops->opendir)(f, path);
1244         }
1245     }
1246 
1247     if (vfs_unlock(node->lock) != VFS_OK) {
1248         if (dp && (node->ops.i_fops->closedir) != NULL) {
1249             (node->ops.i_fops->closedir)(f, dp);
1250         }
1251 
1252         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1253         dp = NULL;
1254         goto end;
1255     }
1256 
1257 end:
1258     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1259         return NULL;
1260     }
1261 
1262     if (dp == NULL) {
1263         vfs_file_del(f);
1264 
1265         vfs_unlock(g_vfs_lock_ptr);
1266         return NULL;
1267     }
1268 
1269     dp->dd_vfs_fd = vfs_fd_get(f);
1270     vfs_fd_mark_open(dp->dd_vfs_fd);
1271 
1272     vfs_unlock(g_vfs_lock_ptr);
1273 
1274     return dp;
1275 }
1276 
vfs_closedir(vfs_dir_t * dir)1277 int32_t vfs_closedir(vfs_dir_t *dir)
1278 {
1279     int32_t ret = VFS_ERR_NOSYS;
1280 
1281     vfs_file_t  *f;
1282     vfs_inode_t *node;
1283 
1284     if (dir == NULL) {
1285         return VFS_ERR_INVAL;
1286     }
1287 
1288     f = vfs_file_get(dir->dd_vfs_fd);
1289     if (f == NULL) {
1290         return VFS_ERR_NOENT;
1291     }
1292 
1293     node = f->node;
1294 
1295     if (vfs_lock(node->lock) != VFS_OK) {
1296         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1297         return VFS_ERR_LOCK;
1298     }
1299 
1300     if (node->status != VFS_INODE_VALID) {
1301         vfs_unlock(node->lock);
1302         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1303         return VFS_ERR_NOENT;
1304     }
1305 
1306     if (INODE_IS_FS(node)) {
1307         if ((node->ops.i_fops->closedir) != NULL) {
1308             ret = (node->ops.i_fops->closedir)(f, dir);
1309         }
1310     }
1311 
1312     if (vfs_unlock(node->lock) != VFS_OK) {
1313         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1314         return VFS_ERR_LOCK;
1315     }
1316 
1317     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1318         return VFS_ERR_LOCK;
1319     }
1320 
1321     vfs_file_del(f);
1322 
1323     vfs_unlock(g_vfs_lock_ptr);
1324 
1325     return ret;
1326 }
1327 
vfs_readdir(vfs_dir_t * dir)1328 vfs_dirent_t *vfs_readdir(vfs_dir_t *dir)
1329 {
1330     vfs_dirent_t *dirent = NULL;
1331 
1332     vfs_file_t  *f;
1333     vfs_inode_t *node;
1334 
1335     if (dir == NULL) {
1336         return NULL;
1337     }
1338 
1339     f = vfs_file_get(dir->dd_vfs_fd);
1340     if (f == NULL) {
1341         return NULL;
1342     }
1343 
1344     node = f->node;
1345 
1346     if (vfs_lock(node->lock) != VFS_OK) {
1347         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1348         return NULL;
1349     }
1350 
1351     if (node->status != VFS_INODE_VALID) {
1352         vfs_unlock(node->lock);
1353         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1354         return NULL;
1355     }
1356 
1357     if (INODE_IS_FS(node)) {
1358         if ((node->ops.i_fops->readdir) != NULL) {
1359             dirent = (node->ops.i_fops->readdir)(f, dir);
1360         }
1361     }
1362 
1363     if (vfs_unlock(node->lock) != VFS_OK) {
1364         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1365         return NULL;
1366     }
1367 
1368     return dirent;
1369 }
1370 
vfs_mkdir(const char * path)1371 int32_t vfs_mkdir(const char *path)
1372 {
1373     int32_t ret = VFS_ERR_NOSYS;
1374 
1375     vfs_file_t  *f;
1376     vfs_inode_t *node;
1377 
1378     if (path == NULL) {
1379         return VFS_ERR_INVAL;
1380     }
1381 
1382     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1383         return VFS_ERR_LOCK;
1384     }
1385 
1386     node = vfs_inode_open(path);
1387 
1388     if (node == NULL) {
1389         vfs_unlock(g_vfs_lock_ptr);
1390         return VFS_ERR_NODEV;
1391     }
1392 
1393     f = vfs_file_new(node);
1394 
1395     vfs_unlock(g_vfs_lock_ptr);
1396 
1397     if (f == NULL) {
1398         return VFS_ERR_NOENT;
1399     }
1400 
1401 #ifdef CONFIG_VFS_LSOPEN
1402     strncpy(f->filename, path, sizeof(f->filename) - 1);
1403 #endif
1404 
1405     if (vfs_lock(node->lock) != VFS_OK) {
1406         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1407         ret = VFS_ERR_LOCK;
1408         goto end;
1409     }
1410 
1411     if (node->status != VFS_INODE_VALID) {
1412         vfs_unlock(node->lock);
1413         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1414         ret = VFS_ERR_NOENT;
1415         goto end;
1416     }
1417 
1418     if (INODE_IS_FS(node)) {
1419         if ((node->ops.i_fops->mkdir) != NULL) {
1420             ret = (node->ops.i_fops->mkdir)(f, path);
1421         }
1422     }
1423 
1424     if (vfs_unlock(node->lock) != VFS_OK) {
1425         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1426         ret = VFS_ERR_LOCK;
1427         goto end;
1428     }
1429 
1430 end:
1431     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1432         return VFS_ERR_LOCK;
1433     }
1434 
1435     vfs_file_del(f);
1436     vfs_unlock(g_vfs_lock_ptr);
1437 
1438     return ret;
1439 }
1440 
vfs_rmdir(const char * path)1441 int32_t vfs_rmdir(const char *path)
1442 {
1443     int32_t ret = VFS_ERR_NOSYS;
1444 
1445     vfs_file_t  *f;
1446     vfs_inode_t *node;
1447 
1448     if (path == NULL) {
1449         return VFS_ERR_INVAL;
1450     }
1451 
1452     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1453         return VFS_ERR_LOCK;
1454     }
1455 
1456     node = vfs_inode_open(path);
1457 
1458     if (node == NULL) {
1459         vfs_unlock(g_vfs_lock_ptr);
1460         return VFS_ERR_NODEV;
1461     }
1462 
1463     f = vfs_file_new(node);
1464 
1465     vfs_unlock(g_vfs_lock_ptr);
1466 
1467     if (f == NULL) {
1468         return VFS_ERR_NOENT;
1469     }
1470 
1471 #ifdef CONFIG_VFS_LSOPEN
1472     strncpy(f->filename, path, sizeof(f->filename) - 1);
1473 #endif
1474 
1475     if (vfs_lock(node->lock) != VFS_OK) {
1476         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1477         ret = VFS_ERR_LOCK;
1478         goto end;
1479     }
1480 
1481     if (node->status != VFS_INODE_VALID) {
1482         vfs_unlock(node->lock);
1483         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1484         ret = VFS_ERR_NOENT;
1485         goto end;
1486     }
1487 
1488     if (INODE_IS_FS(node)) {
1489         if ((node->ops.i_fops->rmdir) != NULL) {
1490             ret = (node->ops.i_fops->rmdir)(f, path);
1491         }
1492     }
1493 
1494     if (vfs_unlock(node->lock) != VFS_OK) {
1495         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1496         ret = VFS_ERR_LOCK;
1497         goto end;
1498     }
1499 
1500 end:
1501     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1502         return VFS_ERR_LOCK;
1503     }
1504 
1505     vfs_file_del(f);
1506     vfs_unlock(g_vfs_lock_ptr);
1507 
1508     return ret;
1509 }
1510 
vfs_rewinddir(vfs_dir_t * dir)1511 void vfs_rewinddir(vfs_dir_t *dir)
1512 {
1513     vfs_file_t  *f;
1514     vfs_inode_t *node;
1515 
1516     if (dir == NULL) {
1517         return;
1518     }
1519 
1520     f = vfs_file_get(dir->dd_vfs_fd);
1521     if (f == NULL) {
1522         return;
1523     }
1524 
1525     node = f->node;
1526 
1527     if (vfs_lock(node->lock) != VFS_OK) {
1528         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1529         return;
1530     }
1531 
1532     if (node->status != VFS_INODE_VALID) {
1533         vfs_unlock(node->lock);
1534         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1535         return;
1536     }
1537 
1538     if (INODE_IS_FS(node)) {
1539         if ((node->ops.i_fops->rewinddir) != NULL) {
1540             (node->ops.i_fops->rewinddir)(f, dir);
1541         }
1542     }
1543 
1544     if (vfs_unlock(node->lock) != VFS_OK) {
1545         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1546     }
1547 
1548     return;
1549 }
1550 
vfs_telldir(vfs_dir_t * dir)1551 int32_t vfs_telldir(vfs_dir_t *dir)
1552 {
1553     vfs_file_t  *f;
1554     vfs_inode_t *node;
1555 
1556     int32_t ret = 0;
1557 
1558     if (dir == NULL) {
1559         return VFS_ERR_INVAL;
1560     }
1561 
1562     f = vfs_file_get(dir->dd_vfs_fd);
1563     if (f == NULL) {
1564         return VFS_ERR_NOENT;
1565     }
1566 
1567     node = f->node;
1568 
1569     if (vfs_lock(node->lock) != VFS_OK) {
1570         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1571         return VFS_ERR_LOCK;
1572     }
1573 
1574     if (node->status != VFS_INODE_VALID) {
1575         vfs_unlock(node->lock);
1576         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1577         return VFS_ERR_NOENT;
1578     }
1579 
1580     if (INODE_IS_FS(node)) {
1581         if ((node->ops.i_fops->telldir) != NULL) {
1582             ret = (node->ops.i_fops->telldir)(f, dir);
1583         }
1584     }
1585 
1586     if (vfs_unlock(node->lock) != VFS_OK) {
1587         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1588         return VFS_ERR_LOCK;
1589     }
1590 
1591     return ret;
1592 }
1593 
vfs_seekdir(vfs_dir_t * dir,int32_t loc)1594 void vfs_seekdir(vfs_dir_t *dir, int32_t loc)
1595 {
1596     vfs_file_t  *f;
1597     vfs_inode_t *node;
1598 
1599     if (dir == NULL) {
1600         return;
1601     }
1602 
1603     f = vfs_file_get(dir->dd_vfs_fd);
1604     if (f == NULL) {
1605         return;
1606     }
1607 
1608     node = f->node;
1609 
1610     if (vfs_lock(node->lock) != VFS_OK) {
1611         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1612         return;
1613     }
1614 
1615     if (node->status != VFS_INODE_VALID) {
1616         vfs_unlock(node->lock);
1617         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1618         return;
1619     }
1620 
1621     if (INODE_IS_FS(node)) {
1622         if ((node->ops.i_fops->seekdir) != NULL) {
1623             (node->ops.i_fops->seekdir)(f, dir, loc);
1624         }
1625     }
1626 
1627     if (vfs_unlock(node->lock) != VFS_OK) {
1628         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1629     }
1630 
1631     return;
1632 }
1633 
vfs_statfs(const char * path,vfs_statfs_t * buf)1634 int32_t vfs_statfs(const char *path, vfs_statfs_t *buf)
1635 {
1636     int32_t ret = VFS_ERR_NOSYS;
1637 
1638     vfs_file_t  *f;
1639     vfs_inode_t *node;
1640 
1641     if (path == NULL) {
1642         return VFS_ERR_INVAL;
1643     }
1644 
1645     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1646         return VFS_ERR_LOCK;
1647     }
1648 
1649     node = vfs_inode_open(path);
1650 
1651     if (node == NULL) {
1652         vfs_unlock(g_vfs_lock_ptr);
1653         return VFS_ERR_NODEV;
1654     }
1655 
1656     f = vfs_file_new(node);
1657 
1658     vfs_unlock(g_vfs_lock_ptr);
1659 
1660     if (f == NULL) {
1661         return VFS_ERR_NOENT;
1662     }
1663 
1664 #ifdef CONFIG_VFS_LSOPEN
1665     strncpy(f->filename, path, sizeof(f->filename) - 1);
1666 #endif
1667 
1668     if (vfs_lock(node->lock) != VFS_OK) {
1669         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1670         ret = VFS_ERR_LOCK;
1671         goto end;
1672     }
1673 
1674     if (node->status != VFS_INODE_VALID) {
1675         vfs_unlock(node->lock);
1676         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1677         ret = VFS_ERR_NOENT;
1678         goto end;
1679     }
1680 
1681     if (INODE_IS_FS(node)) {
1682         if ((node->ops.i_fops->statfs) != NULL) {
1683             ret = (node->ops.i_fops->statfs)(f, path, buf);
1684         }
1685     }
1686 
1687     if (vfs_unlock(node->lock) != VFS_OK) {
1688         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1689         ret = VFS_ERR_LOCK;
1690         goto end;
1691     }
1692 
1693 end:
1694     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1695         return VFS_ERR_LOCK;
1696     }
1697 
1698     vfs_file_del(f);
1699     vfs_unlock(g_vfs_lock_ptr);
1700 
1701     return ret;
1702 }
1703 
vfs_access(const char * path,int32_t amode)1704 int32_t vfs_access(const char *path, int32_t amode)
1705 {
1706     int32_t ret = VFS_ERR_NOSYS;
1707 
1708     vfs_file_t  *f;
1709     vfs_inode_t *node;
1710 
1711     if (path == NULL) {
1712         return VFS_ERR_INVAL;
1713     }
1714 
1715     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1716         return VFS_ERR_LOCK;
1717     }
1718 
1719     node = vfs_inode_open(path);
1720 
1721     if (node == NULL) {
1722         vfs_unlock(g_vfs_lock_ptr);
1723         return VFS_ERR_NODEV;
1724     }
1725 
1726     f = vfs_file_new(node);
1727 
1728     vfs_unlock(g_vfs_lock_ptr);
1729 
1730     if (f == NULL) {
1731         return VFS_ERR_NOENT;
1732     }
1733 
1734 #ifdef CONFIG_VFS_LSOPEN
1735     strncpy(f->filename, path, sizeof(f->filename) - 1);
1736 #endif
1737 
1738     if (vfs_lock(node->lock) != VFS_OK) {
1739         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1740         ret = VFS_ERR_LOCK;
1741         goto end;
1742     }
1743 
1744     if (node->status != VFS_INODE_VALID) {
1745         vfs_unlock(node->lock);
1746         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1747         ret = VFS_ERR_NOENT;
1748         goto end;
1749     }
1750 
1751     if (INODE_IS_FS(node)) {
1752         if ((node->ops.i_fops->access) != NULL) {
1753             ret = (node->ops.i_fops->access)(f, path, amode);
1754         }
1755     } else {
1756         ret = VFS_OK; // always OK for devices
1757     }
1758 
1759     if (vfs_unlock(node->lock) != VFS_OK) {
1760         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1761         ret = VFS_ERR_LOCK;
1762         goto end;
1763     }
1764 
1765 end:
1766     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1767         return VFS_ERR_LOCK;
1768     }
1769 
1770     vfs_file_del(f);
1771     vfs_unlock(g_vfs_lock_ptr);
1772 
1773     return ret;
1774 }
1775 
vfs_chdir(const char * path)1776 int vfs_chdir(const char *path)
1777 {
1778 #if (CURRENT_WORKING_DIRECTORY_ENABLE > 0)
1779     if ((path == NULL) || (strlen(path) > VFS_PATH_MAX)){
1780         return VFS_ERR_NAMETOOLONG;
1781     }
1782 
1783     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1784         return VFS_ERR_LOCK;
1785     }
1786 
1787     memset(g_current_working_directory, 0, sizeof(g_current_working_directory));
1788     strncpy(g_current_working_directory, path, strlen(path) + 1);
1789 
1790     vfs_unlock(g_vfs_lock_ptr);
1791 
1792     return VFS_OK;
1793 #else
1794     return VFS_ERR_INVAL;
1795 #endif
1796 }
1797 
vfs_getcwd(char * buf,size_t size)1798 char *vfs_getcwd(char *buf, size_t size)
1799 {
1800 #if (CURRENT_WORKING_DIRECTORY_ENABLE > 0)
1801     if ((buf == NULL) || (size < strlen(g_current_working_directory))) {
1802         return NULL;
1803     }
1804 
1805     strncpy(buf, g_current_working_directory, strlen(g_current_working_directory) + 1);
1806 
1807     return buf;
1808 #else
1809     return NULL;
1810 #endif
1811 }
1812 
1813 
vfs_pathconf(const char * path,int name)1814 int32_t vfs_pathconf(const char *path, int name)
1815 {
1816     int32_t ret = VFS_ERR_NOSYS;
1817 
1818     vfs_file_t  *f;
1819     vfs_inode_t *node;
1820 
1821     if (path == NULL) {
1822         return VFS_ERR_INVAL;
1823     }
1824 
1825     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1826         return VFS_ERR_LOCK;
1827     }
1828 
1829     node = vfs_inode_open(path);
1830 
1831     if (node == NULL) {
1832         vfs_unlock(g_vfs_lock_ptr);
1833         return VFS_ERR_NODEV;
1834     }
1835 
1836     f = vfs_file_new(node);
1837 
1838     vfs_unlock(g_vfs_lock_ptr);
1839 
1840     if (f == NULL) {
1841         return VFS_ERR_NOENT;
1842     }
1843 
1844 #ifdef CONFIG_VFS_LSOPEN
1845     strncpy(f->filename, path, sizeof(f->filename) - 1);
1846 #endif
1847 
1848     if (vfs_lock(node->lock) != VFS_OK) {
1849         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1850         ret = VFS_ERR_LOCK;
1851         goto end;
1852     }
1853 
1854     if (node->status != VFS_INODE_VALID) {
1855         vfs_unlock(node->lock);
1856         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1857         ret = VFS_ERR_NOENT;
1858         goto end;
1859     }
1860 
1861     if (INODE_IS_FS(node)) {
1862         if ((node->ops.i_fops->pathconf) != NULL) {
1863             ret = (node->ops.i_fops->pathconf)(f, path, name);
1864         }
1865     }
1866 
1867     if (vfs_unlock(node->lock) != VFS_OK) {
1868         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1869         ret = VFS_ERR_LOCK;
1870         goto end;
1871     }
1872 
1873 end:
1874     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1875         return VFS_ERR_LOCK;
1876     }
1877 
1878     vfs_file_del(f);
1879     vfs_unlock(g_vfs_lock_ptr);
1880 
1881     return ret;
1882 }
1883 
vfs_fpathconf(int fd,int name)1884 int32_t vfs_fpathconf(int fd, int name)
1885 {
1886     int32_t ret = VFS_ERR_NOSYS;
1887 
1888     vfs_file_t  *file;
1889     vfs_inode_t *node;
1890 
1891     file = vfs_file_get(fd);
1892     if (file == NULL) {
1893         return VFS_ERR_NOENT;
1894     }
1895 
1896     node = file->node;
1897 
1898     if (vfs_lock(node->lock) != VFS_OK) {
1899         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1900         return VFS_ERR_LOCK;
1901     }
1902 
1903     if (node->status != VFS_INODE_VALID) {
1904         vfs_unlock(node->lock);
1905         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1906         return VFS_ERR_NOENT;
1907     }
1908 
1909     if (INODE_IS_FS(node)) {
1910         if ((node->ops.i_fops->fpathconf) != NULL) {
1911             ret = (node->ops.i_fops->fpathconf)(file, name);
1912         }
1913     }
1914 
1915     if (vfs_unlock(node->lock) != VFS_OK) {
1916         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1917         return VFS_ERR_LOCK;
1918     }
1919 
1920     return ret;
1921 }
1922 
vfs_utime(const char * path,const vfs_utimbuf_t * times)1923 int vfs_utime(const char *path, const vfs_utimbuf_t *times)
1924 {
1925     int32_t ret = VFS_ERR_NOSYS;
1926 
1927     vfs_file_t  *f;
1928     vfs_inode_t *node;
1929 
1930     if (path == NULL) {
1931         return VFS_ERR_INVAL;
1932     }
1933 
1934     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1935         return VFS_ERR_LOCK;
1936     }
1937 
1938     node = vfs_inode_open(path);
1939 
1940     if (node == NULL) {
1941         vfs_unlock(g_vfs_lock_ptr);
1942         return VFS_ERR_NODEV;
1943     }
1944 
1945     f = vfs_file_new(node);
1946 
1947     vfs_unlock(g_vfs_lock_ptr);
1948 
1949     if (f == NULL) {
1950         return VFS_ERR_NOENT;
1951     }
1952 
1953 #ifdef CONFIG_VFS_LSOPEN
1954     strncpy(f->filename, path, sizeof(f->filename) - 1);
1955 #endif
1956 
1957     if (vfs_lock(node->lock) != VFS_OK) {
1958         VFS_ERROR("%s failed to lock inode %p!\n\r", __func__, node);
1959         ret = VFS_ERR_LOCK;
1960         goto end;
1961     }
1962 
1963     if (node->status != VFS_INODE_VALID) {
1964         vfs_unlock(node->lock);
1965         VFS_ERROR("%s node %p is invalid now!\n\r", __func__, node);
1966         ret = VFS_ERR_NOENT;
1967         goto end;
1968     }
1969 
1970     if (INODE_IS_FS(node)) {
1971         if ((node->ops.i_fops->utime) != NULL) {
1972             ret = (node->ops.i_fops->utime)(f, path, times);
1973         }
1974     }
1975 
1976     if (vfs_unlock(node->lock) != VFS_OK) {
1977         VFS_ERROR("%s failed to unlock inode %p!\n\r", __func__, node);
1978         ret = VFS_ERR_LOCK;
1979         goto end;
1980     }
1981 
1982 end:
1983     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
1984         return VFS_ERR_LOCK;
1985     }
1986 
1987     vfs_file_del(f);
1988     vfs_unlock(g_vfs_lock_ptr);
1989 
1990     return ret;
1991 }
1992 
vfs_fd_offset_get(void)1993 int32_t vfs_fd_offset_get(void)
1994 {
1995     return VFS_FD_OFFSET;
1996 }
1997 
vfs_fcntl(int fd,int cmd,int val)1998 int vfs_fcntl(int fd, int cmd, int val)
1999 {
2000     if (fd < 0) {
2001         return -EINVAL;
2002     }
2003 
2004     if (fd < vfs_fd_offset_get()) {
2005 #ifdef IO_NEED_TRAP
2006         return trap_fcntl(fd, cmd, val);
2007 #else
2008         return -ENOENT;
2009 #endif
2010     }
2011 
2012     return 0;
2013 }
2014 
vfs_register_driver(const char * path,vfs_file_ops_t * ops,void * arg)2015 int32_t vfs_register_driver(const char *path, vfs_file_ops_t *ops, void *arg)
2016 {
2017     int32_t ret = VFS_ERR_NOSYS;
2018 
2019     vfs_inode_t *node = NULL;
2020 
2021     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
2022         return VFS_ERR_LOCK;
2023     }
2024 
2025     node = vfs_inode_open(path);
2026     if(NULL != node)
2027     {
2028         VFS_ERROR("%s failed to register, the path has exist %s, %d!\n\r", __func__, path, node->status);
2029         vfs_unlock(g_vfs_lock_ptr);
2030         return VFS_ERR_INVAL;
2031     }
2032 
2033     ret = vfs_inode_reserve(path, &node);
2034     if (ret == VFS_OK) {
2035         INODE_SET_CHAR(node);
2036 
2037         node->ops.i_ops = ops;
2038         node->i_arg     = arg;
2039     }
2040 
2041     if (vfs_unlock(g_vfs_lock_ptr) != VFS_OK) {
2042         if (node->i_name != NULL) {
2043             vfs_free(node->i_name);
2044         }
2045 
2046         memset(node, 0, sizeof(vfs_inode_t));
2047         return VFS_ERR_LOCK;
2048     }
2049 
2050     return ret;
2051 }
2052 
vfs_unregister_driver(const char * path)2053 int32_t vfs_unregister_driver(const char *path)
2054 {
2055     int32_t ret;
2056 
2057     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
2058         return VFS_ERR_LOCK;
2059     }
2060 
2061     ret = vfs_inode_release(path);
2062 
2063     if (vfs_unlock(g_vfs_lock_ptr) != VFS_OK) {
2064         return VFS_ERR_LOCK;
2065     }
2066 
2067     return ret;
2068 }
2069 
vfs_register_fs(const char * path,vfs_filesystem_ops_t * ops,void * arg)2070 int32_t vfs_register_fs(const char *path, vfs_filesystem_ops_t* ops, void *arg)
2071 {
2072     int32_t ret;
2073 
2074     vfs_inode_t *node = NULL;
2075 
2076     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
2077         return VFS_ERR_LOCK;
2078     }
2079 
2080     node = vfs_inode_open(path);
2081     if(NULL != node)
2082     {
2083         VFS_ERROR("%s failed to register, the path has exist %s, %d!\n\r", __func__, path, node->status);
2084         vfs_unlock(g_vfs_lock_ptr);
2085         return VFS_ERR_INVAL;
2086     }
2087 
2088     ret = vfs_inode_reserve(path, &node);
2089     if (ret == VFS_OK) {
2090         INODE_SET_FS(node);
2091 
2092         node->ops.i_fops = ops;
2093         node->i_arg      = arg;
2094     }
2095 
2096     if (vfs_unlock(g_vfs_lock_ptr) != VFS_OK) {
2097         if (node->i_name != NULL) {
2098             vfs_free(node->i_name);
2099         }
2100 
2101         memset(node, 0, sizeof(vfs_inode_t));
2102         return VFS_ERR_LOCK;
2103     }
2104 
2105     return ret;
2106 }
2107 
vfs_unregister_fs(const char * path)2108 int32_t vfs_unregister_fs(const char *path)
2109 {
2110     int32_t ret;
2111 
2112     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
2113         return VFS_ERR_LOCK;
2114     }
2115 
2116     ret = vfs_inode_release(path);
2117 
2118     if (vfs_unlock(g_vfs_lock_ptr) != VFS_OK) {
2119         return VFS_ERR_LOCK;
2120     }
2121 
2122     return ret;
2123 }
2124 
2125 
2126 
2127 #ifdef CONFIG_VFS_LSOPEN
vfs_dump_open()2128 void vfs_dump_open()
2129 {
2130     vfs_lock(g_vfs_lock_ptr);
2131     vfs_file_open_dump();
2132     vfs_unlock(g_vfs_lock_ptr);
2133 }
2134 #endif
2135 
vfs_list(vfs_list_type_t t)2136 int32_t vfs_list(vfs_list_type_t t)
2137 {
2138     return vfs_inode_list(t);
2139 }
2140 
vfs_get_node_name(const char * path,char names[][64],uint32_t * size)2141 int32_t vfs_get_node_name(const char *path, char names[][64], uint32_t* size)
2142 {
2143     return vfs_inode_get_names(path, names, size);
2144 }
vfs_dup(int oldfd)2145 int vfs_dup(int oldfd)
2146 {
2147     int ret = VFS_ERR_GENERAL, realold = oldfd - VFS_FD_OFFSET;;
2148     vfs_file_t *f;
2149 
2150     if (vfs_lock(g_vfs_lock_ptr) != VFS_OK) {
2151         return VFS_ERR_LOCK;
2152     }
2153 
2154     if (realold < 0 || realold >= VFS_MAX_FILE_NUM || !vfs_fd_is_open(oldfd)) {
2155         vfs_unlock(g_vfs_lock_ptr);
2156         return VFS_ERR_GENERAL;
2157     }
2158 
2159     /* -1 as *node, just for NULL check, do NOT really use it! */
2160     f = vfs_file_new((vfs_inode_t *)(-1));
2161     if (f) {
2162         ret = vfs_fd_get(f);
2163         vfs_fd_mark_open(ret);
2164         f->redirect_fd = oldfd;
2165     } else {
2166         ret = VFS_ERR_GENERAL;
2167     }
2168 
2169     vfs_unlock(g_vfs_lock_ptr);
2170 
2171     return ret;
2172 }
2173 
vfs_dup2(int oldfd,int newfd)2174 int vfs_dup2(int oldfd, int newfd)
2175 {
2176     if (is_stdio_fd(newfd)) {
2177         return set_stdio_redirect_fd(newfd, oldfd) == 0 ? VFS_OK : VFS_ERR_GENERAL;
2178     } else {
2179         return set_normal_redirect_fd(oldfd, newfd) >= 0 ? newfd : VFS_ERR_GENERAL;
2180     }
2181 }
2182