154568cb3Sopenharmony_ci/*
254568cb3Sopenharmony_ci * Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved.
354568cb3Sopenharmony_ci *
454568cb3Sopenharmony_ci * UniProton is licensed under Mulan PSL v2.
554568cb3Sopenharmony_ci * You can use this software according to the terms and conditions of the Mulan PSL v2.
654568cb3Sopenharmony_ci * You may obtain a copy of Mulan PSL v2 at:
754568cb3Sopenharmony_ci *          http://license.coscl.org.cn/MulanPSL2
854568cb3Sopenharmony_ci * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
954568cb3Sopenharmony_ci * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
1054568cb3Sopenharmony_ci * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
1154568cb3Sopenharmony_ci * See the Mulan PSL v2 for more details.
1254568cb3Sopenharmony_ci * Create: 2022-09-21
1354568cb3Sopenharmony_ci * Description: 文件系统vfs层
1454568cb3Sopenharmony_ci */
1554568cb3Sopenharmony_ci
1654568cb3Sopenharmony_ci#define _GNU_SOURCE 1
1754568cb3Sopenharmony_ci#include <stdint.h>
1854568cb3Sopenharmony_ci#include <string.h>
1954568cb3Sopenharmony_ci#include <stdlib.h>
2054568cb3Sopenharmony_ci#include <stdarg.h>
2154568cb3Sopenharmony_ci#include <unistd.h>
2254568cb3Sopenharmony_ci#include <sys/uio.h>
2354568cb3Sopenharmony_ci#include <pthread.h>
2454568cb3Sopenharmony_ci#include "errno.h"
2554568cb3Sopenharmony_ci#include "fcntl.h"
2654568cb3Sopenharmony_ci#include "limits.h"
2754568cb3Sopenharmony_ci#include "securec.h"
2854568cb3Sopenharmony_ci#include "prt_fs.h"
2954568cb3Sopenharmony_ci#include "vfs_config.h"
3054568cb3Sopenharmony_ci#include "vfs_files.h"
3154568cb3Sopenharmony_ci#include "vfs_maps.h"
3254568cb3Sopenharmony_ci#include "vfs_mount.h"
3354568cb3Sopenharmony_ci#include "vfs_operations.h"
3454568cb3Sopenharmony_ci#include "prt_task.h"
3554568cb3Sopenharmony_ci
3654568cb3Sopenharmony_ci#define FREE_AND_SET_NULL(ptr) do { \
3754568cb3Sopenharmony_ci    free(ptr);                      \
3854568cb3Sopenharmony_ci    ptr = NULL;                     \
3954568cb3Sopenharmony_ci} while (0)
4054568cb3Sopenharmony_ci
4154568cb3Sopenharmony_cistatic pthread_mutex_t g_vfsMutex = PTHREAD_MUTEX_INITIALIZER;
4254568cb3Sopenharmony_ci
4354568cb3Sopenharmony_ciS32 OsVfsLock(void)
4454568cb3Sopenharmony_ci{
4554568cb3Sopenharmony_ci    S32 ret = pthread_mutex_lock(&g_vfsMutex);
4654568cb3Sopenharmony_ci    if (ret != 0) {
4754568cb3Sopenharmony_ci        return FS_NOK;
4854568cb3Sopenharmony_ci    }
4954568cb3Sopenharmony_ci    return FS_OK;
5054568cb3Sopenharmony_ci}
5154568cb3Sopenharmony_ci
5254568cb3Sopenharmony_civoid OsVfsUnlock(void)
5354568cb3Sopenharmony_ci{
5454568cb3Sopenharmony_ci    (void)pthread_mutex_unlock(&g_vfsMutex);
5554568cb3Sopenharmony_ci    return;
5654568cb3Sopenharmony_ci}
5754568cb3Sopenharmony_ci
5854568cb3Sopenharmony_ciS32 OsVfsOpen(const char *path, S32 flags, va_list ap)
5954568cb3Sopenharmony_ci{
6054568cb3Sopenharmony_ci    (void)ap;
6154568cb3Sopenharmony_ci    struct TagFile *file = NULL;
6254568cb3Sopenharmony_ci    S32 fd = -1;
6354568cb3Sopenharmony_ci    const char *pathInMp = NULL;
6454568cb3Sopenharmony_ci    struct TagMountPoint *mp = NULL;
6554568cb3Sopenharmony_ci    TskHandle taskId = 0;
6654568cb3Sopenharmony_ci
6754568cb3Sopenharmony_ci    if ((path == NULL) || (path[strlen(path) - 1] == '/')) {
6854568cb3Sopenharmony_ci        VFS_ERRNO_SET(EINVAL);
6954568cb3Sopenharmony_ci        return fd;
7054568cb3Sopenharmony_ci    }
7154568cb3Sopenharmony_ci
7254568cb3Sopenharmony_ci    if (OsVfsLock() != FS_OK) {
7354568cb3Sopenharmony_ci        VFS_ERRNO_SET(EAGAIN);
7454568cb3Sopenharmony_ci        return fd;
7554568cb3Sopenharmony_ci    }
7654568cb3Sopenharmony_ci
7754568cb3Sopenharmony_ci    mp = OsVfsFindMp(path, &pathInMp);
7854568cb3Sopenharmony_ci    if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0') ||
7954568cb3Sopenharmony_ci        (mp->mFs->fsFops == NULL) || (mp->mFs->fsFops->open == NULL)) {
8054568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOENT);
8154568cb3Sopenharmony_ci        OsVfsUnlock();
8254568cb3Sopenharmony_ci        return fd;
8354568cb3Sopenharmony_ci    }
8454568cb3Sopenharmony_ci
8554568cb3Sopenharmony_ci    if ((mp->mWriteEnable == FALSE) &&
8654568cb3Sopenharmony_ci        (flags & (O_CREAT | O_WRONLY | O_RDWR))) {
8754568cb3Sopenharmony_ci        VFS_ERRNO_SET(EACCES);
8854568cb3Sopenharmony_ci        OsVfsUnlock();
8954568cb3Sopenharmony_ci        return fd;
9054568cb3Sopenharmony_ci    }
9154568cb3Sopenharmony_ci
9254568cb3Sopenharmony_ci    file = OsVfsGetFile();
9354568cb3Sopenharmony_ci    if (file == NULL) {
9454568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENFILE);
9554568cb3Sopenharmony_ci        OsVfsUnlock();
9654568cb3Sopenharmony_ci        return fd;
9754568cb3Sopenharmony_ci    }
9854568cb3Sopenharmony_ci
9954568cb3Sopenharmony_ci    file->fullPath = strdup(path);
10054568cb3Sopenharmony_ci    if (file->fullPath == NULL) {
10154568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOMEM);
10254568cb3Sopenharmony_ci        OsVfsPutFile(file);
10354568cb3Sopenharmony_ci        OsVfsUnlock();
10454568cb3Sopenharmony_ci        return FS_NOK;
10554568cb3Sopenharmony_ci    }
10654568cb3Sopenharmony_ci
10754568cb3Sopenharmony_ci    (void)PRT_TaskSelf(&taskId);
10854568cb3Sopenharmony_ci    file->fFlags = (U32)flags;
10954568cb3Sopenharmony_ci    file->fOffset = 0;
11054568cb3Sopenharmony_ci    file->fData = NULL;
11154568cb3Sopenharmony_ci    file->fFops = mp->mFs->fsFops;
11254568cb3Sopenharmony_ci    file->fMp = mp;
11354568cb3Sopenharmony_ci    file->fOwner = taskId;
11454568cb3Sopenharmony_ci
11554568cb3Sopenharmony_ci    if (file->fFops->open(file, pathInMp, flags) == 0) {
11654568cb3Sopenharmony_ci        mp->mRefs++;
11754568cb3Sopenharmony_ci        fd = OsFileToFd(file);
11854568cb3Sopenharmony_ci        file->fStatus = FILE_STATUS_READY;
11954568cb3Sopenharmony_ci    } else {
12054568cb3Sopenharmony_ci        OsVfsPutFile(file);
12154568cb3Sopenharmony_ci    }
12254568cb3Sopenharmony_ci
12354568cb3Sopenharmony_ci    OsVfsUnlock();
12454568cb3Sopenharmony_ci    return fd;
12554568cb3Sopenharmony_ci}
12654568cb3Sopenharmony_ci
12754568cb3Sopenharmony_cistatic struct TagFile *OsVfsAttachFile(S32 fd, U32 status)
12854568cb3Sopenharmony_ci{
12954568cb3Sopenharmony_ci    struct TagFile *file = NULL;
13054568cb3Sopenharmony_ci
13154568cb3Sopenharmony_ci    if ((fd < 0) || (fd >= CONFIG_NFILE_DESCRIPTORS)) {
13254568cb3Sopenharmony_ci        VFS_ERRNO_SET(EBADF);
13354568cb3Sopenharmony_ci        return NULL;
13454568cb3Sopenharmony_ci    }
13554568cb3Sopenharmony_ci
13654568cb3Sopenharmony_ci    if (OsVfsLock() != FS_OK) {
13754568cb3Sopenharmony_ci        VFS_ERRNO_SET(EFAULT);
13854568cb3Sopenharmony_ci        return NULL;
13954568cb3Sopenharmony_ci    }
14054568cb3Sopenharmony_ci
14154568cb3Sopenharmony_ci    file = OsFdToFile(fd);
14254568cb3Sopenharmony_ci    if ((file == NULL) || (file->fMp == NULL)) {
14354568cb3Sopenharmony_ci        VFS_ERRNO_SET(EBADF);
14454568cb3Sopenharmony_ci        OsVfsUnlock();
14554568cb3Sopenharmony_ci        return NULL;
14654568cb3Sopenharmony_ci    }
14754568cb3Sopenharmony_ci
14854568cb3Sopenharmony_ci    if (file->fStatus != FILE_STATUS_READY) {
14954568cb3Sopenharmony_ci        VFS_ERRNO_SET(EBADF);
15054568cb3Sopenharmony_ci        OsVfsUnlock();
15154568cb3Sopenharmony_ci        return NULL;
15254568cb3Sopenharmony_ci    }
15354568cb3Sopenharmony_ci
15454568cb3Sopenharmony_ci    file->fStatus = status;
15554568cb3Sopenharmony_ci    return file;
15654568cb3Sopenharmony_ci}
15754568cb3Sopenharmony_ci
15854568cb3Sopenharmony_cistatic struct TagFile *OsVfsAttachFileReady(S32 fd)
15954568cb3Sopenharmony_ci{
16054568cb3Sopenharmony_ci    return OsVfsAttachFile(fd, FILE_STATUS_READY);
16154568cb3Sopenharmony_ci}
16254568cb3Sopenharmony_ci
16354568cb3Sopenharmony_cistatic struct TagFile *OsVfsAttachFileWithStatus(S32 fd, S32 status)
16454568cb3Sopenharmony_ci{
16554568cb3Sopenharmony_ci    return OsVfsAttachFile(fd, (U32)status);
16654568cb3Sopenharmony_ci}
16754568cb3Sopenharmony_ci
16854568cb3Sopenharmony_cistatic void OsVfsDetachFile(const struct TagFile *file)
16954568cb3Sopenharmony_ci{
17054568cb3Sopenharmony_ci    (void)file;
17154568cb3Sopenharmony_ci    OsVfsUnlock();
17254568cb3Sopenharmony_ci}
17354568cb3Sopenharmony_ci
17454568cb3Sopenharmony_ciS32 OsVfsClose(S32 fd)
17554568cb3Sopenharmony_ci{
17654568cb3Sopenharmony_ci    S32 ret = FS_NOK;
17754568cb3Sopenharmony_ci    struct TagFile *file = OsVfsAttachFileWithStatus(fd, FILE_STATUS_CLOSING);
17854568cb3Sopenharmony_ci    if (file == NULL) {
17954568cb3Sopenharmony_ci        return ret;
18054568cb3Sopenharmony_ci    }
18154568cb3Sopenharmony_ci
18254568cb3Sopenharmony_ci    if ((file->fFops != NULL) && (file->fFops->close != NULL)) {
18354568cb3Sopenharmony_ci        ret = file->fFops->close(file);
18454568cb3Sopenharmony_ci    } else {
18554568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOTSUP);
18654568cb3Sopenharmony_ci    }
18754568cb3Sopenharmony_ci
18854568cb3Sopenharmony_ci    if ((ret == 0) && (file->fMp != NULL)) {
18954568cb3Sopenharmony_ci        file->fMp->mRefs--;
19054568cb3Sopenharmony_ci    }
19154568cb3Sopenharmony_ci
19254568cb3Sopenharmony_ci    if (file->fullPath != NULL) {
19354568cb3Sopenharmony_ci        free((void *)file->fullPath);
19454568cb3Sopenharmony_ci    }
19554568cb3Sopenharmony_ci
19654568cb3Sopenharmony_ci    OsVfsDetachFile(file);
19754568cb3Sopenharmony_ci    OsVfsPutFile(file);
19854568cb3Sopenharmony_ci    return ret;
19954568cb3Sopenharmony_ci}
20054568cb3Sopenharmony_ci
20154568cb3Sopenharmony_cissize_t OsVfsRead(S32 fd, char *buff, size_t bytes)
20254568cb3Sopenharmony_ci{
20354568cb3Sopenharmony_ci    struct TagFile *file = NULL;
20454568cb3Sopenharmony_ci    ssize_t ret = (ssize_t)-1;
20554568cb3Sopenharmony_ci
20654568cb3Sopenharmony_ci    if (buff == NULL) {
20754568cb3Sopenharmony_ci        VFS_ERRNO_SET(EFAULT);
20854568cb3Sopenharmony_ci        return ret;
20954568cb3Sopenharmony_ci    }
21054568cb3Sopenharmony_ci
21154568cb3Sopenharmony_ci    if (bytes == 0) {
21254568cb3Sopenharmony_ci        return 0;
21354568cb3Sopenharmony_ci    }
21454568cb3Sopenharmony_ci
21554568cb3Sopenharmony_ci    file = OsVfsAttachFileReady(fd);
21654568cb3Sopenharmony_ci    if (file == NULL) {
21754568cb3Sopenharmony_ci        return ret;
21854568cb3Sopenharmony_ci    }
21954568cb3Sopenharmony_ci
22054568cb3Sopenharmony_ci    if ((file->fFlags & O_ACCMODE) == O_WRONLY) {
22154568cb3Sopenharmony_ci        VFS_ERRNO_SET(EACCES);
22254568cb3Sopenharmony_ci    } else if ((file->fFops != NULL) && (file->fFops->read != NULL)) {
22354568cb3Sopenharmony_ci        ret = file->fFops->read(file, buff, bytes);
22454568cb3Sopenharmony_ci    } else {
22554568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOTSUP);
22654568cb3Sopenharmony_ci    }
22754568cb3Sopenharmony_ci
22854568cb3Sopenharmony_ci    OsVfsDetachFile(file);
22954568cb3Sopenharmony_ci    return ret;
23054568cb3Sopenharmony_ci}
23154568cb3Sopenharmony_ci
23254568cb3Sopenharmony_cissize_t OsVfsWrite(S32 fd, const void *buff, size_t bytes)
23354568cb3Sopenharmony_ci{
23454568cb3Sopenharmony_ci    struct TagFile *file = NULL;
23554568cb3Sopenharmony_ci    ssize_t ret = (ssize_t)FS_NOK;
23654568cb3Sopenharmony_ci
23754568cb3Sopenharmony_ci    if ((buff == NULL) || (bytes == 0)) {
23854568cb3Sopenharmony_ci        VFS_ERRNO_SET(EINVAL);
23954568cb3Sopenharmony_ci        return ret;
24054568cb3Sopenharmony_ci    }
24154568cb3Sopenharmony_ci
24254568cb3Sopenharmony_ci    file = OsVfsAttachFileReady(fd);
24354568cb3Sopenharmony_ci    if (file == NULL) {
24454568cb3Sopenharmony_ci        return ret;
24554568cb3Sopenharmony_ci    }
24654568cb3Sopenharmony_ci
24754568cb3Sopenharmony_ci    if ((file->fFlags & O_ACCMODE) == O_RDONLY) {
24854568cb3Sopenharmony_ci        VFS_ERRNO_SET(EACCES);
24954568cb3Sopenharmony_ci    } else if ((file->fFops != NULL) && (file->fFops->write != NULL)) {
25054568cb3Sopenharmony_ci        ret = file->fFops->write(file, buff, bytes);
25154568cb3Sopenharmony_ci    } else {
25254568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOTSUP);
25354568cb3Sopenharmony_ci    }
25454568cb3Sopenharmony_ci
25554568cb3Sopenharmony_ci    OsVfsDetachFile(file);
25654568cb3Sopenharmony_ci    return ret;
25754568cb3Sopenharmony_ci}
25854568cb3Sopenharmony_ci
25954568cb3Sopenharmony_cioff_t OsVfsLseek(S32 fd, off_t off, S32 whence)
26054568cb3Sopenharmony_ci{
26154568cb3Sopenharmony_ci    off_t ret = (off_t)FS_NOK;
26254568cb3Sopenharmony_ci    struct TagFile *file = OsVfsAttachFileReady(fd);
26354568cb3Sopenharmony_ci    if (file == NULL) {
26454568cb3Sopenharmony_ci        return ret;
26554568cb3Sopenharmony_ci    }
26654568cb3Sopenharmony_ci
26754568cb3Sopenharmony_ci    if ((file->fFops == NULL) || (file->fFops->lseek == NULL)) {
26854568cb3Sopenharmony_ci        ret = file->fOffset;
26954568cb3Sopenharmony_ci    } else {
27054568cb3Sopenharmony_ci        ret = file->fFops->lseek(file, off, whence);
27154568cb3Sopenharmony_ci    }
27254568cb3Sopenharmony_ci
27354568cb3Sopenharmony_ci    OsVfsDetachFile(file);
27454568cb3Sopenharmony_ci    return ret;
27554568cb3Sopenharmony_ci}
27654568cb3Sopenharmony_ci
27754568cb3Sopenharmony_ciS32 OsVfsStat(const char *path, struct stat *stat)
27854568cb3Sopenharmony_ci{
27954568cb3Sopenharmony_ci    struct TagMountPoint *mp = NULL;
28054568cb3Sopenharmony_ci    const char *pathInMp = NULL;
28154568cb3Sopenharmony_ci    S32 ret = FS_NOK;
28254568cb3Sopenharmony_ci
28354568cb3Sopenharmony_ci    if ((path == NULL) || (stat == NULL)) {
28454568cb3Sopenharmony_ci        VFS_ERRNO_SET(EINVAL);
28554568cb3Sopenharmony_ci        return ret;
28654568cb3Sopenharmony_ci    }
28754568cb3Sopenharmony_ci
28854568cb3Sopenharmony_ci    if (OsVfsLock() != FS_OK) {
28954568cb3Sopenharmony_ci        VFS_ERRNO_SET(EAGAIN);
29054568cb3Sopenharmony_ci        return ret;
29154568cb3Sopenharmony_ci    }
29254568cb3Sopenharmony_ci
29354568cb3Sopenharmony_ci    mp = OsVfsFindMp(path, &pathInMp);
29454568cb3Sopenharmony_ci    if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0')) {
29554568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOENT);
29654568cb3Sopenharmony_ci        OsVfsUnlock();
29754568cb3Sopenharmony_ci        return ret;
29854568cb3Sopenharmony_ci    }
29954568cb3Sopenharmony_ci
30054568cb3Sopenharmony_ci    if (mp->mFs->fsFops->stat != NULL) {
30154568cb3Sopenharmony_ci        ret = mp->mFs->fsFops->stat(mp, pathInMp, stat);
30254568cb3Sopenharmony_ci    } else {
30354568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOTSUP);
30454568cb3Sopenharmony_ci    }
30554568cb3Sopenharmony_ci
30654568cb3Sopenharmony_ci    OsVfsUnlock();
30754568cb3Sopenharmony_ci    return ret;
30854568cb3Sopenharmony_ci}
30954568cb3Sopenharmony_ci
31054568cb3Sopenharmony_ciS32 OsVfsFstat(S32 fd, struct stat *buf)
31154568cb3Sopenharmony_ci{
31254568cb3Sopenharmony_ci    S32 ret;
31354568cb3Sopenharmony_ci    struct TagFile *filep = OsVfsAttachFileReady(fd);
31454568cb3Sopenharmony_ci    if ((filep == NULL) || (filep->fMp == NULL) || filep->fullPath == NULL) {
31554568cb3Sopenharmony_ci        return FS_NOK;
31654568cb3Sopenharmony_ci    }
31754568cb3Sopenharmony_ci    ret = stat(filep->fullPath, buf);
31854568cb3Sopenharmony_ci    OsVfsDetachFile(filep);
31954568cb3Sopenharmony_ci    return ret;
32054568cb3Sopenharmony_ci}
32154568cb3Sopenharmony_ci
32254568cb3Sopenharmony_ciS32 OsVfsStatfs(const char *path, struct statfs *buf)
32354568cb3Sopenharmony_ci{
32454568cb3Sopenharmony_ci    struct TagMountPoint *mp = NULL;
32554568cb3Sopenharmony_ci    const char *pathInMp = NULL;
32654568cb3Sopenharmony_ci    S32 ret = FS_NOK;
32754568cb3Sopenharmony_ci
32854568cb3Sopenharmony_ci    if ((path == NULL) || (buf == NULL)) {
32954568cb3Sopenharmony_ci        VFS_ERRNO_SET(EINVAL);
33054568cb3Sopenharmony_ci        return ret;
33154568cb3Sopenharmony_ci    }
33254568cb3Sopenharmony_ci
33354568cb3Sopenharmony_ci    if (OsVfsLock() != FS_OK) {
33454568cb3Sopenharmony_ci        VFS_ERRNO_SET(EAGAIN);
33554568cb3Sopenharmony_ci        return ret;
33654568cb3Sopenharmony_ci    }
33754568cb3Sopenharmony_ci
33854568cb3Sopenharmony_ci    mp = OsVfsFindMp(path, &pathInMp);
33954568cb3Sopenharmony_ci    if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0')) {
34054568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOENT);
34154568cb3Sopenharmony_ci        OsVfsUnlock();
34254568cb3Sopenharmony_ci        return ret;
34354568cb3Sopenharmony_ci    }
34454568cb3Sopenharmony_ci
34554568cb3Sopenharmony_ci    if (mp->mFs->fsFops->stat != NULL) {
34654568cb3Sopenharmony_ci        ret = mp->mFs->fsMops->statfs(pathInMp, buf);
34754568cb3Sopenharmony_ci    } else {
34854568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOTSUP);
34954568cb3Sopenharmony_ci    }
35054568cb3Sopenharmony_ci
35154568cb3Sopenharmony_ci    OsVfsUnlock();
35254568cb3Sopenharmony_ci    return ret;
35354568cb3Sopenharmony_ci}
35454568cb3Sopenharmony_ci
35554568cb3Sopenharmony_ciS32 OsVfsUnlink(const char *path)
35654568cb3Sopenharmony_ci{
35754568cb3Sopenharmony_ci    struct TagMountPoint *mp = NULL;
35854568cb3Sopenharmony_ci    const char *pathInMp = NULL;
35954568cb3Sopenharmony_ci    S32 ret = FS_NOK;
36054568cb3Sopenharmony_ci
36154568cb3Sopenharmony_ci    if (path == NULL) {
36254568cb3Sopenharmony_ci        VFS_ERRNO_SET(EINVAL);
36354568cb3Sopenharmony_ci        return ret;
36454568cb3Sopenharmony_ci    }
36554568cb3Sopenharmony_ci
36654568cb3Sopenharmony_ci    if (OsVfsLock() != FS_OK) {
36754568cb3Sopenharmony_ci        VFS_ERRNO_SET(EAGAIN);
36854568cb3Sopenharmony_ci        return ret;
36954568cb3Sopenharmony_ci    }
37054568cb3Sopenharmony_ci
37154568cb3Sopenharmony_ci    mp = OsVfsFindMp(path, &pathInMp);
37254568cb3Sopenharmony_ci    if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0') ||
37354568cb3Sopenharmony_ci        (mp->mFs->fsFops->unlink == NULL)) {
37454568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOENT);
37554568cb3Sopenharmony_ci        OsVfsUnlock();
37654568cb3Sopenharmony_ci        return ret;
37754568cb3Sopenharmony_ci    }
37854568cb3Sopenharmony_ci
37954568cb3Sopenharmony_ci    ret = mp->mFs->fsFops->unlink(mp, pathInMp);
38054568cb3Sopenharmony_ci
38154568cb3Sopenharmony_ci    OsVfsUnlock();
38254568cb3Sopenharmony_ci    return ret;
38354568cb3Sopenharmony_ci}
38454568cb3Sopenharmony_ci
38554568cb3Sopenharmony_ciS32 OsVfsRename(const char *oldName, const char *newName)
38654568cb3Sopenharmony_ci{
38754568cb3Sopenharmony_ci    struct TagMountPoint *mpOld = NULL;
38854568cb3Sopenharmony_ci    struct TagMountPoint *mpNew = NULL;
38954568cb3Sopenharmony_ci    const char *pathInMpOld = NULL;
39054568cb3Sopenharmony_ci    const char *pathInMpNew = NULL;
39154568cb3Sopenharmony_ci    S32 ret = FS_NOK;
39254568cb3Sopenharmony_ci
39354568cb3Sopenharmony_ci    if ((oldName == NULL) || (newName == NULL)) {
39454568cb3Sopenharmony_ci        VFS_ERRNO_SET(EINVAL);
39554568cb3Sopenharmony_ci        return ret;
39654568cb3Sopenharmony_ci    }
39754568cb3Sopenharmony_ci
39854568cb3Sopenharmony_ci    if (OsVfsLock() != FS_OK) {
39954568cb3Sopenharmony_ci        VFS_ERRNO_SET(EAGAIN);
40054568cb3Sopenharmony_ci        return ret;
40154568cb3Sopenharmony_ci    }
40254568cb3Sopenharmony_ci
40354568cb3Sopenharmony_ci    mpOld = OsVfsFindMp(oldName, &pathInMpOld);
40454568cb3Sopenharmony_ci
40554568cb3Sopenharmony_ci    if (pathInMpOld == NULL) {
40654568cb3Sopenharmony_ci        VFS_ERRNO_SET(EINVAL);
40754568cb3Sopenharmony_ci        OsVfsUnlock();
40854568cb3Sopenharmony_ci        return ret;
40954568cb3Sopenharmony_ci    }
41054568cb3Sopenharmony_ci
41154568cb3Sopenharmony_ci    if ((mpOld == NULL) || (*pathInMpOld == '\0') ||
41254568cb3Sopenharmony_ci        (mpOld->mFs->fsFops->unlink == NULL)) {
41354568cb3Sopenharmony_ci        VFS_ERRNO_SET(EINVAL);
41454568cb3Sopenharmony_ci        OsVfsUnlock();
41554568cb3Sopenharmony_ci        return ret;
41654568cb3Sopenharmony_ci    }
41754568cb3Sopenharmony_ci
41854568cb3Sopenharmony_ci    mpNew = OsVfsFindMp(newName, &pathInMpNew);
41954568cb3Sopenharmony_ci    if ((mpNew == NULL) || (pathInMpNew == NULL) || (*pathInMpNew == '\0') || (mpNew->mFs->fsFops->unlink == NULL)) {
42054568cb3Sopenharmony_ci        VFS_ERRNO_SET(EINVAL);
42154568cb3Sopenharmony_ci        OsVfsUnlock();
42254568cb3Sopenharmony_ci        return ret;
42354568cb3Sopenharmony_ci    }
42454568cb3Sopenharmony_ci
42554568cb3Sopenharmony_ci    if (mpOld != mpNew) {
42654568cb3Sopenharmony_ci        VFS_ERRNO_SET(EXDEV);
42754568cb3Sopenharmony_ci        OsVfsUnlock();
42854568cb3Sopenharmony_ci        return ret;
42954568cb3Sopenharmony_ci    }
43054568cb3Sopenharmony_ci
43154568cb3Sopenharmony_ci    if (mpOld->mFs->fsFops->rename != NULL) {
43254568cb3Sopenharmony_ci        ret = mpOld->mFs->fsFops->rename(mpOld, pathInMpOld, pathInMpNew);
43354568cb3Sopenharmony_ci    } else {
43454568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOTSUP);
43554568cb3Sopenharmony_ci    }
43654568cb3Sopenharmony_ci
43754568cb3Sopenharmony_ci    OsVfsUnlock();
43854568cb3Sopenharmony_ci    return ret;
43954568cb3Sopenharmony_ci}
44054568cb3Sopenharmony_ci
44154568cb3Sopenharmony_ciS32 OsVfsIoctl(S32 fd, S32 func, unsigned long arg)
44254568cb3Sopenharmony_ci{
44354568cb3Sopenharmony_ci    S32 ret = FS_NOK;
44454568cb3Sopenharmony_ci    struct TagFile *file = OsVfsAttachFileReady(fd);
44554568cb3Sopenharmony_ci    if (file == NULL) {
44654568cb3Sopenharmony_ci        return ret;
44754568cb3Sopenharmony_ci    }
44854568cb3Sopenharmony_ci
44954568cb3Sopenharmony_ci    if ((file->fFops != NULL) && (file->fFops->ioctl != NULL)) {
45054568cb3Sopenharmony_ci        ret = file->fFops->ioctl(file, func, arg);
45154568cb3Sopenharmony_ci    } else {
45254568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOTSUP);
45354568cb3Sopenharmony_ci    }
45454568cb3Sopenharmony_ci
45554568cb3Sopenharmony_ci    OsVfsDetachFile(file);
45654568cb3Sopenharmony_ci    return ret;
45754568cb3Sopenharmony_ci}
45854568cb3Sopenharmony_ci
45954568cb3Sopenharmony_ciS32 OsVfsSync(S32 fd)
46054568cb3Sopenharmony_ci{
46154568cb3Sopenharmony_ci    S32 ret = FS_NOK;
46254568cb3Sopenharmony_ci    struct TagFile *file = OsVfsAttachFileReady(fd);
46354568cb3Sopenharmony_ci    if (file == NULL) {
46454568cb3Sopenharmony_ci        return ret;
46554568cb3Sopenharmony_ci    }
46654568cb3Sopenharmony_ci
46754568cb3Sopenharmony_ci    if (file->fMp->mWriteEnable == FALSE) {
46854568cb3Sopenharmony_ci        VFS_ERRNO_SET(EACCES);
46954568cb3Sopenharmony_ci        OsVfsDetachFile(file);
47054568cb3Sopenharmony_ci        return ret;
47154568cb3Sopenharmony_ci    }
47254568cb3Sopenharmony_ci
47354568cb3Sopenharmony_ci    if ((file->fFops != NULL) && (file->fFops->sync != NULL)) {
47454568cb3Sopenharmony_ci        ret = file->fFops->sync(file);
47554568cb3Sopenharmony_ci    } else {
47654568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOTSUP);
47754568cb3Sopenharmony_ci    }
47854568cb3Sopenharmony_ci
47954568cb3Sopenharmony_ci    OsVfsDetachFile(file);
48054568cb3Sopenharmony_ci    return ret;
48154568cb3Sopenharmony_ci}
48254568cb3Sopenharmony_ci
48354568cb3Sopenharmony_ciDIR *OsVfsOpendir(const char *path)
48454568cb3Sopenharmony_ci{
48554568cb3Sopenharmony_ci    struct TagMountPoint *mp = NULL;
48654568cb3Sopenharmony_ci    const char *pathInMp = NULL;
48754568cb3Sopenharmony_ci    struct TagDir *dir = NULL;
48854568cb3Sopenharmony_ci    U32 ret;
48954568cb3Sopenharmony_ci
49054568cb3Sopenharmony_ci    if (path == NULL) {
49154568cb3Sopenharmony_ci        VFS_ERRNO_SET(EINVAL);
49254568cb3Sopenharmony_ci        return NULL;
49354568cb3Sopenharmony_ci    }
49454568cb3Sopenharmony_ci
49554568cb3Sopenharmony_ci    dir = (struct TagDir *)malloc(sizeof(struct TagDir));
49654568cb3Sopenharmony_ci    if (dir == NULL) {
49754568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOMEM);
49854568cb3Sopenharmony_ci        return NULL;
49954568cb3Sopenharmony_ci    }
50054568cb3Sopenharmony_ci
50154568cb3Sopenharmony_ci    if (OsVfsLock() != FS_OK) {
50254568cb3Sopenharmony_ci        VFS_ERRNO_SET(EAGAIN);
50354568cb3Sopenharmony_ci        free(dir);
50454568cb3Sopenharmony_ci        return NULL;
50554568cb3Sopenharmony_ci    }
50654568cb3Sopenharmony_ci
50754568cb3Sopenharmony_ci    mp = OsVfsFindMp(path, &pathInMp);
50854568cb3Sopenharmony_ci    if ((mp == NULL) || (pathInMp == NULL)) {
50954568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOENT);
51054568cb3Sopenharmony_ci        OsVfsUnlock();
51154568cb3Sopenharmony_ci        free(dir);
51254568cb3Sopenharmony_ci        return NULL;
51354568cb3Sopenharmony_ci    }
51454568cb3Sopenharmony_ci
51554568cb3Sopenharmony_ci    if (mp->mFs->fsFops->opendir == NULL) {
51654568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOTSUP);
51754568cb3Sopenharmony_ci        OsVfsUnlock();
51854568cb3Sopenharmony_ci        free(dir);
51954568cb3Sopenharmony_ci        return NULL;
52054568cb3Sopenharmony_ci    }
52154568cb3Sopenharmony_ci
52254568cb3Sopenharmony_ci    dir->dMp = mp;
52354568cb3Sopenharmony_ci    dir->dOffset = 0;
52454568cb3Sopenharmony_ci
52554568cb3Sopenharmony_ci    ret = (U32)mp->mFs->fsFops->opendir(dir, pathInMp);
52654568cb3Sopenharmony_ci    if (ret == 0) {
52754568cb3Sopenharmony_ci        mp->mRefs++;
52854568cb3Sopenharmony_ci    } else {
52954568cb3Sopenharmony_ci        free(dir);
53054568cb3Sopenharmony_ci        dir = NULL;
53154568cb3Sopenharmony_ci    }
53254568cb3Sopenharmony_ci
53354568cb3Sopenharmony_ci    OsVfsUnlock();
53454568cb3Sopenharmony_ci    return (DIR *)dir;
53554568cb3Sopenharmony_ci}
53654568cb3Sopenharmony_ci
53754568cb3Sopenharmony_cistruct dirent *OsVfsReaddir(DIR *d)
53854568cb3Sopenharmony_ci{
53954568cb3Sopenharmony_ci    struct dirent *ret = NULL;
54054568cb3Sopenharmony_ci    struct TagDir *dir = (struct TagDir *)d;
54154568cb3Sopenharmony_ci
54254568cb3Sopenharmony_ci    if ((dir == NULL) || (dir->dMp == NULL)) {
54354568cb3Sopenharmony_ci        VFS_ERRNO_SET(EINVAL);
54454568cb3Sopenharmony_ci        return NULL;
54554568cb3Sopenharmony_ci    }
54654568cb3Sopenharmony_ci
54754568cb3Sopenharmony_ci    if (OsVfsLock() != FS_OK) {
54854568cb3Sopenharmony_ci        VFS_ERRNO_SET(EAGAIN);
54954568cb3Sopenharmony_ci        return NULL;
55054568cb3Sopenharmony_ci    }
55154568cb3Sopenharmony_ci
55254568cb3Sopenharmony_ci    if ((dir->dMp->mFs != NULL) && (dir->dMp->mFs->fsFops != NULL) &&
55354568cb3Sopenharmony_ci        (dir->dMp->mFs->fsFops->readdir != NULL)) {
55454568cb3Sopenharmony_ci        if (dir->dMp->mFs->fsFops->readdir(dir, &dir->dDent) == 0) {
55554568cb3Sopenharmony_ci            ret = &dir->dDent;
55654568cb3Sopenharmony_ci        }
55754568cb3Sopenharmony_ci    } else {
55854568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOTSUP);
55954568cb3Sopenharmony_ci    }
56054568cb3Sopenharmony_ci
56154568cb3Sopenharmony_ci    OsVfsUnlock();
56254568cb3Sopenharmony_ci    return ret;
56354568cb3Sopenharmony_ci}
56454568cb3Sopenharmony_ci
56554568cb3Sopenharmony_ciS32 OsVfsClosedir(DIR *d)
56654568cb3Sopenharmony_ci{
56754568cb3Sopenharmony_ci    struct TagMountPoint *mp = NULL;
56854568cb3Sopenharmony_ci    S32 ret = FS_NOK;
56954568cb3Sopenharmony_ci    struct TagDir *dir = (struct TagDir *)d;
57054568cb3Sopenharmony_ci
57154568cb3Sopenharmony_ci    if ((dir == NULL) || (dir->dMp == NULL)) {
57254568cb3Sopenharmony_ci        VFS_ERRNO_SET(EBADF);
57354568cb3Sopenharmony_ci        return ret;
57454568cb3Sopenharmony_ci    }
57554568cb3Sopenharmony_ci
57654568cb3Sopenharmony_ci    mp = dir->dMp;
57754568cb3Sopenharmony_ci
57854568cb3Sopenharmony_ci    if (OsVfsLock() != FS_OK) {
57954568cb3Sopenharmony_ci        VFS_ERRNO_SET(EAGAIN);
58054568cb3Sopenharmony_ci        return ret;
58154568cb3Sopenharmony_ci    }
58254568cb3Sopenharmony_ci
58354568cb3Sopenharmony_ci    if ((dir->dMp->mFs != NULL) && (dir->dMp->mFs->fsFops != NULL) &&
58454568cb3Sopenharmony_ci        (dir->dMp->mFs->fsFops->closedir != NULL)) {
58554568cb3Sopenharmony_ci        ret = dir->dMp->mFs->fsFops->closedir(dir);
58654568cb3Sopenharmony_ci    } else {
58754568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOTSUP);
58854568cb3Sopenharmony_ci    }
58954568cb3Sopenharmony_ci
59054568cb3Sopenharmony_ci    if (ret == 0) {
59154568cb3Sopenharmony_ci        mp->mRefs--;
59254568cb3Sopenharmony_ci    } else {
59354568cb3Sopenharmony_ci        VFS_ERRNO_SET(EBADF);
59454568cb3Sopenharmony_ci    }
59554568cb3Sopenharmony_ci
59654568cb3Sopenharmony_ci    OsVfsUnlock();
59754568cb3Sopenharmony_ci    free(dir);
59854568cb3Sopenharmony_ci    dir = NULL;
59954568cb3Sopenharmony_ci    return ret;
60054568cb3Sopenharmony_ci}
60154568cb3Sopenharmony_ci
60254568cb3Sopenharmony_ciS32 OsVfsMkdir(const char *path, S32 mode)
60354568cb3Sopenharmony_ci{
60454568cb3Sopenharmony_ci    struct TagMountPoint *mp = NULL;
60554568cb3Sopenharmony_ci    const char *pathInMp = NULL;
60654568cb3Sopenharmony_ci    S32 ret = FS_NOK;
60754568cb3Sopenharmony_ci    (void)mode;
60854568cb3Sopenharmony_ci
60954568cb3Sopenharmony_ci    if (path == NULL) {
61054568cb3Sopenharmony_ci        VFS_ERRNO_SET(EINVAL);
61154568cb3Sopenharmony_ci        return ret;
61254568cb3Sopenharmony_ci    }
61354568cb3Sopenharmony_ci
61454568cb3Sopenharmony_ci    if (OsVfsLock() != FS_OK) {
61554568cb3Sopenharmony_ci        VFS_ERRNO_SET(EAGAIN);
61654568cb3Sopenharmony_ci        return ret;
61754568cb3Sopenharmony_ci    }
61854568cb3Sopenharmony_ci
61954568cb3Sopenharmony_ci    mp = OsVfsFindMp(path, &pathInMp);
62054568cb3Sopenharmony_ci    if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0')) {
62154568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOENT);
62254568cb3Sopenharmony_ci        OsVfsUnlock();
62354568cb3Sopenharmony_ci        return ret;
62454568cb3Sopenharmony_ci    }
62554568cb3Sopenharmony_ci
62654568cb3Sopenharmony_ci    if (mp->mFs->fsFops->mkdir != NULL) {
62754568cb3Sopenharmony_ci        ret = mp->mFs->fsFops->mkdir(mp, pathInMp);
62854568cb3Sopenharmony_ci    } else {
62954568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOTSUP);
63054568cb3Sopenharmony_ci        ret = FS_NOK;
63154568cb3Sopenharmony_ci    }
63254568cb3Sopenharmony_ci
63354568cb3Sopenharmony_ci    OsVfsUnlock();
63454568cb3Sopenharmony_ci    return ret;
63554568cb3Sopenharmony_ci}
63654568cb3Sopenharmony_ci
63754568cb3Sopenharmony_ciS32 OsVfsFcntl(S32 fd, S32 cmd, va_list ap)
63854568cb3Sopenharmony_ci{
63954568cb3Sopenharmony_ci    S32 ret = FS_NOK;
64054568cb3Sopenharmony_ci    U32 flags;
64154568cb3Sopenharmony_ci    struct TagFile *filep = OsVfsAttachFileReady(fd);
64254568cb3Sopenharmony_ci    if (filep == NULL) {
64354568cb3Sopenharmony_ci        return ret;
64454568cb3Sopenharmony_ci    }
64554568cb3Sopenharmony_ci
64654568cb3Sopenharmony_ci    if (filep->fFops == NULL) {
64754568cb3Sopenharmony_ci        VFS_ERRNO_SET(EBADF);
64854568cb3Sopenharmony_ci        OsVfsDetachFile(filep);
64954568cb3Sopenharmony_ci        return ret;
65054568cb3Sopenharmony_ci    }
65154568cb3Sopenharmony_ci
65254568cb3Sopenharmony_ci    if (cmd == F_GETFL) {
65354568cb3Sopenharmony_ci        ret = (S32)(filep->fFlags);
65454568cb3Sopenharmony_ci    } else if (cmd == F_SETFL) {
65554568cb3Sopenharmony_ci        flags = (U32)va_arg(ap, S32);
65654568cb3Sopenharmony_ci        flags &= PRT_FCNTL;
65754568cb3Sopenharmony_ci        filep->fFlags &= ~PRT_FCNTL;
65854568cb3Sopenharmony_ci        filep->fFlags |= flags;
65954568cb3Sopenharmony_ci        ret = FS_OK;
66054568cb3Sopenharmony_ci    } else {
66154568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOSYS);
66254568cb3Sopenharmony_ci    }
66354568cb3Sopenharmony_ci    OsVfsDetachFile(filep);
66454568cb3Sopenharmony_ci    va_end(ap);
66554568cb3Sopenharmony_ci    return ret;
66654568cb3Sopenharmony_ci}
66754568cb3Sopenharmony_ci
66854568cb3Sopenharmony_cissize_t OsVfsPread(S32 fd, void *buff, size_t bytes, off_t off)
66954568cb3Sopenharmony_ci{
67054568cb3Sopenharmony_ci    off_t savepos, pos;
67154568cb3Sopenharmony_ci    ssize_t ret;
67254568cb3Sopenharmony_ci
67354568cb3Sopenharmony_ci    if (buff == NULL) {
67454568cb3Sopenharmony_ci        VFS_ERRNO_SET(EFAULT);
67554568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
67654568cb3Sopenharmony_ci    }
67754568cb3Sopenharmony_ci
67854568cb3Sopenharmony_ci    if (bytes == 0) {
67954568cb3Sopenharmony_ci        return 0;
68054568cb3Sopenharmony_ci    }
68154568cb3Sopenharmony_ci
68254568cb3Sopenharmony_ci    if (OsVfsLock() != FS_OK) {
68354568cb3Sopenharmony_ci        VFS_ERRNO_SET(EAGAIN);
68454568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
68554568cb3Sopenharmony_ci    }
68654568cb3Sopenharmony_ci
68754568cb3Sopenharmony_ci    savepos = lseek(fd, 0, SEEK_CUR);
68854568cb3Sopenharmony_ci    if (savepos == (off_t)-1) {
68954568cb3Sopenharmony_ci        OsVfsUnlock();
69054568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
69154568cb3Sopenharmony_ci    }
69254568cb3Sopenharmony_ci
69354568cb3Sopenharmony_ci    pos = lseek(fd, off, SEEK_SET);
69454568cb3Sopenharmony_ci    if (pos == (off_t)-1) {
69554568cb3Sopenharmony_ci        OsVfsUnlock();
69654568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
69754568cb3Sopenharmony_ci    }
69854568cb3Sopenharmony_ci
69954568cb3Sopenharmony_ci    ret = read(fd, buff, bytes);
70054568cb3Sopenharmony_ci    pos = lseek(fd, savepos, SEEK_SET);
70154568cb3Sopenharmony_ci    if ((pos == (off_t)-1) && (ret >= 0)) {
70254568cb3Sopenharmony_ci        OsVfsUnlock();
70354568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
70454568cb3Sopenharmony_ci    }
70554568cb3Sopenharmony_ci
70654568cb3Sopenharmony_ci    OsVfsUnlock();
70754568cb3Sopenharmony_ci    return ret;
70854568cb3Sopenharmony_ci}
70954568cb3Sopenharmony_ci
71054568cb3Sopenharmony_cissize_t OsVfsPwrite(S32 fd, const void *buff, size_t bytes, off_t off)
71154568cb3Sopenharmony_ci{
71254568cb3Sopenharmony_ci    ssize_t ret;
71354568cb3Sopenharmony_ci    off_t savepos, pos;
71454568cb3Sopenharmony_ci
71554568cb3Sopenharmony_ci    if (buff == NULL) {
71654568cb3Sopenharmony_ci        VFS_ERRNO_SET(EFAULT);
71754568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
71854568cb3Sopenharmony_ci    }
71954568cb3Sopenharmony_ci
72054568cb3Sopenharmony_ci    if (bytes == 0) {
72154568cb3Sopenharmony_ci        return 0;
72254568cb3Sopenharmony_ci    }
72354568cb3Sopenharmony_ci
72454568cb3Sopenharmony_ci    if (OsVfsLock() != FS_OK) {
72554568cb3Sopenharmony_ci        VFS_ERRNO_SET(EAGAIN);
72654568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
72754568cb3Sopenharmony_ci    }
72854568cb3Sopenharmony_ci
72954568cb3Sopenharmony_ci    savepos = lseek(fd, 0, SEEK_CUR);
73054568cb3Sopenharmony_ci    if (savepos == (off_t)-1) {
73154568cb3Sopenharmony_ci        OsVfsUnlock();
73254568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
73354568cb3Sopenharmony_ci    }
73454568cb3Sopenharmony_ci
73554568cb3Sopenharmony_ci    pos = lseek(fd, off, SEEK_SET);
73654568cb3Sopenharmony_ci    if (pos == (off_t)-1) {
73754568cb3Sopenharmony_ci        OsVfsUnlock();
73854568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
73954568cb3Sopenharmony_ci    }
74054568cb3Sopenharmony_ci
74154568cb3Sopenharmony_ci    ret = write(fd, buff, bytes);
74254568cb3Sopenharmony_ci    pos = lseek(fd, savepos, SEEK_SET);
74354568cb3Sopenharmony_ci    if ((pos == (off_t)-1) && (ret >= 0)) {
74454568cb3Sopenharmony_ci        OsVfsUnlock();
74554568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
74654568cb3Sopenharmony_ci    }
74754568cb3Sopenharmony_ci
74854568cb3Sopenharmony_ci    OsVfsUnlock();
74954568cb3Sopenharmony_ci    return ret;
75054568cb3Sopenharmony_ci}
75154568cb3Sopenharmony_ci
75254568cb3Sopenharmony_ciS32 OsVfsFtruncate(S32 fd, off_t length)
75354568cb3Sopenharmony_ci{
75454568cb3Sopenharmony_ci    S32 ret = FS_NOK;
75554568cb3Sopenharmony_ci    struct TagFile *file = NULL;
75654568cb3Sopenharmony_ci
75754568cb3Sopenharmony_ci    if (length <= 0) {
75854568cb3Sopenharmony_ci        VFS_ERRNO_SET(EINVAL);
75954568cb3Sopenharmony_ci        return ret;
76054568cb3Sopenharmony_ci    }
76154568cb3Sopenharmony_ci
76254568cb3Sopenharmony_ci    file = OsVfsAttachFileReady(fd);
76354568cb3Sopenharmony_ci    if (file == NULL) {
76454568cb3Sopenharmony_ci        return ret;
76554568cb3Sopenharmony_ci    }
76654568cb3Sopenharmony_ci
76754568cb3Sopenharmony_ci    if (file->fMp->mWriteEnable == FALSE) {
76854568cb3Sopenharmony_ci        VFS_ERRNO_SET(EACCES);
76954568cb3Sopenharmony_ci        OsVfsDetachFile(file);
77054568cb3Sopenharmony_ci        return ret;
77154568cb3Sopenharmony_ci    }
77254568cb3Sopenharmony_ci
77354568cb3Sopenharmony_ci    if ((file->fFlags & O_ACCMODE) == O_RDONLY) {
77454568cb3Sopenharmony_ci        VFS_ERRNO_SET(EACCES);
77554568cb3Sopenharmony_ci    } else if ((file->fFops != NULL) && (file->fFops->truncate != NULL)) {
77654568cb3Sopenharmony_ci        ret = file->fFops->truncate(file, length);
77754568cb3Sopenharmony_ci    } else {
77854568cb3Sopenharmony_ci        VFS_ERRNO_SET(ENOTSUP);
77954568cb3Sopenharmony_ci    }
78054568cb3Sopenharmony_ci
78154568cb3Sopenharmony_ci    OsVfsDetachFile(file);
78254568cb3Sopenharmony_ci    return ret;
78354568cb3Sopenharmony_ci}
78454568cb3Sopenharmony_ci
78554568cb3Sopenharmony_cissize_t OsVfsReadv(S32 fd, const struct iovec *iovBuf, S32 iovcnt)
78654568cb3Sopenharmony_ci{
78754568cb3Sopenharmony_ci    S32 i;
78854568cb3Sopenharmony_ci    errno_t ret;
78954568cb3Sopenharmony_ci    char *buf = NULL;
79054568cb3Sopenharmony_ci    char *curBuf = NULL;
79154568cb3Sopenharmony_ci    char *readBuf = NULL;
79254568cb3Sopenharmony_ci    size_t bufLen = 0;
79354568cb3Sopenharmony_ci    size_t bytesToRead;
79454568cb3Sopenharmony_ci    ssize_t totalBytesRead;
79554568cb3Sopenharmony_ci    size_t totalLen;
79654568cb3Sopenharmony_ci    const struct iovec *iov = (const struct iovec *)iovBuf;
79754568cb3Sopenharmony_ci
79854568cb3Sopenharmony_ci    if ((iov == NULL) || (iovcnt <= 0) || (iovcnt > IOV_MAX_CNT)) {
79954568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
80054568cb3Sopenharmony_ci    }
80154568cb3Sopenharmony_ci
80254568cb3Sopenharmony_ci    for (i = 0; i < iovcnt; ++i) {
80354568cb3Sopenharmony_ci        if ((SSIZE_MAX - bufLen) < iov[i].iov_len) {
80454568cb3Sopenharmony_ci            return (ssize_t)FS_NOK;
80554568cb3Sopenharmony_ci        }
80654568cb3Sopenharmony_ci        bufLen += iov[i].iov_len;
80754568cb3Sopenharmony_ci    }
80854568cb3Sopenharmony_ci    if (bufLen == 0) {
80954568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
81054568cb3Sopenharmony_ci    }
81154568cb3Sopenharmony_ci    totalLen = bufLen * sizeof(char);
81254568cb3Sopenharmony_ci    buf = (char *)malloc(totalLen);
81354568cb3Sopenharmony_ci    if (buf == NULL) {
81454568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
81554568cb3Sopenharmony_ci    }
81654568cb3Sopenharmony_ci
81754568cb3Sopenharmony_ci    totalBytesRead = read(fd, buf, bufLen);
81854568cb3Sopenharmony_ci    if ((size_t)totalBytesRead < totalLen) {
81954568cb3Sopenharmony_ci        totalLen = (size_t)totalBytesRead;
82054568cb3Sopenharmony_ci    }
82154568cb3Sopenharmony_ci    curBuf = buf;
82254568cb3Sopenharmony_ci    for (i = 0; i < iovcnt; ++i) {
82354568cb3Sopenharmony_ci        readBuf = (char *)iov[i].iov_base;
82454568cb3Sopenharmony_ci        bytesToRead = iov[i].iov_len;
82554568cb3Sopenharmony_ci
82654568cb3Sopenharmony_ci        size_t lenToRead = totalLen < bytesToRead ? totalLen : bytesToRead;
82754568cb3Sopenharmony_ci        ret = memcpy_s(readBuf, bytesToRead, curBuf, lenToRead);
82854568cb3Sopenharmony_ci        if (ret != EOK) {
82954568cb3Sopenharmony_ci            free(buf);
83054568cb3Sopenharmony_ci            return (ssize_t)FS_NOK;
83154568cb3Sopenharmony_ci        }
83254568cb3Sopenharmony_ci        if (totalLen < (size_t)bytesToRead) {
83354568cb3Sopenharmony_ci            break;
83454568cb3Sopenharmony_ci        }
83554568cb3Sopenharmony_ci        curBuf += bytesToRead;
83654568cb3Sopenharmony_ci        totalLen -= bytesToRead;
83754568cb3Sopenharmony_ci    }
83854568cb3Sopenharmony_ci    free(buf);
83954568cb3Sopenharmony_ci    return totalBytesRead;
84054568cb3Sopenharmony_ci}
84154568cb3Sopenharmony_ci
84254568cb3Sopenharmony_cissize_t OsVfsWritev(S32 fd, const struct iovec *iovBuf, S32 iovcnt)
84354568cb3Sopenharmony_ci{
84454568cb3Sopenharmony_ci    S32 i;
84554568cb3Sopenharmony_ci    errno_t ret;
84654568cb3Sopenharmony_ci    char *buf = NULL;
84754568cb3Sopenharmony_ci    char *curBuf = NULL;
84854568cb3Sopenharmony_ci    char *writeBuf = NULL;
84954568cb3Sopenharmony_ci    size_t bufLen = 0;
85054568cb3Sopenharmony_ci    size_t bytesToWrite;
85154568cb3Sopenharmony_ci    ssize_t totalBytesWritten;
85254568cb3Sopenharmony_ci    size_t totalLen;
85354568cb3Sopenharmony_ci    const struct iovec *iov = iovBuf;
85454568cb3Sopenharmony_ci
85554568cb3Sopenharmony_ci    if ((iov == NULL) || (iovcnt <= 0) || (iovcnt > IOV_MAX_CNT)) {
85654568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
85754568cb3Sopenharmony_ci    }
85854568cb3Sopenharmony_ci
85954568cb3Sopenharmony_ci    for (i = 0; i < iovcnt; ++i) {
86054568cb3Sopenharmony_ci        if ((SSIZE_MAX - bufLen) < iov[i].iov_len) {
86154568cb3Sopenharmony_ci            VFS_ERRNO_SET(EINVAL);
86254568cb3Sopenharmony_ci            return (ssize_t)FS_NOK;
86354568cb3Sopenharmony_ci        }
86454568cb3Sopenharmony_ci        bufLen += iov[i].iov_len;
86554568cb3Sopenharmony_ci    }
86654568cb3Sopenharmony_ci    if (bufLen == 0) {
86754568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
86854568cb3Sopenharmony_ci    }
86954568cb3Sopenharmony_ci    totalLen = bufLen * sizeof(char);
87054568cb3Sopenharmony_ci    buf = (char *)malloc(totalLen);
87154568cb3Sopenharmony_ci    if (buf == NULL) {
87254568cb3Sopenharmony_ci        return (ssize_t)FS_NOK;
87354568cb3Sopenharmony_ci    }
87454568cb3Sopenharmony_ci    curBuf = buf;
87554568cb3Sopenharmony_ci    for (i = 0; i < iovcnt; ++i) {
87654568cb3Sopenharmony_ci        writeBuf = (char *)iov[i].iov_base;
87754568cb3Sopenharmony_ci        bytesToWrite = iov[i].iov_len;
87854568cb3Sopenharmony_ci        if (((ssize_t)totalLen <= 0) || ((ssize_t)bytesToWrite <= 0)) {
87954568cb3Sopenharmony_ci            continue;
88054568cb3Sopenharmony_ci        }
88154568cb3Sopenharmony_ci        ret = memcpy_s(curBuf, totalLen, writeBuf, bytesToWrite);
88254568cb3Sopenharmony_ci        if (ret != EOK) {
88354568cb3Sopenharmony_ci            free(buf);
88454568cb3Sopenharmony_ci            return (ssize_t)FS_NOK;
88554568cb3Sopenharmony_ci        }
88654568cb3Sopenharmony_ci        curBuf += bytesToWrite;
88754568cb3Sopenharmony_ci        totalLen -= bytesToWrite;
88854568cb3Sopenharmony_ci    }
88954568cb3Sopenharmony_ci
89054568cb3Sopenharmony_ci    totalBytesWritten = write(fd, buf, bufLen);
89154568cb3Sopenharmony_ci    free(buf);
89254568cb3Sopenharmony_ci
89354568cb3Sopenharmony_ci    return totalBytesWritten;
89454568cb3Sopenharmony_ci}
895