1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #define _GNU_SOURCE 1
33 #include "lfs_api.h"
34 #include "los_config.h"
35 #include "los_mux.h"
36 #include "los_debug.h"
37 #include "securec.h"
38
39 lfs_t g_lfs;
40 FileDirInfo g_lfsDir[LFS_MAX_OPEN_DIRS] = {0};
41
42 struct FileOpInfo g_fsOp[LOSCFG_LFS_MAX_MOUNT_SIZE] = {0};
43 static LittleFsHandleStruct g_handle[LOSCFG_LFS_MAX_OPEN_FILES] = {0};
44 struct dirent g_nameValue;
45 static const char *g_littlefsMntName[LOSCFG_LFS_MAX_MOUNT_SIZE] = {"/a", "/littlefs"};
46 #define LFS_MUTEX_UNINIT (-1)
47 static UINT32 g_lfsMutex = LFS_MUTEX_UNINIT;
48
LfsLock(void)49 static int LfsLock(void)
50 {
51 if (LOS_MuxPend(g_lfsMutex, LOS_WAIT_FOREVER) != LOS_OK) {
52 PRINT_ERR("LfsLock failed!");
53 return LOS_NOK;
54 }
55
56 return LOS_OK;
57 }
58
LfsUnlock(void)59 static void LfsUnlock(void)
60 {
61 (void)LOS_MuxPost(g_lfsMutex);
62 }
63
LfsAllocFd(const char * fileName,int * fd)64 LittleFsHandleStruct *LfsAllocFd(const char *fileName, int *fd)
65 {
66 for (int i = 0; i < LOSCFG_LFS_MAX_OPEN_FILES; i++) {
67 if (g_handle[i].useFlag == 0) {
68 *fd = i;
69 g_handle[i].useFlag = 1;
70 g_handle[i].pathName = strdup(fileName);
71 return &(g_handle[i]);
72 }
73 }
74 *fd = INVALID_FD;
75 return NULL;
76 }
77
LfsFreeFd(int fd)78 static void LfsFreeFd(int fd)
79 {
80 g_handle[fd].useFlag = 0;
81 if (g_handle[fd].pathName != NULL) {
82 free((void *)g_handle[fd].pathName);
83 g_handle[fd].pathName = NULL;
84 }
85
86 if (g_handle[fd].lfsHandle != NULL) {
87 g_handle[fd].lfsHandle = NULL;
88 }
89 }
90
CheckFileIsOpen(const char * fileName)91 BOOL CheckFileIsOpen(const char *fileName)
92 {
93 for (int i = 0; i < LOSCFG_LFS_MAX_OPEN_FILES; i++) {
94 if (g_handle[i].useFlag == 1) {
95 if (strcmp(g_handle[i].pathName, fileName) == 0) {
96 return TRUE;
97 }
98 }
99 }
100 return FALSE;
101 }
102
LfsFdIsValid(int fd)103 static BOOL LfsFdIsValid(int fd)
104 {
105 if (fd >= LOSCFG_LFS_MAX_OPEN_FILES || fd < 0) {
106 return FALSE;
107 }
108 if (g_handle[fd].lfsHandle == NULL) {
109 return FALSE;
110 }
111 return TRUE;
112 }
113
GetFreeDir(const char * dirName)114 FileDirInfo *GetFreeDir(const char *dirName)
115 {
116 for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) {
117 if (g_lfsDir[i].useFlag == 0) {
118 g_lfsDir[i].useFlag = 1;
119 g_lfsDir[i].dirName = strdup(dirName);
120 return &(g_lfsDir[i]);
121 }
122 }
123 return NULL;
124 }
125
FreeDirInfo(const char * dirName)126 void FreeDirInfo(const char *dirName)
127 {
128 for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) {
129 if (g_lfsDir[i].useFlag == 1 && strcmp(g_lfsDir[i].dirName, dirName) == 0) {
130 g_lfsDir[i].useFlag = 0;
131 if (g_lfsDir[i].dirName) {
132 free(g_lfsDir[i].dirName);
133 g_lfsDir[i].dirName = NULL;
134 }
135 }
136 }
137 }
138
CheckDirIsOpen(const char * dirName)139 BOOL CheckDirIsOpen(const char *dirName)
140 {
141 for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) {
142 if (g_lfsDir[i].useFlag == 1) {
143 if (strcmp(g_lfsDir[i].dirName, dirName) == 0) {
144 return TRUE;
145 }
146 }
147 }
148 return FALSE;
149 }
150
GetFirstLevelPathLen(const char * pathName)151 int GetFirstLevelPathLen(const char *pathName)
152 {
153 int len = 1;
154 for (int i = 1; i < strlen(pathName) + 1; i++) {
155 if (pathName[i] == '/') {
156 break;
157 }
158 len++;
159 }
160
161 return len;
162 }
163
CheckPathIsMounted(const char * pathName,struct FileOpInfo ** fileOpInfo)164 BOOL CheckPathIsMounted(const char *pathName, struct FileOpInfo **fileOpInfo)
165 {
166 char tmpName[LITTLEFS_MAX_LFN_LEN] = {0};
167 int len = GetFirstLevelPathLen(pathName);
168
169 for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
170 if (g_fsOp[i].useFlag == 1) {
171 (void)strncpy_s(tmpName, LITTLEFS_MAX_LFN_LEN, pathName, len);
172 if (strcmp(tmpName, g_fsOp[i].dirName) == 0) {
173 *fileOpInfo = &(g_fsOp[i]);
174 return TRUE;
175 }
176 }
177 }
178 return FALSE;
179 }
180
AllocMountRes(const char * target,const struct FileOps * fileOps)181 struct FileOpInfo *AllocMountRes(const char* target, const struct FileOps *fileOps)
182 {
183 for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
184 if (g_fsOp[i].useFlag == 0 && strcmp(target, g_littlefsMntName[i]) == 0) {
185 g_fsOp[i].useFlag = 1;
186 g_fsOp[i].fsVops = fileOps;
187 g_fsOp[i].dirName = strdup(target);
188 return &(g_fsOp[i]);
189 }
190 }
191
192 return NULL;
193 }
194
SetDefaultMountPath(int pathNameIndex,const char * target)195 int SetDefaultMountPath(int pathNameIndex, const char* target)
196 {
197 if (pathNameIndex >= LOSCFG_LFS_MAX_MOUNT_SIZE) {
198 return VFS_ERROR;
199 }
200
201 g_littlefsMntName[pathNameIndex] = strdup(target);
202 return VFS_OK;
203 }
204
GetMountRes(const char * target,int * mountIndex)205 struct FileOpInfo *GetMountRes(const char *target, int *mountIndex)
206 {
207 for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
208 if (g_fsOp[i].useFlag == 1) {
209 if (g_fsOp[i].dirName && strcmp(target, g_fsOp[i].dirName) == 0) {
210 *mountIndex = i;
211 return &(g_fsOp[i]);
212 }
213 }
214 }
215
216 return NULL;
217 }
218
FreeMountResByIndex(int mountIndex)219 int FreeMountResByIndex(int mountIndex)
220 {
221 if (mountIndex < 0 || mountIndex >= LOSCFG_LFS_MAX_MOUNT_SIZE) {
222 return VFS_ERROR;
223 }
224
225 if (g_fsOp[mountIndex].useFlag == 1 && g_fsOp[mountIndex].dirName != NULL) {
226 g_fsOp[mountIndex].useFlag = 0;
227 free(g_fsOp[mountIndex].dirName);
228 g_fsOp[mountIndex].dirName = NULL;
229 }
230
231 return VFS_OK;
232 }
233
FreeMountRes(const char * target)234 int FreeMountRes(const char *target)
235 {
236 for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
237 if (g_fsOp[i].useFlag == 1) {
238 if (g_fsOp[i].dirName && strcmp(target, g_fsOp[i].dirName) == 0) {
239 g_fsOp[i].useFlag = 0;
240 free(g_fsOp[i].dirName);
241 g_fsOp[i].dirName = NULL;
242 return VFS_OK;
243 }
244 }
245 }
246
247 return VFS_ERROR;
248 }
249
ConvertFlagToLfsOpenFlag(int oflags)250 static int ConvertFlagToLfsOpenFlag (int oflags)
251 {
252 int lfsOpenFlag = 0;
253
254 if (oflags & O_CREAT) {
255 lfsOpenFlag |= LFS_O_CREAT;
256 }
257
258 if (oflags & O_EXCL) {
259 lfsOpenFlag |= LFS_O_EXCL;
260 }
261
262 if (oflags & O_TRUNC) {
263 lfsOpenFlag |= LFS_O_TRUNC;
264 }
265
266 if (oflags & O_APPEND) {
267 lfsOpenFlag |= LFS_O_APPEND;
268 }
269
270 if (oflags & O_RDWR) {
271 lfsOpenFlag |= LFS_O_RDWR;
272 }
273
274 if (oflags & O_WRONLY) {
275 lfsOpenFlag |= LFS_O_WRONLY;
276 }
277
278 if (oflags == O_RDONLY) {
279 lfsOpenFlag |= LFS_O_RDONLY;
280 }
281
282 return lfsOpenFlag;
283 }
284
LittlefsErrno(int result)285 static int LittlefsErrno(int result)
286 {
287 return (result < 0) ? -result : result;
288 }
289
290 const struct MountOps g_lfsMnt = {
291 .Mount = LfsMount,
292 .Umount = LfsUmount,
293 };
294
295 const struct FileOps g_lfsFops = {
296 .Mkdir = LfsMkdir,
297 .Unlink = LfsUnlink,
298 .Rmdir = LfsRmdir,
299 .Opendir = LfsOpendir,
300 .Readdir = LfsReaddir,
301 .Closedir = LfsClosedir,
302 .Open = LfsOpen,
303 .Close = LfsClose,
304 .Write = LfsWrite,
305 .Read = LfsRead,
306 .Seek = LfsSeek,
307 .Rename = LfsRename,
308 .Getattr = LfsStat,
309 .Fsync = LfsFsync,
310 .Fstat = LfsFstat,
311 .Pread = LfsPread,
312 .Pwrite = LfsPwrite,
313 };
314
LfsMount(const char * source,const char * target,const char * fileSystemType,unsigned long mountflags,const void * data)315 int LfsMount(const char *source, const char *target, const char *fileSystemType, unsigned long mountflags,
316 const void *data)
317 {
318 int ret;
319 struct FileOpInfo *fileOpInfo = NULL;
320
321 if (target == NULL || fileSystemType == NULL || data == NULL) {
322 errno = EFAULT;
323 return VFS_ERROR;
324 }
325
326 if (strcmp(fileSystemType, "littlefs") != 0) {
327 errno = ENODEV;
328 return VFS_ERROR;
329 }
330
331 if (g_lfsMutex == LFS_MUTEX_UNINIT) {
332 if (LOS_MuxCreate(&g_lfsMutex) != LOS_OK) {
333 errno = EBUSY;
334 return VFS_ERROR;
335 }
336 }
337
338 if (LfsLock() != LOS_OK) {
339 errno = EAGAIN;
340 return VFS_ERROR;
341 }
342
343 if (CheckPathIsMounted(target, &fileOpInfo)) {
344 errno = EBUSY;
345 ret = VFS_ERROR;
346 goto ERROUT;
347 }
348
349 // select free mount resource
350 fileOpInfo = AllocMountRes(target, &g_lfsFops);
351 if (fileOpInfo == NULL) {
352 errno = ENODEV;
353 ret = VFS_ERROR;
354 goto ERROUT;
355 }
356
357 ret = lfs_mount(&(fileOpInfo->lfsInfo), (struct lfs_config*)data);
358 if (ret != 0) {
359 ret = lfs_format(&(fileOpInfo->lfsInfo), (struct lfs_config*)data);
360 if (ret == 0) {
361 ret = lfs_mount(&(fileOpInfo->lfsInfo), (struct lfs_config*)data);
362 }
363 }
364
365 if (ret != 0) {
366 errno = LittlefsErrno(ret);
367 ret = VFS_ERROR;
368 }
369
370 ERROUT:
371 LfsUnlock();
372 return ret;
373 }
374
LfsUmount(const char * target)375 int LfsUmount(const char *target)
376 {
377 int ret;
378 int mountIndex = -1;
379 struct FileOpInfo *fileOpInfo = NULL;
380
381 if (target == NULL) {
382 errno = EFAULT;
383 return VFS_ERROR;
384 }
385
386 if (LfsLock() != LOS_OK) {
387 errno = EAGAIN;
388 return VFS_ERROR;
389 }
390
391 fileOpInfo = GetMountRes(target, &mountIndex);
392 if (fileOpInfo == NULL) {
393 errno = ENOENT;
394 LfsUnlock();
395 return VFS_ERROR;
396 }
397
398 ret = lfs_unmount(&(fileOpInfo->lfsInfo));
399 if (ret != 0) {
400 errno = LittlefsErrno(ret);
401 ret = VFS_ERROR;
402 }
403
404 (void)FreeMountResByIndex(mountIndex);
405 LfsUnlock();
406 return ret;
407 }
408
LfsUnlink(const char * fileName)409 int LfsUnlink(const char *fileName)
410 {
411 int ret;
412 struct FileOpInfo *fileOpInfo = NULL;
413
414 if (fileName == NULL) {
415 errno = EFAULT;
416 return VFS_ERROR;
417 }
418
419 if (LfsLock() != LOS_OK) {
420 errno = EAGAIN;
421 return VFS_ERROR;
422 }
423
424 if (CheckPathIsMounted(fileName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
425 errno = ENOENT;
426 LfsUnlock();
427 return VFS_ERROR;
428 }
429
430 ret = lfs_remove(&(fileOpInfo->lfsInfo), fileName);
431 if (ret != 0) {
432 errno = LittlefsErrno(ret);
433 ret = VFS_ERROR;
434 }
435
436 LfsUnlock();
437 return ret;
438 }
439
LfsMkdir(const char * dirName,mode_t mode)440 int LfsMkdir(const char *dirName, mode_t mode)
441 {
442 int ret;
443 struct FileOpInfo *fileOpInfo = NULL;
444
445 if (dirName == NULL) {
446 errno = EFAULT;
447 return VFS_ERROR;
448 }
449
450 if (LfsLock() != LOS_OK) {
451 errno = EAGAIN;
452 return VFS_ERROR;
453 }
454
455 if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
456 errno = ENOENT;
457 LfsUnlock();
458 return VFS_ERROR;
459 }
460
461 ret = lfs_mkdir(&(fileOpInfo->lfsInfo), dirName);
462 if (ret != 0) {
463 errno = LittlefsErrno(ret);
464 ret = VFS_ERROR;
465 }
466
467 LfsUnlock();
468 return ret;
469 }
470
LfsRmdir(const char * dirName)471 int LfsRmdir(const char *dirName)
472 {
473 int ret;
474
475 struct FileOpInfo *fileOpInfo = NULL;
476
477 if (dirName == NULL) {
478 errno = EFAULT;
479 return VFS_ERROR;
480 }
481
482 if (LfsLock() != LOS_OK) {
483 errno = EAGAIN;
484 return VFS_ERROR;
485 }
486
487 if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
488 errno = ENOENT;
489 LfsUnlock();
490 return VFS_ERROR;
491 }
492
493 ret = lfs_remove(&(fileOpInfo->lfsInfo), dirName);
494 if (ret != 0) {
495 errno = LittlefsErrno(ret);
496 ret = VFS_ERROR;
497 }
498
499 LfsUnlock();
500 return ret;
501 }
502
LfsOpendir(const char * dirName)503 DIR *LfsOpendir(const char *dirName)
504 {
505 int ret;
506 struct FileOpInfo *fileOpInfo = NULL;
507
508 if (dirName == NULL) {
509 errno = EFAULT;
510 return NULL;
511 }
512
513 if (LfsLock() != LOS_OK) {
514 errno = EAGAIN;
515 return NULL;
516 }
517
518 if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
519 errno = ENOENT;
520 goto ERROUT;
521 }
522
523 if (CheckDirIsOpen(dirName)) {
524 errno = EBUSY;
525 goto ERROUT;
526 }
527
528 FileDirInfo *dirInfo = GetFreeDir(dirName);
529 if (dirInfo == NULL) {
530 errno = ENFILE;
531 goto ERROUT;
532 }
533
534 ret = lfs_dir_open(&(fileOpInfo->lfsInfo), (lfs_dir_t *)(&(dirInfo->dir)), dirName);
535
536 if (ret != 0) {
537 FreeDirInfo(dirName);
538 errno = LittlefsErrno(ret);
539 goto ERROUT;
540 }
541
542 dirInfo->lfsHandle = &(fileOpInfo->lfsInfo);
543
544 LfsUnlock();
545 return (DIR *)dirInfo;
546
547 ERROUT:
548 LfsUnlock();
549 return NULL;
550 }
551
LfsReaddir(DIR * dir)552 struct dirent *LfsReaddir(DIR *dir)
553 {
554 int ret;
555 struct lfs_info lfsInfo;
556
557 FileDirInfo *dirInfo = (FileDirInfo *)dir;
558
559 if (dirInfo == NULL || dirInfo->lfsHandle == NULL) {
560 errno = EBADF;
561 return NULL;
562 }
563
564 if (LfsLock() != LOS_OK) {
565 errno = EAGAIN;
566 return NULL;
567 }
568
569 ret = lfs_dir_read(dirInfo->lfsHandle, (lfs_dir_t *)(&(dirInfo->dir)), &lfsInfo);
570 if (ret == TRUE) {
571 (void)strncpy_s(g_nameValue.d_name, sizeof(g_nameValue.d_name), lfsInfo.name, strlen(lfsInfo.name) + 1);
572 if (lfsInfo.type == LFS_TYPE_DIR) {
573 g_nameValue.d_type = DT_DIR;
574 } else if (lfsInfo.type == LFS_TYPE_REG) {
575 g_nameValue.d_type = DT_REG;
576 }
577
578 g_nameValue.d_reclen = lfsInfo.size;
579
580 LfsUnlock();
581 return &g_nameValue;
582 }
583
584 if (ret != 0) {
585 errno = LittlefsErrno(ret);
586 }
587
588 LfsUnlock();
589 return NULL;
590 }
591
LfsClosedir(DIR * dir)592 int LfsClosedir(DIR *dir)
593 {
594 int ret;
595 FileDirInfo *dirInfo = (FileDirInfo *)dir;
596
597 if (dirInfo == NULL || dirInfo->lfsHandle == NULL) {
598 errno = EBADF;
599 return VFS_ERROR;
600 }
601
602 if (LfsLock() != LOS_OK) {
603 errno = EAGAIN;
604 return VFS_ERROR;
605 }
606
607 ret = lfs_dir_close(dirInfo->lfsHandle, (lfs_dir_t *)(&(dirInfo->dir)));
608
609 FreeDirInfo(dirInfo->dirName);
610
611 if (ret != 0) {
612 errno = LittlefsErrno(ret);
613 ret = VFS_ERROR;
614 }
615
616 LfsUnlock();
617 return ret;
618 }
619
LfsOpen(const char * pathName,int openFlag,...)620 int LfsOpen(const char *pathName, int openFlag, ...)
621 {
622 int fd = INVALID_FD;
623 int err = INVALID_FD;
624
625 struct FileOpInfo *fileOpInfo = NULL;
626
627 if (pathName == NULL) {
628 errno = EFAULT;
629 return INVALID_FD;
630 }
631
632 if (LfsLock() != LOS_OK) {
633 errno = EAGAIN;
634 return VFS_ERROR;
635 }
636
637 if (CheckPathIsMounted(pathName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
638 errno = ENOENT;
639 goto ERROUT;
640 }
641 // if file is already open, return invalid fd
642 if (CheckFileIsOpen(pathName)) {
643 errno = EBUSY;
644 goto ERROUT;
645 }
646
647 LittleFsHandleStruct *fsHandle = LfsAllocFd(pathName, &fd);
648 if (fd == INVALID_FD) {
649 errno = ENFILE;
650 goto ERROUT;
651 }
652
653 int lfsOpenFlag = ConvertFlagToLfsOpenFlag(openFlag);
654 err = lfs_file_open(&(fileOpInfo->lfsInfo), &(fsHandle->file), pathName, lfsOpenFlag);
655 if (err != 0) {
656 LfsFreeFd(fd);
657 errno = LittlefsErrno(err);
658 goto ERROUT;
659 }
660
661 g_handle[fd].lfsHandle = &(fileOpInfo->lfsInfo);
662 LfsUnlock();
663 return fd;
664
665 ERROUT:
666 LfsUnlock();
667 return INVALID_FD;
668 }
669
LfsRead(int fd,void * buf,unsigned int len)670 int LfsRead(int fd, void *buf, unsigned int len)
671 {
672 int ret;
673
674 if (buf == NULL) {
675 errno = EFAULT;
676 return VFS_ERROR;
677 }
678
679 if (LfsLock() != LOS_OK) {
680 errno = EAGAIN;
681 return VFS_ERROR;
682 }
683
684 if (LfsFdIsValid(fd) == FALSE) {
685 errno = EBADF;
686 LfsUnlock();
687 return VFS_ERROR;
688 }
689
690 ret = lfs_file_read(g_handle[fd].lfsHandle, &(g_handle[fd].file), buf, len);
691 if (ret < 0) {
692 errno = LittlefsErrno(ret);
693 ret = VFS_ERROR;
694 }
695 LfsUnlock();
696 return ret;
697 }
698
LfsWrite(int fd,const void * buf,unsigned int len)699 int LfsWrite(int fd, const void *buf, unsigned int len)
700 {
701 int ret;
702
703 if (buf == NULL) {
704 errno = EFAULT;
705 return VFS_ERROR;
706 }
707
708 if (LfsLock() != LOS_OK) {
709 errno = EAGAIN;
710 return VFS_ERROR;
711 }
712
713 if (LfsFdIsValid(fd) == FALSE) {
714 errno = EBADF;
715 LfsUnlock();
716 return VFS_ERROR;
717 }
718
719 ret = lfs_file_write(g_handle[fd].lfsHandle, &(g_handle[fd].file), buf, len);
720 if (ret < 0) {
721 errno = LittlefsErrno(ret);
722 ret = VFS_ERROR;
723 }
724 LfsUnlock();
725 return ret;
726 }
727
LfsSeek(int fd,off_t offset,int whence)728 off_t LfsSeek(int fd, off_t offset, int whence)
729 {
730 off_t ret;
731
732 if (LfsLock() != LOS_OK) {
733 errno = EAGAIN;
734 return VFS_ERROR;
735 }
736
737 if (LfsFdIsValid(fd) == FALSE) {
738 errno = EBADF;
739 LfsUnlock();
740 return VFS_ERROR;
741 }
742
743 ret = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), offset, whence);
744 if (ret < 0) {
745 errno = LittlefsErrno(ret);
746 ret = VFS_ERROR;
747 }
748
749 LfsUnlock();
750 return ret;
751 }
752
LfsClose(int fd)753 int LfsClose(int fd)
754 {
755 int ret;
756
757 if (LfsLock() != LOS_OK) {
758 errno = EAGAIN;
759 return VFS_ERROR;
760 }
761
762 if (LfsFdIsValid(fd) == FALSE) {
763 errno = EBADF;
764 LfsUnlock();
765 return VFS_ERROR;
766 }
767
768 ret = lfs_file_close(g_handle[fd].lfsHandle, &(g_handle[fd].file));
769
770 LfsFreeFd(fd);
771
772 if (ret != 0) {
773 errno = LittlefsErrno(ret);
774 ret = VFS_ERROR;
775 }
776
777 LfsUnlock();
778 return ret;
779 }
780
LfsRename(const char * oldName,const char * newName)781 int LfsRename(const char *oldName, const char *newName)
782 {
783 int ret;
784 struct FileOpInfo *fileOpInfo = NULL;
785
786 if (oldName == NULL || newName == NULL) {
787 errno = EFAULT;
788 return VFS_ERROR;
789 }
790
791 if (LfsLock() != LOS_OK) {
792 errno = EAGAIN;
793 return VFS_ERROR;
794 }
795
796 if (CheckPathIsMounted(oldName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
797 errno = ENOENT;
798 LfsUnlock();
799 return VFS_ERROR;
800 }
801
802 ret = lfs_rename(&(fileOpInfo->lfsInfo), oldName, newName);
803 if (ret != 0) {
804 errno = LittlefsErrno(ret);
805 ret = VFS_ERROR;
806 }
807
808 LfsUnlock();
809 return ret;
810 }
811
LfsStat(const char * path,struct stat * buf)812 int LfsStat(const char *path, struct stat *buf)
813 {
814 int ret;
815 struct lfs_info info;
816 struct FileOpInfo *fileOpInfo = NULL;
817
818 if (path == NULL || buf == NULL) {
819 errno = EFAULT;
820 return VFS_ERROR;
821 }
822
823 if (LfsLock() != LOS_OK) {
824 errno = EAGAIN;
825 return VFS_ERROR;
826 }
827
828 if (CheckPathIsMounted(path, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
829 errno = ENOENT;
830 LfsUnlock();
831 return VFS_ERROR;
832 }
833
834 ret = lfs_stat(&(fileOpInfo->lfsInfo), path, &info);
835 if (ret == 0) {
836 buf->st_size = info.size;
837 if (info.type == LFS_TYPE_REG) {
838 buf->st_mode = S_IFREG;
839 } else {
840 buf->st_mode = S_IFDIR;
841 }
842 } else {
843 errno = LittlefsErrno(ret);
844 ret = VFS_ERROR;
845 }
846
847 LfsUnlock();
848 return ret;
849 }
850
LfsFsync(int fd)851 int LfsFsync(int fd)
852 {
853 int ret;
854
855 if (LfsLock() != LOS_OK) {
856 errno = EAGAIN;
857 return VFS_ERROR;
858 }
859
860 if (LfsFdIsValid(fd) == FALSE) {
861 errno = EBADF;
862 LfsUnlock();
863 return VFS_ERROR;
864 }
865
866 ret = lfs_file_sync(g_handle[fd].lfsHandle, &(g_handle[fd].file));
867 if (ret != 0) {
868 errno = LittlefsErrno(ret);
869 ret = VFS_ERROR;
870 }
871 LfsUnlock();
872 return ret;
873 }
874
LfsFstat(int fd,struct stat * buf)875 int LfsFstat(int fd, struct stat *buf)
876 {
877 int ret;
878 struct lfs_info info;
879
880 if (buf == NULL) {
881 errno = EFAULT;
882 return FS_FAILURE;
883 }
884
885 if (LfsLock() != LOS_OK) {
886 errno = EAGAIN;
887 return VFS_ERROR;
888 }
889
890 if (LfsFdIsValid(fd) == FALSE) {
891 errno = EBADF;
892 LfsUnlock();
893 return VFS_ERROR;
894 }
895
896 ret = lfs_stat(g_handle[fd].lfsHandle, g_handle[fd].pathName, &info);
897 if (ret == 0) {
898 buf->st_size = info.size;
899 if (info.type == LFS_TYPE_REG) {
900 buf->st_mode = S_IFREG;
901 } else {
902 buf->st_mode = S_IFDIR;
903 }
904 } else {
905 errno = LittlefsErrno(ret);
906 ret = VFS_ERROR;
907 }
908 LfsUnlock();
909 return ret;
910 }
911
LfsPread(int fd,void * buf,size_t nbyte,off_t offset)912 int LfsPread(int fd, void *buf, size_t nbyte, off_t offset)
913 {
914 int ret;
915 off_t savepos, pos;
916
917 if (buf == NULL) {
918 errno = EFAULT;
919 return VFS_ERROR;
920 }
921
922 if (LfsLock() != LOS_OK) {
923 errno = EAGAIN;
924 return VFS_ERROR;
925 }
926
927 if (LfsFdIsValid(fd) == FALSE) {
928 errno = EBADF;
929 LfsUnlock();
930 return VFS_ERROR;
931 }
932
933 savepos = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), 0, SEEK_CUR);
934 if (savepos == (off_t)-1) {
935 errno = LittlefsErrno(savepos);
936 LfsUnlock();
937 return VFS_ERROR;
938 }
939
940 pos = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), offset, SEEK_SET);
941 if (pos == (off_t)-1) {
942 errno = LittlefsErrno(pos);
943 LfsUnlock();
944 return VFS_ERROR;
945 }
946
947 ret = lfs_file_read(g_handle[fd].lfsHandle, &(g_handle[fd].file), buf, nbyte);
948 if (ret < 0) {
949 errno = LittlefsErrno(ret);
950 ret = VFS_ERROR;
951 }
952
953 pos = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), savepos, SEEK_SET);
954 if ((pos == (off_t)-1) && (ret >= 0)) {
955 errno = LittlefsErrno(pos);
956 ret = VFS_ERROR;
957 }
958
959 LfsUnlock();
960 return ret;
961 }
962
LfsPwrite(int fd,const void * buf,size_t nbyte,off_t offset)963 int LfsPwrite(int fd, const void *buf, size_t nbyte, off_t offset)
964 {
965 int ret;
966 off_t savepos, pos;
967
968 if (buf == NULL) {
969 errno = EFAULT;
970 return VFS_ERROR;
971 }
972
973 if (LfsLock() != LOS_OK) {
974 errno = EAGAIN;
975 return VFS_ERROR;
976 }
977
978 if (LfsFdIsValid(fd) == FALSE) {
979 errno = EBADF;
980 LfsUnlock();
981 return VFS_ERROR;
982 }
983
984 savepos = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), 0, SEEK_CUR);
985 if (savepos == (off_t)-1) {
986 errno = LittlefsErrno(savepos);
987 LfsUnlock();
988 return VFS_ERROR;
989 }
990
991 pos = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), offset, SEEK_SET);
992 if (pos == (off_t)-1) {
993 errno = LittlefsErrno(pos);
994 LfsUnlock();
995 return VFS_ERROR;
996 }
997
998 ret = lfs_file_write(g_handle[fd].lfsHandle, &(g_handle[fd].file), buf, nbyte);
999 if (ret < 0) {
1000 errno = LittlefsErrno(ret);
1001 ret = VFS_ERROR;
1002 }
1003
1004 pos = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), savepos, SEEK_SET);
1005 if ((pos == (off_t)-1) && (ret >= 0)) {
1006 errno = LittlefsErrno(pos);
1007 ret = VFS_ERROR;
1008 }
1009
1010 LfsUnlock();
1011 return ret;
1012 }
1013