• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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