From 491cefae76cc41ad7769675d1fe2a02f416f405f Mon Sep 17 00:00:00 2001 From: arvinzzz Date: Thu, 24 Feb 2022 17:10:50 +0800 Subject: [PATCH] =?UTF-8?q?feature:=20=E8=A1=A5=E5=85=85pread/pwrite?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: arvinzzz Change-Id: Ie31cacd18131113e51a6949dfba57a86ca4eb0e5 --- components/fs/fatfs/fatfs.c | 106 ++++++++++++++++++++++++++++++ components/fs/fatfs/fatfs.h | 2 + components/fs/littlefs/lfs_api.c | 86 ++++++++++++++++++++++++ components/fs/littlefs/lfs_api.h | 2 + components/fs/vfs/fs_operations.h | 2 + components/fs/vfs/los_fs.c | 52 +++++++++++++++ components/fs/vfs/los_fs.h | 4 ++ kal/libc/musl/fs.c | 10 +++ kal/libc/newlib/porting/src/fs.c | 10 +++ 9 files changed, 274 insertions(+) diff --git a/components/fs/fatfs/fatfs.c b/components/fs/fatfs/fatfs.c index 02e4f245..48365d98 100644 --- a/components/fs/fatfs/fatfs.c +++ b/components/fs/fatfs/fatfs.c @@ -1475,6 +1475,110 @@ OUT: return ret; } +ssize_t fatfs_pread(int fd, void *buf, size_t nbyte, off_t offset) +{ + INT32 ret; + off_t savepos, pos; + + if (buf == NULL) { + errno = EFAULT; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + if (!IsValidFd(fd)) { + FsUnlock(); + errno = EBADF; + return FS_FAILURE; + } + + savepos = (off_t)fatfs_lseek(fd, 0, SEEK_CUR); + if (savepos == (off_t)-1) { + errno = FatfsErrno(savepos); + return FS_FAILURE; + } + + pos = (off_t)fatfs_lseek(fd, offset, SEEK_SET); + if (pos == (off_t)-1) { + errno = FatfsErrno(pos); + return FS_FAILURE; + } + + ret = fatfs_read(fd, buf, nbyte); + if (ret < 0) { + FsUnlock(); + errno = FatfsErrno(ret); + return FS_FAILURE; + } + + pos = (off_t)fatfs_lseek(fd, savepos, SEEK_SET); + if ((pos == (off_t)-1) && (ret >= 0)) { + errno = FatfsErrno(pos); + return FS_FAILURE; + } + + FsUnlock(); + + return (ssize_t)ret; +} + +ssize_t fatfs_pwrite(int fd, const void *buf, size_t nbyte, off_t offset) +{ + INT32 ret; + off_t savepos, pos; + + if (buf == NULL) { + errno = EFAULT; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + if (!IsValidFd(fd)) { + FsUnlock(); + errno = EBADF; + return FS_FAILURE; + } + + savepos = (off_t)fatfs_lseek(fd, 0, SEEK_CUR); + if (savepos == (off_t)-1) { + errno = FatfsErrno(savepos); + return FS_FAILURE; + } + + pos = (off_t)fatfs_lseek(fd, offset, SEEK_SET); + if (pos == (off_t)-1) { + errno = FatfsErrno(pos); + return FS_FAILURE; + } + + ret = fatfs_write(fd, buf, nbyte); + if (ret < 0) { + FsUnlock(); + errno = FatfsErrno(ret); + return FS_FAILURE; + } + + pos = (off_t)fatfs_lseek(fd, savepos, SEEK_SET); + if ((pos == (off_t)-1) && (ret >= 0)) { + errno = FatfsErrno(pos); + return FS_FAILURE; + } + + FsUnlock(); + + return (ssize_t)ret; +} + struct MountOps g_fatfsMnt = { .Mount = fatfs_mount, .Umount = fatfs_umount, @@ -1498,4 +1602,6 @@ struct FileOps g_fatfsFops = { .Getattr = fatfs_stat, .Fsync = fatfs_fsync, .Fstat = fatfs_fstat, + .Pread = fatfs_pread, + .Pwrite = fatfs_pwrite, }; diff --git a/components/fs/fatfs/fatfs.h b/components/fs/fatfs/fatfs.h index 6c92fde8..05672a16 100644 --- a/components/fs/fatfs/fatfs.h +++ b/components/fs/fatfs/fatfs.h @@ -69,6 +69,8 @@ int fatfs_rmdir(const char *path); int fatfs_rename(const char *oldName, const char *newName); int fatfs_statfs(const char *path, struct statfs *buf); int fatfs_ftruncate(int fd, off_t length); +ssize_t fatfs_pread(int fd, void *buf, size_t nbyte, off_t offset); +ssize_t fatfs_pwrite(int fd, const void *buf, size_t nbyte, off_t offset); /** * @brief divide a physical drive (SD card, U disk, and MMC card), this function is OHOS-specific diff --git a/components/fs/littlefs/lfs_api.c b/components/fs/littlefs/lfs_api.c index bc11c6d2..5c3e21cb 100644 --- a/components/fs/littlefs/lfs_api.c +++ b/components/fs/littlefs/lfs_api.c @@ -323,6 +323,8 @@ const struct FileOps g_lfsFops = { .Getattr = LfsStat, .Fsync = LfsFsync, .Fstat = LfsFstat, + .Pread = LfsPread, + .Pwrite = LfsPwrite, }; int LfsMount(const char *source, const char *target, const char *fileSystemType, unsigned long mountflags, @@ -801,5 +803,89 @@ int LfsFstat(int fd, struct stat *buf) errno = LittlefsErrno(ret); ret = VFS_ERROR; } + return ret; +} + +int LfsPread(int fd, void *buf, size_t nbyte, off_t offset) +{ + int ret; + off_t savepos, pos; + + if (buf == NULL) { + errno = EFAULT; + return VFS_ERROR; + } + + if (LfsFdIsValid(fd) == FALSE) { + errno = EBADF; + return VFS_ERROR; + } + + savepos = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), 0, SEEK_CUR); + if (savepos == (off_t)-1) { + errno = LittlefsErrno(savepos); + return VFS_ERROR; + } + + pos = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), offset, SEEK_SET); + if (pos == (off_t)-1) { + errno = LittlefsErrno(pos); + return VFS_ERROR; + } + + ret = lfs_file_read(g_handle[fd].lfsHandle, &(g_handle[fd].file), buf, nbyte); + if (ret < 0) { + errno = LittlefsErrno(ret); + ret = VFS_ERROR; + } + + pos = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), savepos, SEEK_SET); + if ((pos == (off_t)-1) && (ret >= 0)) { + errno = LittlefsErrno(pos); + return VFS_ERROR; + } + + return ret; +} + +int LfsPwrite(int fd, const void *buf, size_t nbyte, off_t offset) +{ + int ret; + off_t savepos, pos; + + if (buf == NULL) { + errno = EFAULT; + return VFS_ERROR; + } + + if (LfsFdIsValid(fd) == FALSE) { + errno = EBADF; + return VFS_ERROR; + } + + savepos = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), 0, SEEK_CUR); + if (savepos == (off_t)-1) { + errno = LittlefsErrno(savepos); + return VFS_ERROR; + } + + pos = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), offset, SEEK_SET); + if (pos == (off_t)-1) { + errno = LittlefsErrno(pos); + return VFS_ERROR; + } + + ret = lfs_file_write(g_handle[fd].lfsHandle, &(g_handle[fd].file), buf, nbyte); + if (ret < 0) { + errno = LittlefsErrno(ret); + ret = VFS_ERROR; + } + + pos = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), savepos, SEEK_SET); + if ((pos == (off_t)-1) && (ret >= 0)) { + errno = LittlefsErrno(pos); + return VFS_ERROR; + } + return ret; } \ No newline at end of file diff --git a/components/fs/littlefs/lfs_api.h b/components/fs/littlefs/lfs_api.h index 8776f49d..2258efbc 100644 --- a/components/fs/littlefs/lfs_api.h +++ b/components/fs/littlefs/lfs_api.h @@ -97,6 +97,8 @@ int LfsStat(const char *path, struct stat *buf); int LfsFsync(int fd); int LfsFstat(int fd, struct stat *buf); int SetDefaultMountPath(int pathNameIndex, const char* target); +int LfsPread(int fd, void *buf, size_t nbyte, off_t offset); +int LfsPwrite(int fd, const void *buf, size_t nbyte, off_t offset); #endif /* _LFS_API_H_ */ diff --git a/components/fs/vfs/fs_operations.h b/components/fs/vfs/fs_operations.h index e22be283..f0acfdf6 100644 --- a/components/fs/vfs/fs_operations.h +++ b/components/fs/vfs/fs_operations.h @@ -75,6 +75,8 @@ struct FileOps { int (*Fstat)(int fd, struct stat *buf); int (*Stat)(const char *path, struct stat *buf); int (*Ftruncate)(int fd, off_t length); + int (*Pread)(int fd, void *buf, size_t nbyte, off_t offset); + int (*Pwrite)(int fd, const void *buf, size_t nbyte, off_t offset); }; #endif /* _FS_OPERATIONS_H_ */ diff --git a/components/fs/vfs/los_fs.c b/components/fs/vfs/los_fs.c index c3987758..5fb95380 100644 --- a/components/fs/vfs/los_fs.c +++ b/components/fs/vfs/los_fs.c @@ -595,3 +595,55 @@ int LOS_Ftruncate(int fd, off_t length) } return g_fs->fsFops->Ftruncate(fd, length); } + +ssize_t LOS_Pread(int fd, void *buf, size_t nbyte, off_t offset) +{ +#ifdef LOSCFG_RANDOM_DEV + if (fd == RANDOM_DEV_FD) { + if (nbyte == 0) { + return FS_SUCCESS; + } + if (buf == NULL) { + errno = EINVAL; + return FS_FAILURE; + } + if (nbyte > 1024) { /* 1024, max random_size */ + nbyte = 1024; /* hks_generate_random: random_size must <= 1024 */ + } + struct hks_blob key = {HKS_BLOB_TYPE_RAW, (uint8_t *)buf, nbyte}; + if (hks_generate_random(&key) != 0) { + errno = EIO; + return FS_FAILURE; + } + return (ssize_t)nbyte; + } +#endif + if (g_fs == NULL) { + errno = ENODEV; + return FS_FAILURE; + } + if (g_fs->fsFops == NULL || g_fs->fsFops->Pread == NULL) { + errno = ENOSYS; + return FS_FAILURE; + } + return g_fs->fsFops->Pread(fd, buf, nbyte, offset); +} + +ssize_t LOS_Pwrite(int fd, const void *buf, size_t nbyte, off_t offset) +{ +#ifdef LOSCFG_RANDOM_DEV + if (fd == RANDOM_DEV_FD) { + errno = EBADF; /* "/dev/random" is readonly */ + return FS_FAILURE; + } +#endif + if (g_fs == NULL) { + errno = ENODEV; + return FS_FAILURE; + } + if (g_fs->fsFops == NULL || g_fs->fsFops->Pwrite == NULL) { + errno = ENOSYS; + return FS_FAILURE; + } + return g_fs->fsFops->Pwrite(fd, buf, nbyte, offset); +} diff --git a/components/fs/vfs/los_fs.h b/components/fs/vfs/los_fs.h index 530673ea..7cbca811 100644 --- a/components/fs/vfs/los_fs.h +++ b/components/fs/vfs/los_fs.h @@ -92,6 +92,10 @@ int LOS_FsMount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *data); +ssize_t LOS_Pread(int fd, void *buf, size_t nbyte, off_t offset); + +ssize_t LOS_Pwrite(int fd, const void *buf, size_t nbyte, off_t offset); + #ifdef __cplusplus #if __cplusplus extern "C" { diff --git a/kal/libc/musl/fs.c b/kal/libc/musl/fs.c index 4de67492..e6e19716 100644 --- a/kal/libc/musl/fs.c +++ b/kal/libc/musl/fs.c @@ -144,3 +144,13 @@ int ftruncate(int fd, off_t length) { return LOS_Ftruncate(fd, length); } + +ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset) +{ + return LOS_Pread(fd, buf, nbyte, offset); +} + +ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset) +{ + return LOS_Pwrite(fd, buf, nbyte, offset); +} diff --git a/kal/libc/newlib/porting/src/fs.c b/kal/libc/newlib/porting/src/fs.c index c022049d..b8acfad7 100644 --- a/kal/libc/newlib/porting/src/fs.c +++ b/kal/libc/newlib/porting/src/fs.c @@ -147,6 +147,16 @@ int ioctl(int fd, int req, ...) return -1; } +ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset) +{ + return LOS_Pread(fd, buf, nbyte, offset); +} + +ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset) +{ + return LOS_Pwrite(fd, buf, nbyte, offset); +} + #else /* #ifdef LOSCFG_FS_VFS */ int _open(const char *path, int oflag, ...)