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