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