13d8536b4Sopenharmony_ci/* 23d8536b4Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 33d8536b4Sopenharmony_ci * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. 43d8536b4Sopenharmony_ci * 53d8536b4Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 63d8536b4Sopenharmony_ci * are permitted provided that the following conditions are met: 73d8536b4Sopenharmony_ci * 83d8536b4Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of 93d8536b4Sopenharmony_ci * conditions and the following disclaimer. 103d8536b4Sopenharmony_ci * 113d8536b4Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list 123d8536b4Sopenharmony_ci * of conditions and the following disclaimer in the documentation and/or other materials 133d8536b4Sopenharmony_ci * provided with the distribution. 143d8536b4Sopenharmony_ci * 153d8536b4Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used 163d8536b4Sopenharmony_ci * to endorse or promote products derived from this software without specific prior written 173d8536b4Sopenharmony_ci * permission. 183d8536b4Sopenharmony_ci * 193d8536b4Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 203d8536b4Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 213d8536b4Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 223d8536b4Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 233d8536b4Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 243d8536b4Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 253d8536b4Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 263d8536b4Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 273d8536b4Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 283d8536b4Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 293d8536b4Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 303d8536b4Sopenharmony_ci */ 313d8536b4Sopenharmony_ci 323d8536b4Sopenharmony_ci#define _GNU_SOURCE 1 333d8536b4Sopenharmony_ci#include "ff.h" 343d8536b4Sopenharmony_ci#include "fatfs.h" 353d8536b4Sopenharmony_ci#include "errno.h" 363d8536b4Sopenharmony_ci#include "stdbool.h" 373d8536b4Sopenharmony_ci#include "limits.h" 383d8536b4Sopenharmony_ci#include "pthread.h" 393d8536b4Sopenharmony_ci#include "time.h" 403d8536b4Sopenharmony_ci#include "securec.h" 413d8536b4Sopenharmony_ci#include "los_compiler.h" 423d8536b4Sopenharmony_ci#include "los_debug.h" 433d8536b4Sopenharmony_ci#include "los_sched.h" 443d8536b4Sopenharmony_ci#include "vfs_files.h" 453d8536b4Sopenharmony_ci#include "vfs_operations.h" 463d8536b4Sopenharmony_ci#include "vfs_partition.h" 473d8536b4Sopenharmony_ci#include "vfs_maps.h" 483d8536b4Sopenharmony_ci#include "vfs_mount.h" 493d8536b4Sopenharmony_ci#include "los_fs.h" 503d8536b4Sopenharmony_ci 513d8536b4Sopenharmony_ci/* the max name length of different parts should not bigger than 32 */ 523d8536b4Sopenharmony_ci#define FS_DRIVE_NAME_MAX_LEN 32 533d8536b4Sopenharmony_ci 543d8536b4Sopenharmony_ci#ifndef FAT_MAX_OPEN_DIRS 553d8536b4Sopenharmony_ci#define FAT_MAX_OPEN_DIRS 8 563d8536b4Sopenharmony_ci#endif /* FAT_MAX_OPEN_DIRS */ 573d8536b4Sopenharmony_ci 583d8536b4Sopenharmony_ci#ifndef FS_LOCK_TIMEOUT_SEC 593d8536b4Sopenharmony_ci#define FS_LOCK_TIMEOUT_SEC 15 603d8536b4Sopenharmony_ci#endif /* FS_LOCK_TIMEOUT_SEC */ 613d8536b4Sopenharmony_ci 623d8536b4Sopenharmony_cistatic UINT8 g_workBuffer[FF_MAX_SS]; 633d8536b4Sopenharmony_cistatic char *g_volPath[FF_VOLUMES] = {FF_VOLUME_STRS}; 643d8536b4Sopenharmony_ci 653d8536b4Sopenharmony_ciPARTITION VolToPart[] = { 663d8536b4Sopenharmony_ci { 0, 0, 1, 0, 0 }, 673d8536b4Sopenharmony_ci { 0, 0, 2, 0, 0 }, 683d8536b4Sopenharmony_ci { 0, 0, 3, 0, 0 }, 693d8536b4Sopenharmony_ci { 0, 0, 4, 0, 0 } 703d8536b4Sopenharmony_ci}; 713d8536b4Sopenharmony_ci 723d8536b4Sopenharmony_cistatic int FsChangeDrive(const char *path) 733d8536b4Sopenharmony_ci{ 743d8536b4Sopenharmony_ci INT32 res; 753d8536b4Sopenharmony_ci errno_t retErr; 763d8536b4Sopenharmony_ci UINT16 pathLen = strlen((char const *)path); 773d8536b4Sopenharmony_ci /* the max name length of different parts is 16 */ 783d8536b4Sopenharmony_ci CHAR tmpPath[FS_DRIVE_NAME_MAX_LEN] = { "/" }; 793d8536b4Sopenharmony_ci 803d8536b4Sopenharmony_ci /* make sure the path begin with "/", the path like /xxx/yyy/... */ 813d8536b4Sopenharmony_ci if (pathLen >= (FS_DRIVE_NAME_MAX_LEN - 1)) { 823d8536b4Sopenharmony_ci /* 2: except first flag "/" and last end flag */ 833d8536b4Sopenharmony_ci pathLen = FS_DRIVE_NAME_MAX_LEN - 2; 843d8536b4Sopenharmony_ci } 853d8536b4Sopenharmony_ci 863d8536b4Sopenharmony_ci retErr = strncpy_s(tmpPath + 1, (FS_DRIVE_NAME_MAX_LEN - 1), (char const *)path, pathLen); 873d8536b4Sopenharmony_ci if (retErr != EOK) { 883d8536b4Sopenharmony_ci return (int)LOS_NOK; 893d8536b4Sopenharmony_ci } 903d8536b4Sopenharmony_ci 913d8536b4Sopenharmony_ci res = f_chdrive(tmpPath); 923d8536b4Sopenharmony_ci if (res != FR_OK) { 933d8536b4Sopenharmony_ci return (int)LOS_NOK; 943d8536b4Sopenharmony_ci } 953d8536b4Sopenharmony_ci 963d8536b4Sopenharmony_ci return (int)LOS_OK; 973d8536b4Sopenharmony_ci} 983d8536b4Sopenharmony_ci 993d8536b4Sopenharmony_cistatic int Remount(struct MountPoint *mp, unsigned long mountflags) 1003d8536b4Sopenharmony_ci{ 1013d8536b4Sopenharmony_ci FATFS *fatfs = (FATFS *)mp->mData; 1023d8536b4Sopenharmony_ci 1033d8536b4Sopenharmony_ci /* remount is not allowed when the device is not mounted. */ 1043d8536b4Sopenharmony_ci if (fatfs->fs_type == 0) { 1053d8536b4Sopenharmony_ci errno = EINVAL; 1063d8536b4Sopenharmony_ci return (int)LOS_NOK; 1073d8536b4Sopenharmony_ci } 1083d8536b4Sopenharmony_ci mp->mWriteEnable = (mountflags & MS_RDONLY) ? FALSE : TRUE; 1093d8536b4Sopenharmony_ci 1103d8536b4Sopenharmony_ci return (int)LOS_OK; 1113d8536b4Sopenharmony_ci} 1123d8536b4Sopenharmony_ci 1133d8536b4Sopenharmony_cistatic unsigned int FatFsGetMode(int oflags) 1143d8536b4Sopenharmony_ci{ 1153d8536b4Sopenharmony_ci UINT32 fmode = FA_READ; 1163d8536b4Sopenharmony_ci 1173d8536b4Sopenharmony_ci if ((UINT32)oflags & O_WRONLY) { 1183d8536b4Sopenharmony_ci fmode |= FA_WRITE; 1193d8536b4Sopenharmony_ci } 1203d8536b4Sopenharmony_ci 1213d8536b4Sopenharmony_ci if (((UINT32)oflags & O_ACCMODE) & O_RDWR) { 1223d8536b4Sopenharmony_ci fmode |= FA_WRITE; 1233d8536b4Sopenharmony_ci } 1243d8536b4Sopenharmony_ci /* Creates a new file if the file is not existing, otherwise, just open it. */ 1253d8536b4Sopenharmony_ci if ((UINT32)oflags & O_CREAT) { 1263d8536b4Sopenharmony_ci fmode |= FA_OPEN_ALWAYS; 1273d8536b4Sopenharmony_ci /* Creates a new file. If the file already exists, the function shall fail. */ 1283d8536b4Sopenharmony_ci if ((UINT32)oflags & O_EXCL) { 1293d8536b4Sopenharmony_ci fmode |= FA_CREATE_NEW; 1303d8536b4Sopenharmony_ci } 1313d8536b4Sopenharmony_ci } 1323d8536b4Sopenharmony_ci /* Creates a new file. If the file already exists, its length shall be truncated to 0. */ 1333d8536b4Sopenharmony_ci if ((UINT32)oflags & O_TRUNC) { 1343d8536b4Sopenharmony_ci fmode |= FA_CREATE_ALWAYS; 1353d8536b4Sopenharmony_ci } 1363d8536b4Sopenharmony_ci 1373d8536b4Sopenharmony_ci return fmode; 1383d8536b4Sopenharmony_ci} 1393d8536b4Sopenharmony_ci 1403d8536b4Sopenharmony_cistatic int FatfsErrno(int result) 1413d8536b4Sopenharmony_ci{ 1423d8536b4Sopenharmony_ci INT32 status = 0; 1433d8536b4Sopenharmony_ci 1443d8536b4Sopenharmony_ci if (result < 0) { 1453d8536b4Sopenharmony_ci return result; 1463d8536b4Sopenharmony_ci } 1473d8536b4Sopenharmony_ci 1483d8536b4Sopenharmony_ci /* FatFs errno to Libc errno */ 1493d8536b4Sopenharmony_ci switch (result) { 1503d8536b4Sopenharmony_ci case FR_OK: 1513d8536b4Sopenharmony_ci break; 1523d8536b4Sopenharmony_ci 1533d8536b4Sopenharmony_ci case FR_NO_FILE: 1543d8536b4Sopenharmony_ci case FR_NO_PATH: 1553d8536b4Sopenharmony_ci case FR_NO_FILESYSTEM: 1563d8536b4Sopenharmony_ci status = ENOENT; 1573d8536b4Sopenharmony_ci break; 1583d8536b4Sopenharmony_ci 1593d8536b4Sopenharmony_ci case FR_INVALID_NAME: 1603d8536b4Sopenharmony_ci status = EINVAL; 1613d8536b4Sopenharmony_ci break; 1623d8536b4Sopenharmony_ci 1633d8536b4Sopenharmony_ci case FR_EXIST: 1643d8536b4Sopenharmony_ci case FR_INVALID_OBJECT: 1653d8536b4Sopenharmony_ci status = EEXIST; 1663d8536b4Sopenharmony_ci break; 1673d8536b4Sopenharmony_ci 1683d8536b4Sopenharmony_ci case FR_DISK_ERR: 1693d8536b4Sopenharmony_ci case FR_NOT_READY: 1703d8536b4Sopenharmony_ci case FR_INT_ERR: 1713d8536b4Sopenharmony_ci status = EIO; 1723d8536b4Sopenharmony_ci break; 1733d8536b4Sopenharmony_ci 1743d8536b4Sopenharmony_ci case FR_WRITE_PROTECTED: 1753d8536b4Sopenharmony_ci status = EROFS; 1763d8536b4Sopenharmony_ci break; 1773d8536b4Sopenharmony_ci case FR_MKFS_ABORTED: 1783d8536b4Sopenharmony_ci case FR_INVALID_PARAMETER: 1793d8536b4Sopenharmony_ci status = EINVAL; 1803d8536b4Sopenharmony_ci break; 1813d8536b4Sopenharmony_ci 1823d8536b4Sopenharmony_ci case FR_NO_SPACE_LEFT: 1833d8536b4Sopenharmony_ci status = ENOSPC; 1843d8536b4Sopenharmony_ci break; 1853d8536b4Sopenharmony_ci case FR_NO_DIRENTRY: 1863d8536b4Sopenharmony_ci status = ENFILE; 1873d8536b4Sopenharmony_ci break; 1883d8536b4Sopenharmony_ci case FR_NO_EMPTY_DIR: 1893d8536b4Sopenharmony_ci status = ENOTEMPTY; 1903d8536b4Sopenharmony_ci break; 1913d8536b4Sopenharmony_ci case FR_IS_DIR: 1923d8536b4Sopenharmony_ci status = EISDIR; 1933d8536b4Sopenharmony_ci break; 1943d8536b4Sopenharmony_ci case FR_NO_DIR: 1953d8536b4Sopenharmony_ci status = ENOTDIR; 1963d8536b4Sopenharmony_ci break; 1973d8536b4Sopenharmony_ci case FR_NO_EPERM: 1983d8536b4Sopenharmony_ci case FR_DENIED: 1993d8536b4Sopenharmony_ci status = EPERM; 2003d8536b4Sopenharmony_ci break; 2013d8536b4Sopenharmony_ci case FR_LOCKED: 2023d8536b4Sopenharmony_ci status = EBUSY; 2033d8536b4Sopenharmony_ci break; 2043d8536b4Sopenharmony_ci default: 2053d8536b4Sopenharmony_ci status = result; 2063d8536b4Sopenharmony_ci break; 2073d8536b4Sopenharmony_ci } 2083d8536b4Sopenharmony_ci 2093d8536b4Sopenharmony_ci return status; 2103d8536b4Sopenharmony_ci} 2113d8536b4Sopenharmony_ci 2123d8536b4Sopenharmony_cichar * GetLdPath(const char *source) 2133d8536b4Sopenharmony_ci{ 2143d8536b4Sopenharmony_ci#define LDPATH_PAD 2 // 2 means: strlen("/") + len of '\0' 2153d8536b4Sopenharmony_ci int ret; 2163d8536b4Sopenharmony_ci int partId = GetPartIdByPartName(source); 2173d8536b4Sopenharmony_ci if ((partId < 0) || (partId >= MAX_PARTITION_NUM)) { 2183d8536b4Sopenharmony_ci return NULL; 2193d8536b4Sopenharmony_ci } 2203d8536b4Sopenharmony_ci 2213d8536b4Sopenharmony_ci char *volPath = g_volPath[partId]; 2223d8536b4Sopenharmony_ci char *ldPath = (char *)LOSCFG_FS_MALLOC_HOOK(strlen(volPath) + LDPATH_PAD); 2233d8536b4Sopenharmony_ci if (ldPath == NULL) { 2243d8536b4Sopenharmony_ci return NULL; 2253d8536b4Sopenharmony_ci } 2263d8536b4Sopenharmony_ci 2273d8536b4Sopenharmony_ci (void)memset_s(ldPath, strlen(volPath) + LDPATH_PAD, 0, strlen(volPath) + LDPATH_PAD); 2283d8536b4Sopenharmony_ci 2293d8536b4Sopenharmony_ci /* Convert volPath to ldpath, for example, convert "inner" to "/inner" */ 2303d8536b4Sopenharmony_ci *ldPath = '/'; 2313d8536b4Sopenharmony_ci ret = strcpy_s(ldPath + 1, strlen(volPath)+1, volPath); 2323d8536b4Sopenharmony_ci if (ret != EOK) { 2333d8536b4Sopenharmony_ci LOSCFG_FS_FREE_HOOK(ldPath); 2343d8536b4Sopenharmony_ci return NULL; 2353d8536b4Sopenharmony_ci } 2363d8536b4Sopenharmony_ci 2373d8536b4Sopenharmony_ci return ldPath; 2383d8536b4Sopenharmony_ci} 2393d8536b4Sopenharmony_ci 2403d8536b4Sopenharmony_civoid PutLdPath(const char *ldPath) 2413d8536b4Sopenharmony_ci{ 2423d8536b4Sopenharmony_ci if (ldPath != NULL) { 2433d8536b4Sopenharmony_ci LOSCFG_FS_FREE_HOOK((void *)ldPath); 2443d8536b4Sopenharmony_ci } 2453d8536b4Sopenharmony_ci} 2463d8536b4Sopenharmony_ci 2473d8536b4Sopenharmony_ciint FatfsMount(struct MountPoint *mp, unsigned long mountflags, 2483d8536b4Sopenharmony_ci const void *data) 2493d8536b4Sopenharmony_ci{ 2503d8536b4Sopenharmony_ci FRESULT res; 2513d8536b4Sopenharmony_ci FATFS *fs = NULL; 2523d8536b4Sopenharmony_ci 2533d8536b4Sopenharmony_ci if (mountflags & MS_REMOUNT) { 2543d8536b4Sopenharmony_ci return Remount(mp, mountflags); 2553d8536b4Sopenharmony_ci } 2563d8536b4Sopenharmony_ci 2573d8536b4Sopenharmony_ci char *ldPath = GetLdPath(mp->mDev); 2583d8536b4Sopenharmony_ci if (ldPath == NULL) { 2593d8536b4Sopenharmony_ci errno = EFAULT; 2603d8536b4Sopenharmony_ci return (int)LOS_NOK; 2613d8536b4Sopenharmony_ci } 2623d8536b4Sopenharmony_ci 2633d8536b4Sopenharmony_ci fs = (FATFS *)LOSCFG_FS_MALLOC_HOOK(sizeof(FATFS)); 2643d8536b4Sopenharmony_ci if (fs == NULL) { 2653d8536b4Sopenharmony_ci errno = ENOMEM; 2663d8536b4Sopenharmony_ci PutLdPath(ldPath); 2673d8536b4Sopenharmony_ci return (int)LOS_NOK; 2683d8536b4Sopenharmony_ci } 2693d8536b4Sopenharmony_ci (void)memset_s(fs, sizeof(FATFS), 0, sizeof(FATFS)); 2703d8536b4Sopenharmony_ci 2713d8536b4Sopenharmony_ci res = f_mount(fs, ldPath, 1); 2723d8536b4Sopenharmony_ci if (res != FR_OK) { 2733d8536b4Sopenharmony_ci LOSCFG_FS_FREE_HOOK(fs); 2743d8536b4Sopenharmony_ci PutLdPath(ldPath); 2753d8536b4Sopenharmony_ci errno = FatfsErrno(res); 2763d8536b4Sopenharmony_ci return (int)LOS_NOK; 2773d8536b4Sopenharmony_ci } 2783d8536b4Sopenharmony_ci mp->mData = (void *)fs; 2793d8536b4Sopenharmony_ci 2803d8536b4Sopenharmony_ci PutLdPath(ldPath); 2813d8536b4Sopenharmony_ci return (int)LOS_OK; 2823d8536b4Sopenharmony_ci} 2833d8536b4Sopenharmony_ci 2843d8536b4Sopenharmony_ciint FatfsUmount(struct MountPoint *mp) 2853d8536b4Sopenharmony_ci{ 2863d8536b4Sopenharmony_ci int volId; 2873d8536b4Sopenharmony_ci FRESULT res; 2883d8536b4Sopenharmony_ci char *ldPath = NULL; 2893d8536b4Sopenharmony_ci FATFS *fatfs = (FATFS *)mp->mData; 2903d8536b4Sopenharmony_ci 2913d8536b4Sopenharmony_ci /* The volume is not mounted */ 2923d8536b4Sopenharmony_ci if (fatfs->fs_type == 0) { 2933d8536b4Sopenharmony_ci errno = EINVAL; 2943d8536b4Sopenharmony_ci return (int)LOS_NOK; 2953d8536b4Sopenharmony_ci } 2963d8536b4Sopenharmony_ci 2973d8536b4Sopenharmony_ci volId = GetPartIdByPartName(mp->mDev); 2983d8536b4Sopenharmony_ci /* umount is not allowed when a file or directory is opened. */ 2993d8536b4Sopenharmony_ci if (f_checkopenlock(volId) != FR_OK) { 3003d8536b4Sopenharmony_ci errno = EBUSY; 3013d8536b4Sopenharmony_ci return (int)LOS_NOK; 3023d8536b4Sopenharmony_ci } 3033d8536b4Sopenharmony_ci 3043d8536b4Sopenharmony_ci ldPath = GetLdPath(mp->mDev); 3053d8536b4Sopenharmony_ci if (ldPath == NULL) { 3063d8536b4Sopenharmony_ci errno = EFAULT; 3073d8536b4Sopenharmony_ci return (int)LOS_NOK; 3083d8536b4Sopenharmony_ci } 3093d8536b4Sopenharmony_ci 3103d8536b4Sopenharmony_ci res = f_mount((FATFS *)NULL, ldPath, 0); 3113d8536b4Sopenharmony_ci if (res != FR_OK) { 3123d8536b4Sopenharmony_ci errno = FatfsErrno(res); 3133d8536b4Sopenharmony_ci PutLdPath(ldPath); 3143d8536b4Sopenharmony_ci return (int)LOS_NOK; 3153d8536b4Sopenharmony_ci } 3163d8536b4Sopenharmony_ci 3173d8536b4Sopenharmony_ci if (fatfs->win != NULL) { 3183d8536b4Sopenharmony_ci ff_memfree(fatfs->win); 3193d8536b4Sopenharmony_ci } 3203d8536b4Sopenharmony_ci 3213d8536b4Sopenharmony_ci LOSCFG_FS_FREE_HOOK(mp->mData); 3223d8536b4Sopenharmony_ci mp->mData = NULL; 3233d8536b4Sopenharmony_ci 3243d8536b4Sopenharmony_ci PutLdPath(ldPath); 3253d8536b4Sopenharmony_ci return (int)LOS_OK; 3263d8536b4Sopenharmony_ci} 3273d8536b4Sopenharmony_ci 3283d8536b4Sopenharmony_ciint FatfsUmount2(struct MountPoint *mp, int flag) 3293d8536b4Sopenharmony_ci{ 3303d8536b4Sopenharmony_ci UINT32 flags; 3313d8536b4Sopenharmony_ci FRESULT res; 3323d8536b4Sopenharmony_ci char *ldPath = NULL; 3333d8536b4Sopenharmony_ci FATFS *fatfs = (FATFS *)mp->mData; 3343d8536b4Sopenharmony_ci 3353d8536b4Sopenharmony_ci flags = MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW; 3363d8536b4Sopenharmony_ci if ((UINT32)flag & ~flags) { 3373d8536b4Sopenharmony_ci errno = EINVAL; 3383d8536b4Sopenharmony_ci return (int)LOS_NOK; 3393d8536b4Sopenharmony_ci } 3403d8536b4Sopenharmony_ci 3413d8536b4Sopenharmony_ci /* The volume is not mounted */ 3423d8536b4Sopenharmony_ci if (fatfs->fs_type == 0) { 3433d8536b4Sopenharmony_ci errno = EINVAL; 3443d8536b4Sopenharmony_ci return (int)LOS_NOK; 3453d8536b4Sopenharmony_ci } 3463d8536b4Sopenharmony_ci 3473d8536b4Sopenharmony_ci ldPath = GetLdPath(mp->mDev); 3483d8536b4Sopenharmony_ci if (ldPath == NULL) { 3493d8536b4Sopenharmony_ci errno = EFAULT; 3503d8536b4Sopenharmony_ci return (int)LOS_NOK; 3513d8536b4Sopenharmony_ci } 3523d8536b4Sopenharmony_ci 3533d8536b4Sopenharmony_ci res = f_mount((FATFS *)NULL, ldPath, 0); 3543d8536b4Sopenharmony_ci if (res != FR_OK) { 3553d8536b4Sopenharmony_ci PutLdPath(ldPath); 3563d8536b4Sopenharmony_ci errno = FatfsErrno(res); 3573d8536b4Sopenharmony_ci return (int)LOS_NOK; 3583d8536b4Sopenharmony_ci } 3593d8536b4Sopenharmony_ci 3603d8536b4Sopenharmony_ci if (fatfs->win != NULL) { 3613d8536b4Sopenharmony_ci ff_memfree(fatfs->win); 3623d8536b4Sopenharmony_ci } 3633d8536b4Sopenharmony_ci 3643d8536b4Sopenharmony_ci LOSCFG_FS_FREE_HOOK(mp->mData); 3653d8536b4Sopenharmony_ci mp->mData = NULL; 3663d8536b4Sopenharmony_ci 3673d8536b4Sopenharmony_ci PutLdPath(ldPath); 3683d8536b4Sopenharmony_ci return (int)LOS_OK; 3693d8536b4Sopenharmony_ci} 3703d8536b4Sopenharmony_ci 3713d8536b4Sopenharmony_ciint FatfsOpen(struct File *file, const char *path, int oflag) 3723d8536b4Sopenharmony_ci{ 3733d8536b4Sopenharmony_ci FRESULT res; 3743d8536b4Sopenharmony_ci UINT32 fmode; 3753d8536b4Sopenharmony_ci FIL *fp = NULL; 3763d8536b4Sopenharmony_ci int ret; 3773d8536b4Sopenharmony_ci 3783d8536b4Sopenharmony_ci if (path == NULL) { 3793d8536b4Sopenharmony_ci errno = EFAULT; 3803d8536b4Sopenharmony_ci return (int)LOS_NOK; 3813d8536b4Sopenharmony_ci } 3823d8536b4Sopenharmony_ci 3833d8536b4Sopenharmony_ci fmode = FatFsGetMode(oflag); 3843d8536b4Sopenharmony_ci 3853d8536b4Sopenharmony_ci fp = (FIL *)LOSCFG_FS_MALLOC_HOOK(sizeof(FIL)); 3863d8536b4Sopenharmony_ci if (fp == NULL) { 3873d8536b4Sopenharmony_ci errno = ENOMEM; 3883d8536b4Sopenharmony_ci return (int)LOS_NOK; 3893d8536b4Sopenharmony_ci } 3903d8536b4Sopenharmony_ci (void)memset_s(fp, sizeof(FIL), 0, sizeof(FIL)); 3913d8536b4Sopenharmony_ci 3923d8536b4Sopenharmony_ci ret = FsChangeDrive(path); 3933d8536b4Sopenharmony_ci if (ret != (int)LOS_OK) { 3943d8536b4Sopenharmony_ci PRINT_ERR("FAT open ChangeDrive err 0x%x!\r\n", ret); 3953d8536b4Sopenharmony_ci errno = ENOENT; 3963d8536b4Sopenharmony_ci LOSCFG_FS_FREE_HOOK(fp); 3973d8536b4Sopenharmony_ci return (int)LOS_NOK; 3983d8536b4Sopenharmony_ci } 3993d8536b4Sopenharmony_ci 4003d8536b4Sopenharmony_ci res = f_open(fp, path, fmode); 4013d8536b4Sopenharmony_ci if (res != FR_OK) { 4023d8536b4Sopenharmony_ci PRINT_ERR("FAT open err 0x%x!\r\n", res); 4033d8536b4Sopenharmony_ci LOSCFG_FS_FREE_HOOK(fp); 4043d8536b4Sopenharmony_ci errno = FatfsErrno(res); 4053d8536b4Sopenharmony_ci return (int)LOS_NOK; 4063d8536b4Sopenharmony_ci } 4073d8536b4Sopenharmony_ci 4083d8536b4Sopenharmony_ci file->fData = (void *)fp; 4093d8536b4Sopenharmony_ci 4103d8536b4Sopenharmony_ci return (int)LOS_OK; 4113d8536b4Sopenharmony_ci} 4123d8536b4Sopenharmony_ci 4133d8536b4Sopenharmony_ciint FatfsClose(struct File *file) 4143d8536b4Sopenharmony_ci{ 4153d8536b4Sopenharmony_ci FRESULT res; 4163d8536b4Sopenharmony_ci FIL *fp = (FIL *)file->fData; 4173d8536b4Sopenharmony_ci 4183d8536b4Sopenharmony_ci if ((fp == NULL) || (fp->obj.fs == NULL)) { 4193d8536b4Sopenharmony_ci errno = ENOENT; 4203d8536b4Sopenharmony_ci return (int)LOS_NOK; 4213d8536b4Sopenharmony_ci } 4223d8536b4Sopenharmony_ci 4233d8536b4Sopenharmony_ci res = f_close(fp); 4243d8536b4Sopenharmony_ci if (res != FR_OK) { 4253d8536b4Sopenharmony_ci PRINT_ERR("FAT close err 0x%x!\r\n", res); 4263d8536b4Sopenharmony_ci errno = FatfsErrno(res); 4273d8536b4Sopenharmony_ci return (int)LOS_NOK; 4283d8536b4Sopenharmony_ci } 4293d8536b4Sopenharmony_ci 4303d8536b4Sopenharmony_ci#if !FF_FS_TINY 4313d8536b4Sopenharmony_ci if (fp->buf != NULL) { 4323d8536b4Sopenharmony_ci (void)ff_memfree(fp->buf); 4333d8536b4Sopenharmony_ci } 4343d8536b4Sopenharmony_ci#endif 4353d8536b4Sopenharmony_ci LOSCFG_FS_FREE_HOOK(file->fData); 4363d8536b4Sopenharmony_ci file->fData = NULL; 4373d8536b4Sopenharmony_ci 4383d8536b4Sopenharmony_ci return (int)LOS_OK; 4393d8536b4Sopenharmony_ci} 4403d8536b4Sopenharmony_ci 4413d8536b4Sopenharmony_cissize_t FatfsRead(struct File *file, char *buf, size_t nbyte) 4423d8536b4Sopenharmony_ci{ 4433d8536b4Sopenharmony_ci FRESULT res; 4443d8536b4Sopenharmony_ci UINT32 lenRead; 4453d8536b4Sopenharmony_ci FIL *fp = (FIL *)file->fData; 4463d8536b4Sopenharmony_ci 4473d8536b4Sopenharmony_ci if (buf == NULL) { 4483d8536b4Sopenharmony_ci errno = EFAULT; 4493d8536b4Sopenharmony_ci return (ssize_t)LOS_NOK; 4503d8536b4Sopenharmony_ci } 4513d8536b4Sopenharmony_ci 4523d8536b4Sopenharmony_ci if (fp == NULL) { 4533d8536b4Sopenharmony_ci errno = ENOENT; 4543d8536b4Sopenharmony_ci return (ssize_t)LOS_NOK; 4553d8536b4Sopenharmony_ci } 4563d8536b4Sopenharmony_ci 4573d8536b4Sopenharmony_ci res = f_read(fp, buf, nbyte, &lenRead); 4583d8536b4Sopenharmony_ci if (res != FR_OK) { 4593d8536b4Sopenharmony_ci errno = FatfsErrno(res); 4603d8536b4Sopenharmony_ci return (ssize_t)LOS_NOK; 4613d8536b4Sopenharmony_ci } 4623d8536b4Sopenharmony_ci 4633d8536b4Sopenharmony_ci return (ssize_t)lenRead; 4643d8536b4Sopenharmony_ci} 4653d8536b4Sopenharmony_ci 4663d8536b4Sopenharmony_cissize_t FatfsWrite(struct File *file, const char *buf, size_t nbyte) 4673d8536b4Sopenharmony_ci{ 4683d8536b4Sopenharmony_ci FRESULT res; 4693d8536b4Sopenharmony_ci UINT32 lenWrite; 4703d8536b4Sopenharmony_ci static BOOL overFlow = FALSE; 4713d8536b4Sopenharmony_ci FIL *fp = (FIL *)file->fData; 4723d8536b4Sopenharmony_ci 4733d8536b4Sopenharmony_ci if (buf == NULL) { 4743d8536b4Sopenharmony_ci errno = EFAULT; 4753d8536b4Sopenharmony_ci return (ssize_t)LOS_NOK; 4763d8536b4Sopenharmony_ci } 4773d8536b4Sopenharmony_ci 4783d8536b4Sopenharmony_ci if ((fp == NULL) || (fp->obj.fs == NULL)) { 4793d8536b4Sopenharmony_ci errno = ENOENT; 4803d8536b4Sopenharmony_ci return (ssize_t)LOS_NOK; 4813d8536b4Sopenharmony_ci } 4823d8536b4Sopenharmony_ci 4833d8536b4Sopenharmony_ci res = f_write(fp, buf, nbyte, &lenWrite); 4843d8536b4Sopenharmony_ci if ((res == FR_OK) && (lenWrite == 0) && (nbyte != 0) && (overFlow == FALSE)) { 4853d8536b4Sopenharmony_ci overFlow = TRUE; 4863d8536b4Sopenharmony_ci PRINT_ERR("FAT write err!\r\n"); 4873d8536b4Sopenharmony_ci } 4883d8536b4Sopenharmony_ci 4893d8536b4Sopenharmony_ci if ((res != FR_OK) || (nbyte != lenWrite)) { 4903d8536b4Sopenharmony_ci errno = FatfsErrno(res); 4913d8536b4Sopenharmony_ci return (ssize_t)LOS_NOK; 4923d8536b4Sopenharmony_ci } 4933d8536b4Sopenharmony_ci 4943d8536b4Sopenharmony_ci return (ssize_t)lenWrite; 4953d8536b4Sopenharmony_ci} 4963d8536b4Sopenharmony_ci 4973d8536b4Sopenharmony_cioff_t FatfsLseek(struct File *file, off_t offset, int whence) 4983d8536b4Sopenharmony_ci{ 4993d8536b4Sopenharmony_ci FRESULT res; 5003d8536b4Sopenharmony_ci off_t pos; 5013d8536b4Sopenharmony_ci FIL *fp = (FIL *)file->fData; 5023d8536b4Sopenharmony_ci 5033d8536b4Sopenharmony_ci if ((fp == NULL) || (fp->obj.fs == NULL)) { 5043d8536b4Sopenharmony_ci errno = ENOENT; 5053d8536b4Sopenharmony_ci return (off_t)LOS_NOK; 5063d8536b4Sopenharmony_ci } 5073d8536b4Sopenharmony_ci 5083d8536b4Sopenharmony_ci if (whence == SEEK_SET) { 5093d8536b4Sopenharmony_ci pos = 0; 5103d8536b4Sopenharmony_ci } else if (whence == SEEK_CUR) { 5113d8536b4Sopenharmony_ci pos = f_tell(fp); 5123d8536b4Sopenharmony_ci } else if (whence == SEEK_END) { 5133d8536b4Sopenharmony_ci pos = f_size(fp); 5143d8536b4Sopenharmony_ci } else { 5153d8536b4Sopenharmony_ci errno = EINVAL; 5163d8536b4Sopenharmony_ci return (off_t)LOS_NOK; 5173d8536b4Sopenharmony_ci } 5183d8536b4Sopenharmony_ci 5193d8536b4Sopenharmony_ci res = f_lseek(fp, offset + pos); 5203d8536b4Sopenharmony_ci if (res != FR_OK) { 5213d8536b4Sopenharmony_ci errno = FatfsErrno(res); 5223d8536b4Sopenharmony_ci return (off_t)LOS_NOK; 5233d8536b4Sopenharmony_ci } 5243d8536b4Sopenharmony_ci 5253d8536b4Sopenharmony_ci pos = f_tell(fp); 5263d8536b4Sopenharmony_ci return pos; 5273d8536b4Sopenharmony_ci} 5283d8536b4Sopenharmony_ci 5293d8536b4Sopenharmony_ci/* Remove the specified FILE */ 5303d8536b4Sopenharmony_ciint FatfsUnlink(struct MountPoint *mp, const char *path) 5313d8536b4Sopenharmony_ci{ 5323d8536b4Sopenharmony_ci FRESULT res; 5333d8536b4Sopenharmony_ci int ret; 5343d8536b4Sopenharmony_ci 5353d8536b4Sopenharmony_ci if (path == NULL) { 5363d8536b4Sopenharmony_ci errno = EFAULT; 5373d8536b4Sopenharmony_ci return (int)LOS_NOK; 5383d8536b4Sopenharmony_ci } 5393d8536b4Sopenharmony_ci 5403d8536b4Sopenharmony_ci if (!mp->mWriteEnable) { 5413d8536b4Sopenharmony_ci errno = EACCES; 5423d8536b4Sopenharmony_ci return (int)LOS_NOK; 5433d8536b4Sopenharmony_ci } 5443d8536b4Sopenharmony_ci 5453d8536b4Sopenharmony_ci ret = FsChangeDrive(path); 5463d8536b4Sopenharmony_ci if (ret != (int)LOS_OK) { 5473d8536b4Sopenharmony_ci PRINT_ERR("FAT unlink ChangeDrive err 0x%x!\r\n", ret); 5483d8536b4Sopenharmony_ci errno = ENOENT; 5493d8536b4Sopenharmony_ci return (int)LOS_NOK; 5503d8536b4Sopenharmony_ci } 5513d8536b4Sopenharmony_ci 5523d8536b4Sopenharmony_ci res = f_unlink(path); 5533d8536b4Sopenharmony_ci if (res != FR_OK) { 5543d8536b4Sopenharmony_ci PRINT_ERR("FAT unlink err 0x%x!\r\n", res); 5553d8536b4Sopenharmony_ci errno = FatfsErrno(res); 5563d8536b4Sopenharmony_ci return (int)LOS_NOK; 5573d8536b4Sopenharmony_ci } 5583d8536b4Sopenharmony_ci 5593d8536b4Sopenharmony_ci return (int)LOS_OK; 5603d8536b4Sopenharmony_ci} 5613d8536b4Sopenharmony_ci 5623d8536b4Sopenharmony_ciint FatfsStat(struct MountPoint *mp, const char *path, struct stat *buf) 5633d8536b4Sopenharmony_ci{ 5643d8536b4Sopenharmony_ci FRESULT res; 5653d8536b4Sopenharmony_ci FILINFO fileInfo = {0}; 5663d8536b4Sopenharmony_ci int ret; 5673d8536b4Sopenharmony_ci 5683d8536b4Sopenharmony_ci if ((path == NULL) || (buf == NULL)) { 5693d8536b4Sopenharmony_ci errno = EFAULT; 5703d8536b4Sopenharmony_ci return (int)LOS_NOK; 5713d8536b4Sopenharmony_ci } 5723d8536b4Sopenharmony_ci 5733d8536b4Sopenharmony_ci ret = FsChangeDrive(path); 5743d8536b4Sopenharmony_ci if (ret != (int)LOS_OK) { 5753d8536b4Sopenharmony_ci PRINT_ERR("FAT stat ChangeDrive err 0x%x!\r\n", ret); 5763d8536b4Sopenharmony_ci errno = ENOENT; 5773d8536b4Sopenharmony_ci return (int)LOS_NOK; 5783d8536b4Sopenharmony_ci } 5793d8536b4Sopenharmony_ci 5803d8536b4Sopenharmony_ci res = f_stat(path, &fileInfo); 5813d8536b4Sopenharmony_ci if (res != FR_OK) { 5823d8536b4Sopenharmony_ci PRINT_ERR("FAT stat err 0x%x!\r\n", res); 5833d8536b4Sopenharmony_ci errno = FatfsErrno(res); 5843d8536b4Sopenharmony_ci return (int)LOS_NOK; 5853d8536b4Sopenharmony_ci } 5863d8536b4Sopenharmony_ci 5873d8536b4Sopenharmony_ci buf->st_size = fileInfo.fsize; 5883d8536b4Sopenharmony_ci buf->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | 5893d8536b4Sopenharmony_ci S_IWUSR | S_IWGRP | S_IWOTH | 5903d8536b4Sopenharmony_ci S_IXUSR | S_IXGRP | S_IXOTH; 5913d8536b4Sopenharmony_ci 5923d8536b4Sopenharmony_ci if (fileInfo.fattrib & AM_RDO) { 5933d8536b4Sopenharmony_ci buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); 5943d8536b4Sopenharmony_ci } 5953d8536b4Sopenharmony_ci 5963d8536b4Sopenharmony_ci if (fileInfo.fattrib & AM_DIR) { 5973d8536b4Sopenharmony_ci buf->st_mode &= ~S_IFREG; 5983d8536b4Sopenharmony_ci buf->st_mode |= S_IFDIR; 5993d8536b4Sopenharmony_ci } 6003d8536b4Sopenharmony_ci 6013d8536b4Sopenharmony_ci return (int)LOS_OK; 6023d8536b4Sopenharmony_ci} 6033d8536b4Sopenharmony_ci 6043d8536b4Sopenharmony_ci/* Synchronize all changes to Flash */ 6053d8536b4Sopenharmony_ciint FatfsSync(struct File *file) 6063d8536b4Sopenharmony_ci{ 6073d8536b4Sopenharmony_ci FRESULT res; 6083d8536b4Sopenharmony_ci FIL *fp = (FIL *)file->fData; 6093d8536b4Sopenharmony_ci 6103d8536b4Sopenharmony_ci if ((fp == NULL) || (fp->obj.fs == NULL)) { 6113d8536b4Sopenharmony_ci errno = ENOENT; 6123d8536b4Sopenharmony_ci return (int)LOS_NOK; 6133d8536b4Sopenharmony_ci } 6143d8536b4Sopenharmony_ci 6153d8536b4Sopenharmony_ci res = f_sync(fp); 6163d8536b4Sopenharmony_ci if (res != FR_OK) { 6173d8536b4Sopenharmony_ci errno = FatfsErrno(res); 6183d8536b4Sopenharmony_ci return (int)LOS_NOK; 6193d8536b4Sopenharmony_ci } 6203d8536b4Sopenharmony_ci 6213d8536b4Sopenharmony_ci return (int)LOS_OK; 6223d8536b4Sopenharmony_ci} 6233d8536b4Sopenharmony_ci 6243d8536b4Sopenharmony_ciint FatfsMkdir(struct MountPoint *mp, const char *path) 6253d8536b4Sopenharmony_ci{ 6263d8536b4Sopenharmony_ci FRESULT res; 6273d8536b4Sopenharmony_ci int ret; 6283d8536b4Sopenharmony_ci 6293d8536b4Sopenharmony_ci if (path == NULL) { 6303d8536b4Sopenharmony_ci errno = EFAULT; 6313d8536b4Sopenharmony_ci return (int)LOS_NOK; 6323d8536b4Sopenharmony_ci } 6333d8536b4Sopenharmony_ci 6343d8536b4Sopenharmony_ci if (!mp->mWriteEnable) { 6353d8536b4Sopenharmony_ci errno = EACCES; 6363d8536b4Sopenharmony_ci return (int)LOS_NOK; 6373d8536b4Sopenharmony_ci } 6383d8536b4Sopenharmony_ci 6393d8536b4Sopenharmony_ci ret = FsChangeDrive(path); 6403d8536b4Sopenharmony_ci if (ret != (int)LOS_OK) { 6413d8536b4Sopenharmony_ci PRINT_ERR("FAT mkdir ChangeDrive err 0x%x!\r\n", ret); 6423d8536b4Sopenharmony_ci errno = ENOENT; 6433d8536b4Sopenharmony_ci return (int)LOS_NOK; 6443d8536b4Sopenharmony_ci } 6453d8536b4Sopenharmony_ci 6463d8536b4Sopenharmony_ci res = f_mkdir(path); 6473d8536b4Sopenharmony_ci if (res != FR_OK) { 6483d8536b4Sopenharmony_ci PRINT_ERR("FAT mkdir err 0x%x!\r\n", res); 6493d8536b4Sopenharmony_ci errno = FatfsErrno(res); 6503d8536b4Sopenharmony_ci return (int)LOS_NOK; 6513d8536b4Sopenharmony_ci } 6523d8536b4Sopenharmony_ci 6533d8536b4Sopenharmony_ci return (int)LOS_OK; 6543d8536b4Sopenharmony_ci} 6553d8536b4Sopenharmony_ci 6563d8536b4Sopenharmony_ciint FatfsOpendir(struct Dir *dir, const char *dirName) 6573d8536b4Sopenharmony_ci{ 6583d8536b4Sopenharmony_ci FRESULT res; 6593d8536b4Sopenharmony_ci DIR *dp = NULL; 6603d8536b4Sopenharmony_ci int ret; 6613d8536b4Sopenharmony_ci 6623d8536b4Sopenharmony_ci if (dirName == NULL) { 6633d8536b4Sopenharmony_ci errno = EFAULT; 6643d8536b4Sopenharmony_ci return (int)LOS_NOK; 6653d8536b4Sopenharmony_ci } 6663d8536b4Sopenharmony_ci 6673d8536b4Sopenharmony_ci ret = FsChangeDrive(dirName); 6683d8536b4Sopenharmony_ci if (ret != (int)LOS_OK) { 6693d8536b4Sopenharmony_ci PRINT_ERR("FAT opendir ChangeDrive err 0x%x!\r\n", ret); 6703d8536b4Sopenharmony_ci errno = ENOENT; 6713d8536b4Sopenharmony_ci return (int)LOS_NOK; 6723d8536b4Sopenharmony_ci } 6733d8536b4Sopenharmony_ci 6743d8536b4Sopenharmony_ci dp = (DIR *)LOSCFG_FS_MALLOC_HOOK(sizeof(DIR)); 6753d8536b4Sopenharmony_ci if (dp == NULL) { 6763d8536b4Sopenharmony_ci errno = ENOENT; 6773d8536b4Sopenharmony_ci return (int)LOS_NOK; 6783d8536b4Sopenharmony_ci } 6793d8536b4Sopenharmony_ci (void)memset_s(dp, sizeof(DIR), 0, sizeof(DIR)); 6803d8536b4Sopenharmony_ci 6813d8536b4Sopenharmony_ci res = f_opendir(dp, dirName); 6823d8536b4Sopenharmony_ci if (res != FR_OK) { 6833d8536b4Sopenharmony_ci PRINT_ERR("FAT opendir err 0x%x!\r\n", res); 6843d8536b4Sopenharmony_ci LOSCFG_FS_FREE_HOOK(dp); 6853d8536b4Sopenharmony_ci errno = FatfsErrno(res); 6863d8536b4Sopenharmony_ci return (int)LOS_NOK; 6873d8536b4Sopenharmony_ci } 6883d8536b4Sopenharmony_ci 6893d8536b4Sopenharmony_ci dir->dData = dp; 6903d8536b4Sopenharmony_ci dir->dOffset = 0; 6913d8536b4Sopenharmony_ci 6923d8536b4Sopenharmony_ci return (int)LOS_OK; 6933d8536b4Sopenharmony_ci} 6943d8536b4Sopenharmony_ci 6953d8536b4Sopenharmony_ciint FatfsReaddir(struct Dir *dir, struct dirent *dent) 6963d8536b4Sopenharmony_ci{ 6973d8536b4Sopenharmony_ci FRESULT res; 6983d8536b4Sopenharmony_ci FILINFO fileInfo = {0}; 6993d8536b4Sopenharmony_ci DIR *dp = NULL; 7003d8536b4Sopenharmony_ci 7013d8536b4Sopenharmony_ci if ((dir == NULL) || (dir->dData == NULL)) { 7023d8536b4Sopenharmony_ci errno = EBADF; 7033d8536b4Sopenharmony_ci return (int)LOS_NOK; 7043d8536b4Sopenharmony_ci } 7053d8536b4Sopenharmony_ci 7063d8536b4Sopenharmony_ci dp = (DIR *)dir->dData; 7073d8536b4Sopenharmony_ci res = f_readdir(dp, &fileInfo); 7083d8536b4Sopenharmony_ci /* if res not ok or fname is NULL , return NULL */ 7093d8536b4Sopenharmony_ci if ((res != FR_OK) || (fileInfo.fname[0] == 0x0)) { 7103d8536b4Sopenharmony_ci PRINT_ERR("FAT readdir err 0x%x!\r\n", res); 7113d8536b4Sopenharmony_ci errno = FatfsErrno(res); 7123d8536b4Sopenharmony_ci return (int)LOS_NOK; 7133d8536b4Sopenharmony_ci } 7143d8536b4Sopenharmony_ci 7153d8536b4Sopenharmony_ci (void)memcpy_s(dent->d_name, sizeof(dent->d_name), 7163d8536b4Sopenharmony_ci fileInfo.fname, sizeof(dent->d_name)); 7173d8536b4Sopenharmony_ci if (fileInfo.fattrib & AM_DIR) { 7183d8536b4Sopenharmony_ci dent->d_type = DT_DIR; 7193d8536b4Sopenharmony_ci } else { 7203d8536b4Sopenharmony_ci dent->d_type = DT_REG; 7213d8536b4Sopenharmony_ci } 7223d8536b4Sopenharmony_ci 7233d8536b4Sopenharmony_ci return (int)LOS_OK; 7243d8536b4Sopenharmony_ci} 7253d8536b4Sopenharmony_ci 7263d8536b4Sopenharmony_ciint FatfsClosedir(struct Dir *dir) 7273d8536b4Sopenharmony_ci{ 7283d8536b4Sopenharmony_ci FRESULT res; 7293d8536b4Sopenharmony_ci DIR *dp = NULL; 7303d8536b4Sopenharmony_ci 7313d8536b4Sopenharmony_ci if ((dir == NULL) || (dir->dData == NULL)) { 7323d8536b4Sopenharmony_ci errno = EBADF; 7333d8536b4Sopenharmony_ci return (int)LOS_NOK; 7343d8536b4Sopenharmony_ci } 7353d8536b4Sopenharmony_ci 7363d8536b4Sopenharmony_ci dp = dir->dData; 7373d8536b4Sopenharmony_ci res = f_closedir(dp); 7383d8536b4Sopenharmony_ci if (res != FR_OK) { 7393d8536b4Sopenharmony_ci PRINT_ERR("FAT closedir err 0x%x!\r\n", res); 7403d8536b4Sopenharmony_ci errno = FatfsErrno(res); 7413d8536b4Sopenharmony_ci return (int)LOS_NOK; 7423d8536b4Sopenharmony_ci } 7433d8536b4Sopenharmony_ci 7443d8536b4Sopenharmony_ci LOSCFG_FS_FREE_HOOK(dir->dData); 7453d8536b4Sopenharmony_ci dir->dData = NULL; 7463d8536b4Sopenharmony_ci 7473d8536b4Sopenharmony_ci return (int)LOS_OK; 7483d8536b4Sopenharmony_ci} 7493d8536b4Sopenharmony_ci 7503d8536b4Sopenharmony_ciint FatfsRmdir(struct MountPoint *mp, const char *path) 7513d8536b4Sopenharmony_ci{ 7523d8536b4Sopenharmony_ci FRESULT res; 7533d8536b4Sopenharmony_ci int ret; 7543d8536b4Sopenharmony_ci 7553d8536b4Sopenharmony_ci if ((path == NULL) || (mp == NULL)) { 7563d8536b4Sopenharmony_ci errno = EFAULT; 7573d8536b4Sopenharmony_ci return (int)LOS_NOK; 7583d8536b4Sopenharmony_ci } 7593d8536b4Sopenharmony_ci 7603d8536b4Sopenharmony_ci if (!mp->mWriteEnable) { 7613d8536b4Sopenharmony_ci errno = EACCES; 7623d8536b4Sopenharmony_ci return (int)LOS_NOK; 7633d8536b4Sopenharmony_ci } 7643d8536b4Sopenharmony_ci 7653d8536b4Sopenharmony_ci ret = FsChangeDrive(path); 7663d8536b4Sopenharmony_ci if (ret != (int)LOS_OK) { 7673d8536b4Sopenharmony_ci PRINT_ERR("FAT rmdir ChangeDrive err 0x%x!\r\n", ret); 7683d8536b4Sopenharmony_ci errno = ENOENT; 7693d8536b4Sopenharmony_ci return (int)LOS_NOK; 7703d8536b4Sopenharmony_ci } 7713d8536b4Sopenharmony_ci 7723d8536b4Sopenharmony_ci res = f_rmdir(path); 7733d8536b4Sopenharmony_ci if (res != FR_OK) { 7743d8536b4Sopenharmony_ci PRINT_ERR("FAT rmdir err 0x%x!\r\n", res); 7753d8536b4Sopenharmony_ci errno = FatfsErrno(res); 7763d8536b4Sopenharmony_ci return (int)LOS_NOK; 7773d8536b4Sopenharmony_ci } 7783d8536b4Sopenharmony_ci 7793d8536b4Sopenharmony_ci return (int)LOS_OK; 7803d8536b4Sopenharmony_ci} 7813d8536b4Sopenharmony_ci 7823d8536b4Sopenharmony_ciint FatfsRename(struct MountPoint *mp, const char *oldName, const char *newName) 7833d8536b4Sopenharmony_ci{ 7843d8536b4Sopenharmony_ci FRESULT res; 7853d8536b4Sopenharmony_ci int ret; 7863d8536b4Sopenharmony_ci 7873d8536b4Sopenharmony_ci if ((oldName == NULL) || (newName == NULL)) { 7883d8536b4Sopenharmony_ci errno = EFAULT; 7893d8536b4Sopenharmony_ci return (int)LOS_NOK; 7903d8536b4Sopenharmony_ci } 7913d8536b4Sopenharmony_ci 7923d8536b4Sopenharmony_ci if (!mp->mWriteEnable) { 7933d8536b4Sopenharmony_ci errno = EACCES; 7943d8536b4Sopenharmony_ci return (int)LOS_NOK; 7953d8536b4Sopenharmony_ci } 7963d8536b4Sopenharmony_ci 7973d8536b4Sopenharmony_ci ret = FsChangeDrive(oldName); 7983d8536b4Sopenharmony_ci if (ret != (int)LOS_OK) { 7993d8536b4Sopenharmony_ci PRINT_ERR("FAT f_getfree ChangeDrive err 0x%x!\r\n", ret); 8003d8536b4Sopenharmony_ci errno = ENOENT; 8013d8536b4Sopenharmony_ci return (int)LOS_NOK; 8023d8536b4Sopenharmony_ci } 8033d8536b4Sopenharmony_ci 8043d8536b4Sopenharmony_ci res = f_rename(oldName, newName); 8053d8536b4Sopenharmony_ci if (res != FR_OK) { 8063d8536b4Sopenharmony_ci PRINT_ERR("FAT frename err 0x%x!\r\n", res); 8073d8536b4Sopenharmony_ci errno = FatfsErrno(res); 8083d8536b4Sopenharmony_ci return (int)LOS_NOK; 8093d8536b4Sopenharmony_ci } 8103d8536b4Sopenharmony_ci 8113d8536b4Sopenharmony_ci return (int)LOS_OK; 8123d8536b4Sopenharmony_ci} 8133d8536b4Sopenharmony_ci 8143d8536b4Sopenharmony_ciint FatfsStatfs(const char *path, struct statfs *buf) 8153d8536b4Sopenharmony_ci{ 8163d8536b4Sopenharmony_ci FATFS *fs = NULL; 8173d8536b4Sopenharmony_ci UINT32 freeClust; 8183d8536b4Sopenharmony_ci FRESULT res; 8193d8536b4Sopenharmony_ci int ret; 8203d8536b4Sopenharmony_ci 8213d8536b4Sopenharmony_ci if ((path == NULL) || (buf == NULL)) { 8223d8536b4Sopenharmony_ci errno = EFAULT; 8233d8536b4Sopenharmony_ci return (int)LOS_NOK; 8243d8536b4Sopenharmony_ci } 8253d8536b4Sopenharmony_ci 8263d8536b4Sopenharmony_ci ret = FsChangeDrive(path); 8273d8536b4Sopenharmony_ci if (ret != FR_OK) { 8283d8536b4Sopenharmony_ci PRINT_ERR("FAT f_getfree ChangeDrive err %d.", ret); 8293d8536b4Sopenharmony_ci errno = FatfsErrno(FR_INVALID_PARAMETER); 8303d8536b4Sopenharmony_ci return (int)LOS_NOK; 8313d8536b4Sopenharmony_ci } 8323d8536b4Sopenharmony_ci 8333d8536b4Sopenharmony_ci res = f_getfree(path, &freeClust, &fs); 8343d8536b4Sopenharmony_ci if (res != FR_OK) { 8353d8536b4Sopenharmony_ci PRINT_ERR("FAT f_getfree err 0x%x.", res); 8363d8536b4Sopenharmony_ci errno = FatfsErrno(res); 8373d8536b4Sopenharmony_ci return (int)LOS_NOK; 8383d8536b4Sopenharmony_ci } 8393d8536b4Sopenharmony_ci buf->f_bfree = freeClust; 8403d8536b4Sopenharmony_ci buf->f_bavail = freeClust; 8413d8536b4Sopenharmony_ci /* Cluster #0 and #1 is for VBR, reserve sectors and fat */ 8423d8536b4Sopenharmony_ci buf->f_blocks = fs->n_fatent - 2; 8433d8536b4Sopenharmony_ci#if FF_MAX_SS != FF_MIN_SS 8443d8536b4Sopenharmony_ci buf->f_bsize = fs->ssize * fs->csize; 8453d8536b4Sopenharmony_ci#else 8463d8536b4Sopenharmony_ci buf->f_bsize = FF_MIN_SS * fs->csize; 8473d8536b4Sopenharmony_ci#endif 8483d8536b4Sopenharmony_ci 8493d8536b4Sopenharmony_ci return (int)LOS_OK; 8503d8536b4Sopenharmony_ci} 8513d8536b4Sopenharmony_ci 8523d8536b4Sopenharmony_cistatic int DoTruncate(struct File *file, off_t length, UINT32 count) 8533d8536b4Sopenharmony_ci{ 8543d8536b4Sopenharmony_ci FRESULT res = FR_OK; 8553d8536b4Sopenharmony_ci DWORD csz; 8563d8536b4Sopenharmony_ci FIL *fp = (FIL *)file->fData; 8573d8536b4Sopenharmony_ci 8583d8536b4Sopenharmony_ci csz = (DWORD)(fp->obj.fs)->csize * SS(fp->obj.fs); /* Cluster size */ 8593d8536b4Sopenharmony_ci if (length > csz * count) { 8603d8536b4Sopenharmony_ci#if FF_USE_EXPAND 8613d8536b4Sopenharmony_ci res = f_expand(fp, 0, (FSIZE_t)(length), FALLOC_FL_KEEP_SIZE); 8623d8536b4Sopenharmony_ci#else 8633d8536b4Sopenharmony_ci errno = ENOSYS; 8643d8536b4Sopenharmony_ci return (int)LOS_NOK; 8653d8536b4Sopenharmony_ci#endif 8663d8536b4Sopenharmony_ci } else if (length < csz * count) { 8673d8536b4Sopenharmony_ci res = f_truncate(fp, (FSIZE_t)length); 8683d8536b4Sopenharmony_ci } 8693d8536b4Sopenharmony_ci 8703d8536b4Sopenharmony_ci if (res != FR_OK) { 8713d8536b4Sopenharmony_ci errno = FatfsErrno(res); 8723d8536b4Sopenharmony_ci return (int)LOS_NOK; 8733d8536b4Sopenharmony_ci } 8743d8536b4Sopenharmony_ci 8753d8536b4Sopenharmony_ci fp->obj.objsize = length; /* Set file size to length */ 8763d8536b4Sopenharmony_ci fp->flag |= 0x40; /* Set modified flag */ 8773d8536b4Sopenharmony_ci 8783d8536b4Sopenharmony_ci return (int)LOS_OK; 8793d8536b4Sopenharmony_ci} 8803d8536b4Sopenharmony_ci 8813d8536b4Sopenharmony_ciint FatfsTruncate(struct File *file, off_t length) 8823d8536b4Sopenharmony_ci{ 8833d8536b4Sopenharmony_ci FRESULT res; 8843d8536b4Sopenharmony_ci UINT count; 8853d8536b4Sopenharmony_ci DWORD fclust; 8863d8536b4Sopenharmony_ci FIL *fp = (FIL *)file->fData; 8873d8536b4Sopenharmony_ci 8883d8536b4Sopenharmony_ci if ((length < 0) || (length > UINT_MAX)) { 8893d8536b4Sopenharmony_ci errno = EINVAL; 8903d8536b4Sopenharmony_ci return (int)LOS_NOK; 8913d8536b4Sopenharmony_ci } 8923d8536b4Sopenharmony_ci 8933d8536b4Sopenharmony_ci if ((fp == NULL) || (fp->obj.fs == NULL)) { 8943d8536b4Sopenharmony_ci errno = ENOENT; 8953d8536b4Sopenharmony_ci return (int)LOS_NOK; 8963d8536b4Sopenharmony_ci } 8973d8536b4Sopenharmony_ci 8983d8536b4Sopenharmony_ci res = f_getclustinfo(fp, &fclust, &count); 8993d8536b4Sopenharmony_ci if (res != FR_OK) { 9003d8536b4Sopenharmony_ci errno = FatfsErrno(res); 9013d8536b4Sopenharmony_ci return (int)LOS_NOK; 9023d8536b4Sopenharmony_ci } 9033d8536b4Sopenharmony_ci 9043d8536b4Sopenharmony_ci return DoTruncate(file, length, count); 9053d8536b4Sopenharmony_ci} 9063d8536b4Sopenharmony_ci 9073d8536b4Sopenharmony_ciint FatfsFdisk(const char *dev, int *partTbl, int arrayNum) 9083d8536b4Sopenharmony_ci{ 9093d8536b4Sopenharmony_ci int pdrv; 9103d8536b4Sopenharmony_ci FRESULT res; 9113d8536b4Sopenharmony_ci 9123d8536b4Sopenharmony_ci if ((dev == NULL) || (partTbl == NULL)) { 9133d8536b4Sopenharmony_ci errno = EFAULT; 9143d8536b4Sopenharmony_ci return (int)LOS_NOK; 9153d8536b4Sopenharmony_ci } 9163d8536b4Sopenharmony_ci 9173d8536b4Sopenharmony_ci pdrv = GetDevIdByDevName(dev); 9183d8536b4Sopenharmony_ci if (pdrv < 0) { 9193d8536b4Sopenharmony_ci errno = EFAULT; 9203d8536b4Sopenharmony_ci return (int)LOS_NOK; 9213d8536b4Sopenharmony_ci } 9223d8536b4Sopenharmony_ci 9233d8536b4Sopenharmony_ci res = f_fdisk(pdrv, (DWORD const *)partTbl, g_workBuffer); 9243d8536b4Sopenharmony_ci if (res != FR_OK) { 9253d8536b4Sopenharmony_ci errno = FatfsErrno(res); 9263d8536b4Sopenharmony_ci return (int)LOS_NOK; 9273d8536b4Sopenharmony_ci } 9283d8536b4Sopenharmony_ci 9293d8536b4Sopenharmony_ci return (int)LOS_OK; 9303d8536b4Sopenharmony_ci} 9313d8536b4Sopenharmony_ci 9323d8536b4Sopenharmony_ciint FatfsFormat(const char *partName, void *privData) 9333d8536b4Sopenharmony_ci{ 9343d8536b4Sopenharmony_ci FRESULT res; 9353d8536b4Sopenharmony_ci MKFS_PARM opt = {0}; 9363d8536b4Sopenharmony_ci int option = *(int *)privData; 9373d8536b4Sopenharmony_ci char *dev = NULL; /* logical driver */ 9383d8536b4Sopenharmony_ci 9393d8536b4Sopenharmony_ci if (partName == NULL) { 9403d8536b4Sopenharmony_ci errno = EFAULT; 9413d8536b4Sopenharmony_ci return (int)LOS_NOK; 9423d8536b4Sopenharmony_ci } 9433d8536b4Sopenharmony_ci 9443d8536b4Sopenharmony_ci dev = GetLdPath(partName); 9453d8536b4Sopenharmony_ci if (dev == NULL) { 9463d8536b4Sopenharmony_ci errno = EFAULT; 9473d8536b4Sopenharmony_ci return (int)LOS_NOK; 9483d8536b4Sopenharmony_ci } 9493d8536b4Sopenharmony_ci 9503d8536b4Sopenharmony_ci opt.fmt = option; 9513d8536b4Sopenharmony_ci opt.n_sect = 0; /* use default allocation unit size depends on the volume 9523d8536b4Sopenharmony_ci size. */ 9533d8536b4Sopenharmony_ci res = f_mkfs(dev, &opt, g_workBuffer, FF_MAX_SS); 9543d8536b4Sopenharmony_ci if (res != FR_OK) { 9553d8536b4Sopenharmony_ci errno = FatfsErrno(res); 9563d8536b4Sopenharmony_ci PutLdPath(dev); 9573d8536b4Sopenharmony_ci return (int)LOS_NOK; 9583d8536b4Sopenharmony_ci } 9593d8536b4Sopenharmony_ci 9603d8536b4Sopenharmony_ci return (int)LOS_OK; 9613d8536b4Sopenharmony_ci} 9623d8536b4Sopenharmony_ci 9633d8536b4Sopenharmony_cistatic struct MountOps g_fatfsMnt = { 9643d8536b4Sopenharmony_ci .mount = FatfsMount, 9653d8536b4Sopenharmony_ci .umount = FatfsUmount, 9663d8536b4Sopenharmony_ci .umount2 = FatfsUmount2, 9673d8536b4Sopenharmony_ci .statfs = FatfsStatfs, 9683d8536b4Sopenharmony_ci}; 9693d8536b4Sopenharmony_ci 9703d8536b4Sopenharmony_cistatic struct FileOps g_fatfsFops = { 9713d8536b4Sopenharmony_ci .open = FatfsOpen, 9723d8536b4Sopenharmony_ci .close = FatfsClose, 9733d8536b4Sopenharmony_ci .read = FatfsRead, 9743d8536b4Sopenharmony_ci .write = FatfsWrite, 9753d8536b4Sopenharmony_ci .lseek = FatfsLseek, 9763d8536b4Sopenharmony_ci .stat = FatfsStat, 9773d8536b4Sopenharmony_ci .truncate = FatfsTruncate, 9783d8536b4Sopenharmony_ci .unlink = FatfsUnlink, 9793d8536b4Sopenharmony_ci .rename = FatfsRename, 9803d8536b4Sopenharmony_ci .ioctl = NULL, /* not support */ 9813d8536b4Sopenharmony_ci .sync = FatfsSync, 9823d8536b4Sopenharmony_ci .opendir = FatfsOpendir, 9833d8536b4Sopenharmony_ci .readdir = FatfsReaddir, 9843d8536b4Sopenharmony_ci .closedir = FatfsClosedir, 9853d8536b4Sopenharmony_ci .mkdir = FatfsMkdir, 9863d8536b4Sopenharmony_ci .rmdir = FatfsRmdir, 9873d8536b4Sopenharmony_ci}; 9883d8536b4Sopenharmony_ci 9893d8536b4Sopenharmony_cistatic struct FsManagement g_fatfsMgt = { 9903d8536b4Sopenharmony_ci .fdisk = FatfsFdisk, 9913d8536b4Sopenharmony_ci .format = FatfsFormat, 9923d8536b4Sopenharmony_ci}; 9933d8536b4Sopenharmony_ci 9943d8536b4Sopenharmony_civoid FatFsInit(void) 9953d8536b4Sopenharmony_ci{ 9963d8536b4Sopenharmony_ci (void)OsFsRegister("vfat", &g_fatfsMnt, &g_fatfsFops, &g_fatfsMgt); 9973d8536b4Sopenharmony_ci} 998