• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2022 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_adapter.h"
34 #include "los_config.h"
35 #include "los_fs.h"
36 #include "vfs_files.h"
37 #include "vfs_operations.h"
38 #include "vfs_partition.h"
39 #include "vfs_maps.h"
40 #include "vfs_mount.h"
41 #include "securec.h"
42 #include "los_fs.h"
43 
44 static struct PartitionCfg g_partitionCfg;
45 static struct DeviceDesc *g_lfsDevice = NULL;
46 
LfsGetStartAddr(int partition)47 static uint32_t LfsGetStartAddr(int partition)
48 {
49     if (g_lfsDevice == NULL) {
50         struct DeviceDesc *device = NULL;
51         for (device = getDeviceList(); device != NULL; device = device->dNext) {
52             if (strcmp(device->dFsType, "littlefs") == 0) {
53                 g_lfsDevice = device;
54                 break;
55             }
56         }
57     }
58 
59     if ((g_lfsDevice == NULL) || (partition >= g_lfsDevice->dPartNum)) {
60         return INVALID_DEVICE_ADDR;
61     }
62 
63     return (uint32_t)g_lfsDevice->dAddrArray[partition];
64 }
65 
littlefs_block_read(const struct lfs_config * c,lfs_block_t block,lfs_off_t off,void * dst,lfs_size_t size)66 WEAK int littlefs_block_read(const struct lfs_config *c, lfs_block_t block,
67                              lfs_off_t off, void *dst, lfs_size_t size)
68 {
69     UINT32 addr = c->block_size * block + off;
70     UINT32 startaddr = LfsGetStartAddr((int)c->context);
71     if (startaddr == INVALID_DEVICE_ADDR) {
72         return -1;
73     }
74     addr += startaddr;
75 
76     return (g_partitionCfg.readFunc)((int)c->context, &addr, dst, size);
77 }
78 
littlefs_block_write(const struct lfs_config * c,lfs_block_t block,lfs_off_t off,const void * dst,lfs_size_t size)79 WEAK int littlefs_block_write(const struct lfs_config *c, lfs_block_t block,
80                               lfs_off_t off, const void *dst, lfs_size_t size)
81 {
82     UINT32 addr = c->block_size * block + off;
83     UINT32 startaddr = LfsGetStartAddr((int)c->context);
84     if (startaddr == INVALID_DEVICE_ADDR) {
85         return -1;
86     }
87 
88     addr += startaddr;
89 
90     return (g_partitionCfg.writeFunc)((int)c->context, &addr, dst, size);
91 }
92 
littlefs_block_erase(const struct lfs_config * c,lfs_block_t block)93 WEAK int littlefs_block_erase(const struct lfs_config *c, lfs_block_t block)
94 {
95     UINT32 addr = c->block_size * block;
96     UINT32 startaddr = LfsGetStartAddr((int)c->context);
97     if (startaddr == INVALID_DEVICE_ADDR) {
98         return -1;
99     }
100 
101     addr += startaddr;
102 
103     return (g_partitionCfg.eraseFunc)((int)c->context, addr, c->block_size);
104 }
105 
littlefs_block_sync(const struct lfs_config * c)106 WEAK int littlefs_block_sync(const struct lfs_config *c)
107 {
108     (void)c;
109     return 0;
110 }
111 
ConvertFlagToLfsOpenFlag(int oflags)112 static int ConvertFlagToLfsOpenFlag (int oflags)
113 {
114     int lfsOpenFlag = 0;
115 
116     if (oflags & O_CREAT) {
117         lfsOpenFlag |= LFS_O_CREAT;
118     }
119 
120     if (oflags & O_EXCL) {
121         lfsOpenFlag |= LFS_O_EXCL;
122     }
123 
124     if (oflags & O_TRUNC) {
125         lfsOpenFlag |= LFS_O_TRUNC;
126     }
127 
128     if (oflags & O_APPEND) {
129         lfsOpenFlag |= LFS_O_APPEND;
130     }
131 
132     if (oflags & O_RDWR) {
133         lfsOpenFlag |= LFS_O_RDWR;
134     }
135 
136     if (oflags & O_WRONLY) {
137         lfsOpenFlag |= LFS_O_WRONLY;
138     }
139 
140     if (oflags == O_RDONLY) {
141         lfsOpenFlag |= LFS_O_RDONLY;
142     }
143 
144     return lfsOpenFlag;
145 }
146 
LittlefsErrno(int result)147 static int LittlefsErrno(int result)
148 {
149     return (result < 0) ? -result : result;
150 }
151 
LfsConfigAdapter(struct PartitionCfg * pCfg,struct lfs_config * lfsCfg)152 void LfsConfigAdapter(struct PartitionCfg *pCfg, struct lfs_config *lfsCfg)
153 {
154     lfsCfg->context = (void *)pCfg->partNo;
155 
156     lfsCfg->read_size = pCfg->readSize;
157     lfsCfg->prog_size = pCfg->writeSize;
158     lfsCfg->cache_size = pCfg->cacheSize;
159     lfsCfg->block_cycles = pCfg->blockCycles;
160     lfsCfg->lookahead_size = pCfg->lookaheadSize;
161     lfsCfg->block_size = pCfg->blockSize;
162     lfsCfg->block_count = pCfg->blockCount;
163 
164     lfsCfg->read = littlefs_block_read;
165     lfsCfg->prog = littlefs_block_write;
166     lfsCfg->erase = littlefs_block_erase;
167     lfsCfg->sync = littlefs_block_sync;
168 
169     g_partitionCfg.readFunc = pCfg->readFunc;
170     g_partitionCfg.writeFunc = pCfg->writeFunc;
171     g_partitionCfg.eraseFunc = pCfg->eraseFunc;
172 }
173 
LfsMount(struct MountPoint * mp,unsigned long mountflags,const void * data)174 int LfsMount(struct MountPoint *mp, unsigned long mountflags, const void *data)
175 {
176     int ret;
177     lfs_t *mountHdl = NULL;
178     struct lfs_config *cfg = NULL;
179 
180     if ((mp == NULL) || (mp->mPath == NULL) || (data == NULL)) {
181         errno = EFAULT;
182         ret = (int)LOS_NOK;
183         goto errout;
184     }
185 
186     if (mountflags & MS_REMOUNT) {
187         errno = ENOSYS;
188         ret = (int)LOS_NOK;
189         goto errout;
190     }
191 
192     mountHdl = (lfs_t *)LOSCFG_FS_MALLOC_HOOK(sizeof(lfs_t) + sizeof(struct lfs_config));
193     if (mountHdl == NULL) {
194         errno = ENODEV;
195         ret = (int)LOS_NOK;
196         goto errout;
197     }
198     (void)memset_s(mountHdl, sizeof(lfs_t) + sizeof(struct lfs_config), 0, sizeof(lfs_t) + sizeof(struct lfs_config));
199     mp->mData = (void *)mountHdl;
200     cfg = (void *)((UINTPTR)mountHdl + sizeof(lfs_t));
201 
202     LfsConfigAdapter((struct PartitionCfg *)data, cfg);
203 
204     ret = lfs_mount((lfs_t *)mp->mData, cfg);
205     if (ret != 0) {
206         ret = lfs_format((lfs_t *)mp->mData, cfg);
207         if (ret == 0) {
208             ret = lfs_mount((lfs_t *)mp->mData, cfg);
209         }
210     }
211     if (ret != 0) {
212         LOSCFG_FS_FREE_HOOK(mountHdl);
213         errno = LittlefsErrno(ret);
214         ret = (int)LOS_NOK;
215     }
216 
217 errout:
218     return ret;
219 }
220 
LfsUmount(struct MountPoint * mp)221 int LfsUmount(struct MountPoint *mp)
222 {
223     int ret;
224 
225     if (mp == NULL) {
226         errno = EFAULT;
227         return (int)LOS_NOK;
228     }
229 
230     if (mp->mData == NULL) {
231         errno = ENOENT;
232         return (int)LOS_NOK;
233     }
234 
235     ret = lfs_unmount((lfs_t *)mp->mData);
236     if (ret != 0) {
237         errno = LittlefsErrno(ret);
238         ret = (int)LOS_NOK;
239     }
240 
241     LOSCFG_FS_FREE_HOOK(mp->mData);
242     mp->mData = NULL;
243     return ret;
244 }
245 
LfsUnlink(struct MountPoint * mp,const char * fileName)246 int LfsUnlink(struct MountPoint *mp, const char *fileName)
247 {
248     int ret;
249 
250     if ((mp == NULL) || (fileName == NULL)) {
251         errno = EFAULT;
252         return (int)LOS_NOK;
253     }
254 
255     if (mp->mData == NULL) {
256         errno = ENOENT;
257         return (int)LOS_NOK;
258     }
259 
260     ret = lfs_remove((lfs_t *)mp->mData, fileName);
261     if (ret != 0) {
262         errno = LittlefsErrno(ret);
263         ret = (int)LOS_NOK;
264     }
265 
266     return ret;
267 }
268 
LfsMkdir(struct MountPoint * mp,const char * dirName)269 int LfsMkdir(struct MountPoint *mp, const char *dirName)
270 {
271     int ret;
272 
273     if ((dirName == NULL) || (mp == NULL)) {
274         errno = EFAULT;
275         return (int)LOS_NOK;
276     }
277 
278     if (mp->mData == NULL) {
279         errno = ENOENT;
280         return (int)LOS_NOK;
281     }
282 
283     lfs_t *lfs = (lfs_t *)mp->mData;
284 
285     ret = lfs_mkdir(lfs, dirName);
286     if (ret != 0) {
287         errno = LittlefsErrno(ret);
288         ret = (int)LOS_NOK;
289     }
290 
291     return ret;
292 }
293 
LfsRmdir(struct MountPoint * mp,const char * dirName)294 int LfsRmdir(struct MountPoint *mp, const char *dirName)
295 {
296     int ret;
297     lfs_t *lfs = NULL;
298 
299     if (mp == NULL) {
300         errno = EFAULT;
301         return (int)LOS_NOK;
302     }
303 
304     if (mp->mData == NULL) {
305         errno = ENOENT;
306         return (int)LOS_NOK;
307     }
308 
309     lfs = (lfs_t *)mp->mData;
310 
311     if (dirName == NULL) {
312         errno = EFAULT;
313         return (int)LOS_NOK;
314     }
315 
316     ret = lfs_remove(lfs, dirName);
317     if (ret != 0) {
318         errno = LittlefsErrno(ret);
319         ret = (int)LOS_NOK;
320     }
321 
322     return ret;
323 }
324 
LfsOpendir(struct Dir * dir,const char * dirName)325 int LfsOpendir(struct Dir *dir, const char *dirName)
326 {
327     int ret;
328 
329     if ((dir == NULL) || (dir->dMp == NULL) || (dir->dMp->mData == NULL)) {
330         errno = EFAULT;
331         return (int)LOS_NOK;
332     }
333 
334     lfs_t *lfs = (lfs_t *)dir->dMp->mData;
335     lfs_dir_t *dirInfo = (lfs_dir_t *)LOSCFG_FS_MALLOC_HOOK(sizeof(lfs_dir_t));
336     if (dirInfo == NULL) {
337         errno = ENOMEM;
338         return (int)LOS_NOK;
339     }
340 
341     (void)memset_s(dirInfo, sizeof(lfs_dir_t), 0, sizeof(lfs_dir_t));
342     ret = lfs_dir_open(lfs, dirInfo, dirName);
343     if (ret != 0) {
344         LOSCFG_FS_FREE_HOOK(dirInfo);
345         errno = LittlefsErrno(ret);
346         goto errout;
347     }
348 
349     dir->dData = dirInfo;
350     dir->dOffset = 0;
351 
352     return LOS_OK;
353 
354 errout:
355     return (int)LOS_NOK;
356 }
357 
LfsReaddir(struct Dir * dir,struct dirent * dent)358 int LfsReaddir(struct Dir *dir, struct dirent *dent)
359 {
360     int ret;
361     struct lfs_info lfsInfo;
362 
363     if ((dir == NULL) || (dir->dMp == NULL) || (dir->dMp->mData == NULL) ||
364         (dent == NULL)) {
365         errno = EFAULT;
366         return (int)LOS_NOK;
367     }
368 
369     if (dir->dData == NULL) {
370         errno = EBADF;
371         return (int)LOS_NOK;
372     }
373 
374     lfs_t *lfs = (lfs_t *)dir->dMp->mData;
375     lfs_dir_t *dirInfo = (lfs_dir_t *)dir->dData;
376 
377     ret = lfs_dir_read(lfs, dirInfo, &lfsInfo);
378     if (ret == TRUE) {
379         (void)strncpy_s(dent->d_name, sizeof(dent->d_name), lfsInfo.name, strlen(lfsInfo.name) + 1);
380         if (lfsInfo.type == LFS_TYPE_DIR) {
381             dent->d_type = DT_DIR;
382         } else if (lfsInfo.type == LFS_TYPE_REG) {
383             dent->d_type = DT_REG;
384         }
385 
386         dent->d_reclen = lfsInfo.size;
387 
388         return LOS_OK;
389     }
390 
391     if (ret != 0) {
392         errno = LittlefsErrno(ret);
393     }
394 
395     return (int)LOS_NOK;
396 }
397 
LfsClosedir(struct Dir * dir)398 int LfsClosedir(struct Dir *dir)
399 {
400     int ret;
401 
402     if ((dir == NULL) || (dir->dMp == NULL) || (dir->dMp->mData == NULL)) {
403         errno = EFAULT;
404         return (int)LOS_NOK;
405     }
406 
407     if (dir->dData == NULL) {
408         errno = EBADF;
409         return (int)LOS_NOK;
410     }
411 
412     lfs_t *lfs = (lfs_t *)dir->dMp->mData;
413     lfs_dir_t *dirInfo = (lfs_dir_t *)dir->dData;
414 
415     ret = lfs_dir_close(lfs, dirInfo);
416     if (ret != 0) {
417         errno = LittlefsErrno(ret);
418         ret = (int)LOS_NOK;
419     }
420 
421     LOSCFG_FS_FREE_HOOK(dirInfo);
422     dir->dData = NULL;
423 
424     return ret;
425 }
426 
LfsOpen(struct File * file,const char * pathName,int openFlag)427 int LfsOpen(struct File *file, const char *pathName, int openFlag)
428 {
429     int ret;
430     lfs_file_t *lfsHandle = NULL;
431 
432     if ((pathName == NULL) || (file == NULL) || (file->fMp == NULL) ||
433         (file->fMp->mData == NULL)) {
434         errno = EFAULT;
435         return (int)LOS_NOK;
436     }
437 
438     lfsHandle = (lfs_file_t *)LOSCFG_FS_MALLOC_HOOK(sizeof(lfs_file_t));
439     if (lfsHandle == NULL) {
440         errno = ENOMEM;
441         return (int)LOS_NOK;
442     }
443 
444     int lfsOpenFlag = ConvertFlagToLfsOpenFlag(openFlag);
445     ret = lfs_file_open((lfs_t *)file->fMp->mData, lfsHandle, pathName, lfsOpenFlag);
446     if (ret != 0) {
447         LOSCFG_FS_FREE_HOOK(lfsHandle);
448         errno = LittlefsErrno(ret);
449         goto errout;
450     }
451 
452     file->fData = (void *)lfsHandle;
453     return ret;
454 
455 errout:
456     return INVALID_FD;
457 }
458 
LfsRead(struct File * file,char * buf,size_t len)459 int LfsRead(struct File *file, char *buf, size_t len)
460 {
461     int ret;
462     struct MountPoint *mp = NULL;
463     lfs_file_t *lfsHandle = NULL;
464 
465     if (buf == NULL) {
466         errno = EFAULT;
467         return (int)LOS_NOK;
468     }
469 
470     if ((file == NULL) || (file->fData == NULL)) {
471         errno = EBADF;
472         return (int)LOS_NOK;
473     }
474 
475     lfsHandle = (lfs_file_t *)file->fData;
476     mp = file->fMp;
477     if ((mp == NULL) || (mp->mData == NULL)) {
478         errno = EFAULT;
479         return (int)LOS_NOK;
480     }
481 
482     ret = lfs_file_read((lfs_t *)mp->mData, lfsHandle, buf, len);
483     if (ret < 0) {
484         errno = LittlefsErrno(ret);
485         ret = (int)LOS_NOK;
486     }
487     return ret;
488 }
489 
LfsWrite(struct File * file,const char * buf,size_t len)490 int LfsWrite(struct File *file, const char *buf, size_t len)
491 {
492     int ret;
493     struct MountPoint *mp = NULL;
494     lfs_file_t *lfsHandle = NULL;
495 
496     if (buf == NULL) {
497         errno = EFAULT;
498         return (int)LOS_NOK;
499     }
500 
501     if ((file == NULL) || (file->fData == NULL)) {
502         errno = EBADF;
503         return (int)LOS_NOK;
504     }
505 
506     lfsHandle = (lfs_file_t *)file->fData;
507     mp = file->fMp;
508     if ((mp == NULL) || (mp->mData == NULL)) {
509         errno = EFAULT;
510         return (int)LOS_NOK;
511     }
512 
513     ret = lfs_file_write((lfs_t *)mp->mData, lfsHandle, buf, len);
514     if (ret < 0) {
515         errno = LittlefsErrno(ret);
516         ret = (int)LOS_NOK;
517     }
518     return ret;
519 }
520 
LfsSeek(struct File * file,off_t offset,int whence)521 off_t LfsSeek(struct File *file, off_t offset, int whence)
522 {
523     off_t ret;
524     struct MountPoint *mp = NULL;
525     lfs_file_t *lfsHandle = NULL;
526 
527     if ((file == NULL) || (file->fData == NULL)) {
528         errno = EBADF;
529         return (off_t)LOS_NOK;
530     }
531 
532     lfsHandle = (lfs_file_t *)file->fData;
533     mp = file->fMp;
534     if ((mp == NULL) || (mp->mData == NULL)) {
535         errno = EFAULT;
536         return (off_t)LOS_NOK;
537     }
538 
539     ret = (off_t)lfs_file_seek((lfs_t *)mp->mData, lfsHandle, offset, whence);
540     if (ret < 0) {
541         errno = LittlefsErrno(ret);
542         ret = (off_t)LOS_NOK;
543     }
544 
545     return ret;
546 }
547 
LfsClose(struct File * file)548 int LfsClose(struct File *file)
549 {
550     int ret;
551     struct MountPoint *mp = NULL;
552     lfs_file_t *lfsHandle = NULL;
553 
554     if ((file == NULL) || (file->fData == NULL)) {
555         errno = EBADF;
556         return (int)LOS_NOK;
557     }
558 
559     lfsHandle = (lfs_file_t *)file->fData;
560     mp = file->fMp;
561     if ((mp == NULL) || (mp->mData == NULL)) {
562         errno = EFAULT;
563         return (int)LOS_NOK;
564     }
565 
566     ret = lfs_file_close((lfs_t *)mp->mData, lfsHandle);
567     if (ret != 0) {
568         errno = LittlefsErrno(ret);
569         ret = (int)LOS_NOK;
570     }
571 
572     LOSCFG_FS_FREE_HOOK(file->fData);
573     file->fData = NULL;
574     return ret;
575 }
576 
LfsRename(struct MountPoint * mp,const char * oldName,const char * newName)577 int LfsRename(struct MountPoint *mp, const char *oldName, const char *newName)
578 {
579     int ret;
580 
581     if ((mp == NULL) || (oldName == NULL) || (newName == NULL)) {
582         errno = EFAULT;
583         return (int)LOS_NOK;
584     }
585 
586     if (mp->mData == NULL) {
587         errno = ENOENT;
588         return (int)LOS_NOK;
589     }
590 
591     ret = lfs_rename((lfs_t *)mp->mData, oldName, newName);
592     if (ret != 0) {
593         errno = LittlefsErrno(ret);
594         ret = (int)LOS_NOK;
595     }
596 
597     return ret;
598 }
599 
LfsStat(struct MountPoint * mp,const char * path,struct stat * buf)600 int LfsStat(struct MountPoint *mp, const char *path, struct stat *buf)
601 {
602     int ret;
603     struct lfs_info info;
604 
605     if ((mp == NULL) || (path == NULL) || (buf == NULL)) {
606         errno = EFAULT;
607         return (int)LOS_NOK;
608     }
609 
610     if (mp->mData == NULL) {
611         errno = ENOENT;
612         return (int)LOS_NOK;
613     }
614 
615     ret = lfs_stat((lfs_t *)mp->mData, path, &info);
616     if (ret == 0) {
617         buf->st_size = info.size;
618         if (info.type == LFS_TYPE_REG) {
619             buf->st_mode = S_IFREG;
620         } else {
621             buf->st_mode = S_IFDIR;
622         }
623     } else {
624         errno = LittlefsErrno(ret);
625         ret = (int)LOS_NOK;
626     }
627 
628     return ret;
629 }
630 
LfsSync(struct File * file)631 int LfsSync(struct File *file)
632 {
633     int ret;
634     struct MountPoint *mp = NULL;
635 
636     if ((file == NULL) || (file->fData == NULL)) {
637         errno = EBADF;
638         return (int)LOS_NOK;
639     }
640 
641     if ((file->fMp == NULL) || (file->fMp->mData == NULL)) {
642         errno = EFAULT;
643         return (int)LOS_NOK;
644     }
645 
646     mp = file->fMp;
647     ret = lfs_file_sync((lfs_t *)mp->mData, (lfs_file_t *)file->fData);
648     if (ret != 0) {
649         errno = LittlefsErrno(ret);
650         ret = (int)LOS_NOK;
651     }
652     return ret;
653 }
654 
LfsFormat(const char * partName,void * privData)655 int LfsFormat(const char *partName, void *privData)
656 {
657     int ret;
658     lfs_t lfs = {0};
659     struct lfs_config cfg = {0};
660 
661     (void)partName;
662 
663     LfsConfigAdapter((struct PartitionCfg *)privData, &cfg);
664 
665     ret = lfs_format(&lfs, &cfg);
666     if (ret != 0) {
667         errno = LittlefsErrno(ret);
668         ret = (int)LOS_NOK;
669     }
670     return ret;
671 }
672 
673 static struct MountOps g_lfsMnt = {
674     .mount = LfsMount,
675     .umount = LfsUmount,
676     .umount2 = NULL,
677     .statfs = NULL,
678 };
679 
680 static struct FileOps g_lfsFops = {
681     .open = LfsOpen,
682     .close = LfsClose,
683     .read = LfsRead,
684     .write = LfsWrite,
685     .lseek = LfsSeek,
686     .stat = LfsStat,
687     .truncate = NULL,
688     .unlink = LfsUnlink,
689     .rename = LfsRename,
690     .ioctl = NULL, /* not support */
691     .sync = LfsSync,
692     .rmdir = LfsRmdir,
693     .opendir = LfsOpendir,
694     .readdir = LfsReaddir,
695     .closedir = LfsClosedir,
696     .mkdir = LfsMkdir,
697 };
698 
699 static struct FsManagement g_lfsMgt = {
700     .fdisk = NULL,
701     .format = LfsFormat,
702 };
703 
LfsInit(void)704 void LfsInit(void)
705 {
706     (void)OsFsRegister("littlefs", &g_lfsMnt, &g_lfsFops, &g_lfsMgt);
707 }
708