707 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			707 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
 | 
						|
 * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
 | 
						|
 *
 | 
						|
 * Redistribution and use in source and binary forms, with or without modification,
 | 
						|
 * are permitted provided that the following conditions are met:
 | 
						|
 *
 | 
						|
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 | 
						|
 *    conditions and the following disclaimer.
 | 
						|
 *
 | 
						|
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
 | 
						|
 *    of conditions and the following disclaimer in the documentation and/or other materials
 | 
						|
 *    provided with the distribution.
 | 
						|
 *
 | 
						|
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
 | 
						|
 *    to endorse or promote products derived from this software without specific prior written
 | 
						|
 *    permission.
 | 
						|
 *
 | 
						|
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						|
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | 
						|
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | 
						|
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 | 
						|
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
						|
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
						|
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 | 
						|
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 | 
						|
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 | 
						|
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 | 
						|
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						|
 */
 | 
						|
 | 
						|
#define _GNU_SOURCE 1
 | 
						|
#include "lfs_adapter.h"
 | 
						|
#include "los_config.h"
 | 
						|
#include "vfs_files.h"
 | 
						|
#include "vfs_operations.h"
 | 
						|
#include "vfs_partition.h"
 | 
						|
#include "vfs_maps.h"
 | 
						|
#include "vfs_mount.h"
 | 
						|
#include "securec.h"
 | 
						|
#include "los_fs.h"
 | 
						|
 | 
						|
static struct PartitionCfg g_partitionCfg;
 | 
						|
static struct DeviceDesc *g_lfsDevice = NULL;
 | 
						|
 | 
						|
static uint32_t LfsGetStartAddr(int partition)
 | 
						|
{
 | 
						|
    if (g_lfsDevice == NULL) {
 | 
						|
        struct DeviceDesc *device = NULL;
 | 
						|
        for (device = getDeviceList(); device != NULL; device = device->dNext) {
 | 
						|
            if (strcmp(device->dFsType, "littlefs") == 0) {
 | 
						|
                g_lfsDevice = device;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if ((g_lfsDevice == NULL) || (partition >= g_lfsDevice->dPartNum)) {
 | 
						|
        return INVALID_DEVICE_ADDR;
 | 
						|
    }
 | 
						|
 | 
						|
    return (uint32_t)g_lfsDevice->dAddrArray[partition];
 | 
						|
}
 | 
						|
 | 
						|
WEAK int littlefs_block_read(const struct lfs_config *c, lfs_block_t block,
 | 
						|
                             lfs_off_t off, void *dst, lfs_size_t size)
 | 
						|
{
 | 
						|
    UINT32 addr = c->block_size * block + off;
 | 
						|
    UINT32 startaddr = LfsGetStartAddr((int)c->context);
 | 
						|
    if (startaddr == INVALID_DEVICE_ADDR) {
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    addr += startaddr;
 | 
						|
 | 
						|
    return (g_partitionCfg.readFunc)((int)c->context, &addr, dst, size);
 | 
						|
}
 | 
						|
 | 
						|
WEAK int littlefs_block_write(const struct lfs_config *c, lfs_block_t block,
 | 
						|
                              lfs_off_t off, const void *dst, lfs_size_t size)
 | 
						|
{
 | 
						|
    UINT32 addr = c->block_size * block + off;
 | 
						|
    UINT32 startaddr = LfsGetStartAddr((int)c->context);
 | 
						|
    if (startaddr == INVALID_DEVICE_ADDR) {
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    addr += startaddr;
 | 
						|
 | 
						|
    return (g_partitionCfg.writeFunc)((int)c->context, &addr, dst, size);
 | 
						|
}
 | 
						|
 | 
						|
WEAK int littlefs_block_erase(const struct lfs_config *c, lfs_block_t block)
 | 
						|
{
 | 
						|
    UINT32 addr = c->block_size * block;
 | 
						|
    UINT32 startaddr = LfsGetStartAddr((int)c->context);
 | 
						|
    if (startaddr == INVALID_DEVICE_ADDR) {
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    addr += startaddr;
 | 
						|
 | 
						|
    return (g_partitionCfg.eraseFunc)((int)c->context, addr, c->block_size);
 | 
						|
}
 | 
						|
 | 
						|
WEAK int littlefs_block_sync(const struct lfs_config *c)
 | 
						|
{
 | 
						|
    (void)c;
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int ConvertFlagToLfsOpenFlag (int oflags)
 | 
						|
{
 | 
						|
    int lfsOpenFlag = 0;
 | 
						|
 | 
						|
    if (oflags & O_CREAT) {
 | 
						|
        lfsOpenFlag |= LFS_O_CREAT;
 | 
						|
    }
 | 
						|
 | 
						|
    if (oflags & O_EXCL) {
 | 
						|
        lfsOpenFlag |= LFS_O_EXCL;
 | 
						|
    }
 | 
						|
 | 
						|
    if (oflags & O_TRUNC) {
 | 
						|
        lfsOpenFlag |= LFS_O_TRUNC;
 | 
						|
    }
 | 
						|
 | 
						|
    if (oflags & O_APPEND) {
 | 
						|
        lfsOpenFlag |= LFS_O_APPEND;
 | 
						|
    }
 | 
						|
 | 
						|
    if (oflags & O_RDWR) {
 | 
						|
        lfsOpenFlag |= LFS_O_RDWR;
 | 
						|
    }
 | 
						|
 | 
						|
    if (oflags & O_WRONLY) {
 | 
						|
        lfsOpenFlag |= LFS_O_WRONLY;
 | 
						|
    }
 | 
						|
 | 
						|
    if (oflags == O_RDONLY) {
 | 
						|
        lfsOpenFlag |= LFS_O_RDONLY;
 | 
						|
    }
 | 
						|
 | 
						|
    return lfsOpenFlag;
 | 
						|
}
 | 
						|
 | 
						|
static int LittlefsErrno(int result)
 | 
						|
{
 | 
						|
    return (result < 0) ? -result : result;
 | 
						|
}
 | 
						|
 | 
						|
void LfsConfigAdapter(struct PartitionCfg *pCfg, struct lfs_config *lfsCfg)
 | 
						|
{
 | 
						|
    lfsCfg->context = (void *)pCfg->partNo;
 | 
						|
 | 
						|
    lfsCfg->read_size = pCfg->readSize;
 | 
						|
    lfsCfg->prog_size = pCfg->writeSize;
 | 
						|
    lfsCfg->cache_size = pCfg->cacheSize;
 | 
						|
    lfsCfg->block_cycles = pCfg->blockCycles;
 | 
						|
    lfsCfg->lookahead_size = pCfg->lookaheadSize;
 | 
						|
    lfsCfg->block_size = pCfg->blockSize;
 | 
						|
    lfsCfg->block_count = pCfg->blockCount;
 | 
						|
 | 
						|
    lfsCfg->read = littlefs_block_read;
 | 
						|
    lfsCfg->prog = littlefs_block_write;
 | 
						|
    lfsCfg->erase = littlefs_block_erase;
 | 
						|
    lfsCfg->sync = littlefs_block_sync;
 | 
						|
 | 
						|
    g_partitionCfg.readFunc = pCfg->readFunc;
 | 
						|
    g_partitionCfg.writeFunc = pCfg->writeFunc;
 | 
						|
    g_partitionCfg.eraseFunc = pCfg->eraseFunc;
 | 
						|
}
 | 
						|
 | 
						|
int LfsMount(struct MountPoint *mp, unsigned long mountflags, const void *data)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
    lfs_t *mountHdl = NULL;
 | 
						|
    struct lfs_config *cfg = NULL;
 | 
						|
 | 
						|
    if ((mp == NULL) || (mp->mPath == NULL) || (data == NULL)) {
 | 
						|
        errno = EFAULT;
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
        goto errout;
 | 
						|
    }
 | 
						|
 | 
						|
    if (mountflags & MS_REMOUNT) {
 | 
						|
        errno = ENOSYS;
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
        goto errout;
 | 
						|
    }
 | 
						|
 | 
						|
    mountHdl = (lfs_t *)LOSCFG_FS_MALLOC_HOOK(sizeof(lfs_t) + sizeof(struct lfs_config));
 | 
						|
    if (mountHdl == NULL) {
 | 
						|
        errno = ENODEV;
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
        goto errout;
 | 
						|
    }
 | 
						|
    (void)memset_s(mountHdl, sizeof(lfs_t) + sizeof(struct lfs_config), 0, sizeof(lfs_t) + sizeof(struct lfs_config));
 | 
						|
    mp->mData = (void *)mountHdl;
 | 
						|
    cfg = (void *)((UINTPTR)mountHdl + sizeof(lfs_t));
 | 
						|
 | 
						|
    LfsConfigAdapter((struct PartitionCfg *)data, cfg);
 | 
						|
 | 
						|
    ret = lfs_mount((lfs_t *)mp->mData, cfg);
 | 
						|
    if (ret != 0) {
 | 
						|
        ret = lfs_format((lfs_t *)mp->mData, cfg);
 | 
						|
        if (ret == 0) {
 | 
						|
            ret = lfs_mount((lfs_t *)mp->mData, cfg);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (ret != 0) {
 | 
						|
        LOSCFG_FS_FREE_HOOK(mountHdl);
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
errout:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
int LfsUmount(struct MountPoint *mp)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
 | 
						|
    if (mp == NULL) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    if (mp->mData == NULL) {
 | 
						|
        errno = ENOENT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    ret = lfs_unmount((lfs_t *)mp->mData);
 | 
						|
    if (ret != 0) {
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    LOSCFG_FS_FREE_HOOK(mp->mData);
 | 
						|
    mp->mData = NULL;
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
int LfsUnlink(struct MountPoint *mp, const char *fileName)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
 | 
						|
    if ((mp == NULL) || (fileName == NULL)) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    if (mp->mData == NULL) {
 | 
						|
        errno = ENOENT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    ret = lfs_remove((lfs_t *)mp->mData, fileName);
 | 
						|
    if (ret != 0) {
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
int LfsMkdir(struct MountPoint *mp, const char *dirName)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
 | 
						|
    if ((dirName == NULL) || (mp == NULL)) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    if (mp->mData == NULL) {
 | 
						|
        errno = ENOENT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    lfs_t *lfs = (lfs_t *)mp->mData;
 | 
						|
 | 
						|
    ret = lfs_mkdir(lfs, dirName);
 | 
						|
    if (ret != 0) {
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
int LfsRmdir(struct MountPoint *mp, const char *dirName)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
    lfs_t *lfs = NULL;
 | 
						|
 | 
						|
    if (mp == NULL) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    if (mp->mData == NULL) {
 | 
						|
        errno = ENOENT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    lfs = (lfs_t *)mp->mData;
 | 
						|
 | 
						|
    if (dirName == NULL) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    ret = lfs_remove(lfs, dirName);
 | 
						|
    if (ret != 0) {
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
int LfsOpendir(struct Dir *dir, const char *dirName)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
 | 
						|
    if ((dir == NULL) || (dir->dMp == NULL) || (dir->dMp->mData == NULL)) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    lfs_t *lfs = (lfs_t *)dir->dMp->mData;
 | 
						|
    lfs_dir_t *dirInfo = (lfs_dir_t *)LOSCFG_FS_MALLOC_HOOK(sizeof(lfs_dir_t));
 | 
						|
    if (dirInfo == NULL) {
 | 
						|
        errno = ENOMEM;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    (void)memset_s(dirInfo, sizeof(lfs_dir_t), 0, sizeof(lfs_dir_t));
 | 
						|
    ret = lfs_dir_open(lfs, dirInfo, dirName);
 | 
						|
    if (ret != 0) {
 | 
						|
        LOSCFG_FS_FREE_HOOK(dirInfo);
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        goto errout;
 | 
						|
    }
 | 
						|
 | 
						|
    dir->dData = dirInfo;
 | 
						|
    dir->dOffset = 0;
 | 
						|
 | 
						|
    return LOS_OK;
 | 
						|
 | 
						|
errout:
 | 
						|
    return (int)LOS_NOK;
 | 
						|
}
 | 
						|
 | 
						|
int LfsReaddir(struct Dir *dir, struct dirent *dent)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
    struct lfs_info lfsInfo;
 | 
						|
 | 
						|
    if ((dir == NULL) || (dir->dMp == NULL) || (dir->dMp->mData == NULL) ||
 | 
						|
        (dent == NULL)) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dir->dData == NULL) {
 | 
						|
        errno = EBADF;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    lfs_t *lfs = (lfs_t *)dir->dMp->mData;
 | 
						|
    lfs_dir_t *dirInfo = (lfs_dir_t *)dir->dData;
 | 
						|
 | 
						|
    ret = lfs_dir_read(lfs, dirInfo, &lfsInfo);
 | 
						|
    if (ret == TRUE) {
 | 
						|
        (void)strncpy_s(dent->d_name, sizeof(dent->d_name), lfsInfo.name, strlen(lfsInfo.name) + 1);
 | 
						|
        if (lfsInfo.type == LFS_TYPE_DIR) {
 | 
						|
            dent->d_type = DT_DIR;
 | 
						|
        } else if (lfsInfo.type == LFS_TYPE_REG) {
 | 
						|
            dent->d_type = DT_REG;
 | 
						|
        }
 | 
						|
 | 
						|
        dent->d_reclen = lfsInfo.size;
 | 
						|
 | 
						|
        return LOS_OK;
 | 
						|
    }
 | 
						|
 | 
						|
    if (ret != 0) {
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
    }
 | 
						|
 | 
						|
    return (int)LOS_NOK;
 | 
						|
}
 | 
						|
 | 
						|
int LfsClosedir(struct Dir *dir)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
 | 
						|
    if ((dir == NULL) || (dir->dMp == NULL) || (dir->dMp->mData == NULL)) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dir->dData == NULL) {
 | 
						|
        errno = EBADF;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    lfs_t *lfs = (lfs_t *)dir->dMp->mData;
 | 
						|
    lfs_dir_t *dirInfo = (lfs_dir_t *)dir->dData;
 | 
						|
 | 
						|
    ret = lfs_dir_close(lfs, dirInfo);
 | 
						|
    if (ret != 0) {
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    LOSCFG_FS_FREE_HOOK(dirInfo);
 | 
						|
    dir->dData = NULL;
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
int LfsOpen(struct File *file, const char *pathName, int openFlag)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
    lfs_file_t *lfsHandle = NULL;
 | 
						|
 | 
						|
    if ((pathName == NULL) || (file == NULL) || (file->fMp == NULL) ||
 | 
						|
        (file->fMp->mData == NULL)) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    lfsHandle = (lfs_file_t *)LOSCFG_FS_MALLOC_HOOK(sizeof(lfs_file_t));
 | 
						|
    if (lfsHandle == NULL) {
 | 
						|
        errno = ENOMEM;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    int lfsOpenFlag = ConvertFlagToLfsOpenFlag(openFlag);
 | 
						|
    ret = lfs_file_open((lfs_t *)file->fMp->mData, lfsHandle, pathName, lfsOpenFlag);
 | 
						|
    if (ret != 0) {
 | 
						|
        LOSCFG_FS_FREE_HOOK(lfsHandle);
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        goto errout;
 | 
						|
    }
 | 
						|
 | 
						|
    file->fData = (void *)lfsHandle;
 | 
						|
    return ret;
 | 
						|
 | 
						|
errout:
 | 
						|
    return INVALID_FD;
 | 
						|
}
 | 
						|
 | 
						|
int LfsRead(struct File *file, char *buf, size_t len)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
    struct MountPoint *mp = NULL;
 | 
						|
    lfs_file_t *lfsHandle = NULL;
 | 
						|
 | 
						|
    if (buf == NULL) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((file == NULL) || (file->fData == NULL)) {
 | 
						|
        errno = EBADF;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    lfsHandle = (lfs_file_t *)file->fData;
 | 
						|
    mp = file->fMp;
 | 
						|
    if ((mp == NULL) || (mp->mData == NULL)) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    ret = lfs_file_read((lfs_t *)mp->mData, lfsHandle, buf, len);
 | 
						|
    if (ret < 0) {
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
int LfsWrite(struct File *file, const char *buf, size_t len)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
    struct MountPoint *mp = NULL;
 | 
						|
    lfs_file_t *lfsHandle = NULL;
 | 
						|
 | 
						|
    if (buf == NULL) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((file == NULL) || (file->fData == NULL)) {
 | 
						|
        errno = EBADF;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    lfsHandle = (lfs_file_t *)file->fData;
 | 
						|
    mp = file->fMp;
 | 
						|
    if ((mp == NULL) || (mp->mData == NULL)) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    ret = lfs_file_write((lfs_t *)mp->mData, lfsHandle, buf, len);
 | 
						|
    if (ret < 0) {
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
off_t LfsSeek(struct File *file, off_t offset, int whence)
 | 
						|
{
 | 
						|
    off_t ret;
 | 
						|
    struct MountPoint *mp = NULL;
 | 
						|
    lfs_file_t *lfsHandle = NULL;
 | 
						|
 | 
						|
    if ((file == NULL) || (file->fData == NULL)) {
 | 
						|
        errno = EBADF;
 | 
						|
        return (off_t)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    lfsHandle = (lfs_file_t *)file->fData;
 | 
						|
    mp = file->fMp;
 | 
						|
    if ((mp == NULL) || (mp->mData == NULL)) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (off_t)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    ret = (off_t)lfs_file_seek((lfs_t *)mp->mData, lfsHandle, offset, whence);
 | 
						|
    if (ret < 0) {
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        ret = (off_t)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
int LfsClose(struct File *file)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
    struct MountPoint *mp = NULL;
 | 
						|
    lfs_file_t *lfsHandle = NULL;
 | 
						|
 | 
						|
    if ((file == NULL) || (file->fData == NULL)) {
 | 
						|
        errno = EBADF;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    lfsHandle = (lfs_file_t *)file->fData;
 | 
						|
    mp = file->fMp;
 | 
						|
    if ((mp == NULL) || (mp->mData == NULL)) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    ret = lfs_file_close((lfs_t *)mp->mData, lfsHandle);
 | 
						|
    if (ret != 0) {
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    LOSCFG_FS_FREE_HOOK(file->fData);
 | 
						|
    file->fData = NULL;
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
int LfsRename(struct MountPoint *mp, const char *oldName, const char *newName)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
 | 
						|
    if ((mp == NULL) || (oldName == NULL) || (newName == NULL)) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    if (mp->mData == NULL) {
 | 
						|
        errno = ENOENT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    ret = lfs_rename((lfs_t *)mp->mData, oldName, newName);
 | 
						|
    if (ret != 0) {
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
int LfsStat(struct MountPoint *mp, const char *path, struct stat *buf)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
    struct lfs_info info;
 | 
						|
 | 
						|
    if ((mp == NULL) || (path == NULL) || (buf == NULL)) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    if (mp->mData == NULL) {
 | 
						|
        errno = ENOENT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    ret = lfs_stat((lfs_t *)mp->mData, path, &info);
 | 
						|
    if (ret == 0) {
 | 
						|
        buf->st_size = info.size;
 | 
						|
        if (info.type == LFS_TYPE_REG) {
 | 
						|
            buf->st_mode = S_IFREG;
 | 
						|
        } else {
 | 
						|
            buf->st_mode = S_IFDIR;
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
int LfsSync(struct File *file)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
    struct MountPoint *mp = NULL;
 | 
						|
 | 
						|
    if ((file == NULL) || (file->fData == NULL)) {
 | 
						|
        errno = EBADF;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((file->fMp == NULL) || (file->fMp->mData == NULL)) {
 | 
						|
        errno = EFAULT;
 | 
						|
        return (int)LOS_NOK;
 | 
						|
    }
 | 
						|
 | 
						|
    mp = file->fMp;
 | 
						|
    ret = lfs_file_sync((lfs_t *)mp->mData, (lfs_file_t *)file->fData);
 | 
						|
    if (ret != 0) {
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
int LfsFormat(const char *partName, void *privData)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
    lfs_t lfs = {0};
 | 
						|
    struct lfs_config cfg = {0};
 | 
						|
 | 
						|
    (void)partName;
 | 
						|
 | 
						|
    LfsConfigAdapter((struct PartitionCfg *)privData, &cfg);
 | 
						|
 | 
						|
    ret = lfs_format(&lfs, &cfg);
 | 
						|
    if (ret != 0) {
 | 
						|
        errno = LittlefsErrno(ret);
 | 
						|
        ret = (int)LOS_NOK;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static struct MountOps g_lfsMnt = {
 | 
						|
    .mount = LfsMount,
 | 
						|
    .umount = LfsUmount,
 | 
						|
    .umount2 = NULL,
 | 
						|
    .statfs = NULL,
 | 
						|
};
 | 
						|
 | 
						|
static struct FileOps g_lfsFops = {
 | 
						|
    .open = LfsOpen,
 | 
						|
    .close = LfsClose,
 | 
						|
    .read = LfsRead,
 | 
						|
    .write = LfsWrite,
 | 
						|
    .lseek = LfsSeek,
 | 
						|
    .stat = LfsStat,
 | 
						|
    .truncate = NULL,
 | 
						|
    .unlink = LfsUnlink,
 | 
						|
    .rename = LfsRename,
 | 
						|
    .ioctl = NULL, /* not support */
 | 
						|
    .sync = LfsSync,
 | 
						|
    .rmdir = LfsRmdir,
 | 
						|
    .opendir = LfsOpendir,
 | 
						|
    .readdir = LfsReaddir,
 | 
						|
    .closedir = LfsClosedir,
 | 
						|
    .mkdir = LfsMkdir,
 | 
						|
};
 | 
						|
 | 
						|
static struct FsManagement g_lfsMgt = {
 | 
						|
    .fdisk = NULL,
 | 
						|
    .format = LfsFormat,
 | 
						|
};
 | 
						|
 | 
						|
void LfsInit(void)
 | 
						|
{
 | 
						|
    (void)OsFsRegister("littlefs", &g_lfsMnt, &g_lfsFops, &g_lfsMgt);
 | 
						|
}
 |