Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

io: use fios2 #90

Draft
wants to merge 9 commits into
base: vita
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions newlib/libc/sys/vita/dirent.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ DEALINGS IN THE SOFTWARE.
#include <psp2/types.h>
#include <psp2/io/dirent.h>
#include <psp2/kernel/threadmgr.h>
#include "fios2.h"
#include "vitadescriptor.h"
#include "vitaerror.h"

Expand Down Expand Up @@ -135,8 +136,8 @@ struct dirent *readdir(DIR *dirp)
return NULL;
}

int res = sceIoDread(fdmap->sce_uid, (SceIoDirent *)&dirp->dir);

SceFiosDirEntry fios_dir_entry = {0};
int res = sceFiosDHReadSync(NULL, fdmap->sce_uid, &fios_dir_entry);
__vita_fd_drop(fdmap);

if (res < 0)
Expand All @@ -145,12 +146,25 @@ struct dirent *readdir(DIR *dirp)
return NULL;
}

if (res == 0)
//TODO end of listing

SceFiosStat fios_stat = {0};
res = sceFiosStatSync(NULL, fios_dir_entry.fullPath, &fios_stat);

if (res < 0)
{
// end-of-listing shouldn't change errno
errno = __vita_sce_errno_to_errno(res, ERROR_GENERIC);
return NULL;
}

strncpy(dirp->dir.d_name, fios_dir_entry.fullPath + fios_dir_entry.offsetToName, 256);
dirp->dir.d_stat.st_mode = fios_stat.st_mode;
dirp->dir.d_stat.st_attr = fios_stat.statFlags;
dirp->dir.d_stat.st_size = fios_stat.st_size;
sceFiosDateToSceDateTime(fios_stat.st_ctime, &dirp->dir.d_stat.st_ctime);
sceFiosDateToSceDateTime(fios_stat.st_atime, &dirp->dir.d_stat.st_atime);
sceFiosDateToSceDateTime(fios_stat.st_mtime, &dirp->dir.d_stat.st_mtime);

struct dirent *dir = &dirp->dir;
dirp->index++;
return dir;
Expand All @@ -173,16 +187,18 @@ void rewinddir(DIR *dirp)
return;
}

SceUID dirfd = sceIoDopen(fdmap->filename); // filename contains full path, so it's okay to use in sce funcs
SceFiosDH dirfd;
SceFiosBuffer buf = SCE_FIOS_BUFFER_INITIALIZER;
int res = sceFiosDHOpenSync(NULL, &dirfd, fdmap->filename, buf); // filename contains full path, so it's okay to use in sce funcs

if (dirfd < 0)
if (res < 0)
{
__vita_fd_drop(fdmap);
errno = __vita_sce_errno_to_errno(dirfd, ERROR_GENERIC);
return;
}

sceIoDclose(fdmap->sce_uid);
sceFiosDHCloseSync(NULL, fdmap->sce_uid);
fdmap->sce_uid = dirfd;
__vita_fd_drop(fdmap);

Expand Down
182 changes: 182 additions & 0 deletions newlib/libc/sys/vita/fios2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
#ifndef __FIOS2_H__
#define __FIOS2_H__

#include <psp2/rtc.h>

#define SCE_FIOS_OK 0

#define SCE_FIOS_TIME_NULL ((SceFiosTime)0)
#define SCE_FIOS_TIME_EARLIEST ((SceFiosTime)1)
#define SCE_FIOS_TIME_LATEST ((SceFiosTime)0x7FFFFFFFFFFFFFFFLL)

#define SCE_FIOS_PRIO_MIN ((int8_t)-128)
#define SCE_FIOS_PRIO_DEFAULT ((int8_t)0)
#define SCE_FIOS_PRIO_MAX ((int8_t)127)

#define SCE_FIOS_FH_SIZE 80
#define SCE_FIOS_DH_SIZE 80
#define SCE_FIOS_OP_SIZE 168
#define SCE_FIOS_CHUNK_SIZE 64

#define SCE_FIOS_ALIGN_UP(val, align) (((val) + ((align) - 1)) & ~((align) - 1))
#define SCE_FIOS_STORAGE_SIZE(num, size) (((num) * (size)) + SCE_FIOS_ALIGN_UP(SCE_FIOS_ALIGN_UP((num), 8) / 8, 8))

#define SCE_FIOS_DH_STORAGE_SIZE(numDHs, pathMax) SCE_FIOS_STORAGE_SIZE(numDHs, SCE_FIOS_DH_SIZE + pathMax)
#define SCE_FIOS_FH_STORAGE_SIZE(numFHs, pathMax) SCE_FIOS_STORAGE_SIZE(numFHs, SCE_FIOS_FH_SIZE + pathMax)
#define SCE_FIOS_OP_STORAGE_SIZE(numOps, pathMax) SCE_FIOS_STORAGE_SIZE(numOps, SCE_FIOS_OP_SIZE + pathMax)
#define SCE_FIOS_CHUNK_STORAGE_SIZE(numChunks) SCE_FIOS_STORAGE_SIZE(numChunks, SCE_FIOS_CHUNK_SIZE)

#define SCE_FIOS_BUFFER_INITIALIZER { 0, 0 }
#define SCE_FIOS_PARAMS_INITIALIZER { 0, sizeof(SceFiosParams), 0, 0, 2, 1, 0, 0, 256 * 1024, 2, 0, 0, 0, 0, 0, SCE_FIOS_BUFFER_INITIALIZER, SCE_FIOS_BUFFER_INITIALIZER, SCE_FIOS_BUFFER_INITIALIZER, SCE_FIOS_BUFFER_INITIALIZER, NULL, NULL, NULL, { 66, 189, 66 }, { 0x40000, 0, 0x40000}, { 8 * 1024, 16 * 1024, 8 * 1024}}
#define SCE_FIOS_OPENPARAMS_INITIALIZER { 0, 0, 0, SCE_FIOS_BUFFER_INITIALIZER }
#define SCE_FIOS_OPATTR_INITIALIZER { 0, 0, 0, 0, 0, 0, 0, 0 }
#define SCE_FIOS_RAM_CACHE_CONTEXT_INITIALIZER { sizeof(SceFiosRamCacheContext), 0, (64 * 1024), NULL, NULL, 0, {0, 0, 0} }

typedef enum SceFiosWhence {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those should go in headers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know

SCE_FIOS_SEEK_SET = 0,
SCE_FIOS_SEEK_CUR = 1,
SCE_FIOS_SEEK_END = 2
} SceFiosWhence;

typedef enum SceFiosOpenFlags {
SCE_FIOS_O_RDONLY = (1 << 0),
SCE_FIOS_O_WRONLY = (1 << 1),
SCE_FIOS_O_RDWR = (SCE_FIOS_O_RDONLY | SCE_FIOS_O_WRONLY),
SCE_FIOS_O_APPEND = (1 << 2),
SCE_FIOS_O_CREAT = (1 << 3),
SCE_FIOS_O_TRUNC = (1 << 4),
} SceFiosOpenFlags;

typedef int64_t SceFiosTime;

typedef int32_t SceFiosFH;
typedef int32_t SceFiosDH;
typedef uint64_t SceFiosDate;
typedef int64_t SceFiosOffset;
typedef int64_t SceFiosSize;

typedef struct SceFiosBuffer {
void *pPtr;
size_t length;
} SceFiosBuffer;

typedef struct SceFiosOpAttr {
SceFiosTime deadline;
void *pCallback;
void *pCallbackContext;
int32_t priority : 8;
uint32_t opflags : 24;
uint32_t userTag;
void *userPtr;
void *pReserved;
} SceFiosOpAttr;

typedef struct SceFiosRamCacheContext {
size_t sizeOfContext;
size_t workBufferSize;
size_t blockSize;
void *pWorkBuffer;
const char *pPath;
intptr_t flags;
intptr_t reserved[3];
} SceFiosRamCacheContext;
Comment on lines +74 to +82
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use snake_case instead of camelCase?
eg;

  • pPtr -> ptr
  • pCallback -> callback
  • pCallbackContext -> callback_context
  • userTag -> user_tag or just tag
  • userPtr -> user_ptr or just user
  • pReserved -> reserved
  • sizeOfContext -> size_of_context
  • workBufferSize -> work_buffer_size, work_buf_size or buf_size
  • blockSize -> block_size
  • pWorkBuffer -> work_buffer, buffer or just buf
  • ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no problem. I'm still reversing some of the stuff and these are leftovers from vitashell.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TheOfficialFloW can you allow changing the license to LGPL or others?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes


typedef struct SceFiosOpenParams {
uint32_t openFlags : 16;
uint32_t opFlags : 16;
uint32_t reserved;
SceFiosBuffer buffer;
} SceFiosOpenParams;

typedef struct SceFiosParams {
uint32_t initialized : 1;
uint32_t paramsSize : 15;
uint32_t pathMax : 16;
uint32_t profiling;
uint32_t ioThreadCount;
uint32_t threadsPerScheduler;
uint32_t extraFlag1 : 1;
uint32_t extraFlags : 31;
uint32_t maxChunk;
uint8_t maxDecompressorThreadCount;
uint8_t reserved1;
uint8_t reserved2;
uint8_t reserved3;
intptr_t reserved4;
intptr_t reserved5;
SceFiosBuffer opStorage;
SceFiosBuffer fhStorage;
SceFiosBuffer dhStorage;
SceFiosBuffer chunkStorage;
void *pVprintf;
void *pMemcpy;
void *pProfileCallback;
int threadPriority[3];
int threadAffinity[3];
int threadStackSize[3];
} SceFiosParams;

typedef struct SceFiosStat {
SceFiosOffset st_size;
SceFiosDate st_atime;
SceFiosDate st_mtime;
SceFiosDate st_ctime;
uint32_t statFlags;
uint32_t reserved;
int64_t uid;
int64_t gid;
int64_t dev;
int64_t ino;
int64_t st_mode;
} SceFiosStat;

typedef struct SceFiosDirEntry {
SceFiosOffset fileSize;
uint32_t statFlags;
uint16_t nameLength;
uint16_t fullPathLength;
uint16_t offsetToName;
uint16_t reserved[3];
char fullPath[1024];
} SceFiosDirEntry;

int sceFiosInitialize(const SceFiosParams *params);
void sceFiosTerminate();

int sceFiosRenameSync(const SceFiosOpAttr *attr, const char *old_path, const char *new_path);
int sceFiosDeleteSync(const SceFiosOpAttr *attr, const char *path);

int sceFiosFHOpenSync(const SceFiosOpAttr *attr, SceFiosFH *fh, const char *path, const void *params);
SceFiosSize sceFiosFHReadSync(const SceFiosOpAttr *attr, SceFiosFH fh, void *data, SceFiosSize size);
SceFiosSize sceFiosFHPreadSync(const SceFiosOpAttr *attr, SceFiosFH fh, void *data, SceFiosSize size, SceFiosOffset offset);
SceFiosSize sceFiosFHPwriteSync(const SceFiosOpAttr *attr, SceFiosFH fh, const void *data, SceFiosSize size, SceFiosOffset offset);
SceFiosSize sceFiosFHWriteSync(const SceFiosOpAttr *attr, SceFiosFH fh, const void *data, SceFiosSize size);
int sceFiosFHCloseSync(const SceFiosOpAttr *attr, SceFiosFH fh);
int sceFiosFHSyncSync(const SceFiosOpAttr *attr, SceFiosFH fh);

SceFiosOffset sceFiosFHSeek(SceFiosFH fh, SceFiosOffset offset, SceFiosWhence whence);
SceFiosOffset sceFiosFHTell(SceFiosFH fh);
SceFiosSize sceFiosFHGetSize(SceFiosFH fh);

int sceFiosStatSync(const SceFiosOpAttr *attr, const char *path, SceFiosStat *stat);
int sceFiosChangeStatSync(const SceFiosOpAttr *attr, const char *path, SceFiosStat *stat, int bits);
int sceFiosFHStatSync(const SceFiosOpAttr *attr, SceFiosFH fh, SceFiosStat *stat);

int sceFiosFHTruncateSync(const SceFiosOpAttr *attr, SceFiosFH fh, SceFiosSize size);
int sceFiosFileTruncateSync(const SceFiosOpAttr *attr, const char *path, SceFiosSize size);

int sceFiosDirectoryCreateSync(const SceFiosOpAttr *attr, const char *path);
int sceFiosDirectoryDeleteSync(const SceFiosOpAttr *attr, const char *path);
int sceFiosDHOpenSync(const SceFiosOpAttr *attr, SceFiosDH *dh, const char *path, SceFiosBuffer buffer);
int sceFiosDHReadSync(const SceFiosOpAttr *attr, SceFiosDH dh, SceFiosDirEntry *dir);
int sceFiosDHCloseSync(const SceFiosOpAttr *attr, SceFiosDH dh);

int sceFiosSyncSync(const SceFiosOpAttr *attr, const char* path, int flag);
int sceFiosDevctlSync(const SceFiosOpAttr *attr, const char *dev, unsigned int cmd, void *indata, int inlen, void *outdata, int outlen);

int sceFiosIOFilterAdd(int index, void *pFilterCallback, void *pFilterContext);
void sceFiosIOFilterCache();

SceDateTime *sceFiosDateToSceDateTime(SceFiosDate date, SceDateTime *sce_date);

#endif
38 changes: 22 additions & 16 deletions newlib/libc/sys/vita/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ DEALINGS IN THE SOFTWARE.
#include <psp2/io/stat.h>
#include <psp2/io/fcntl.h>
#include <psp2/io/devctl.h>
#include "fios2.h"
#include "vitaerror.h"
#include "vitadescriptor.h"
#include "vitafs.h"
Expand All @@ -60,7 +61,7 @@ int rmdir(const char *pathname)
return -1;
}

if ((ret = sceIoRmdir(full_path)) < 0)
if ((ret = sceFiosDirectoryDeleteSync(NULL, full_path)) < 0)
{
free(full_path);
errno = __vita_sce_errno_to_errno(ret, ERROR_GENERIC);
Expand All @@ -78,14 +79,14 @@ int lstat(const char *path, struct stat *buf)

int chmod(const char *pathname, mode_t mode)
{
struct SceIoStat stat = {0};
struct SceFiosStat stat = {0};
char* full_path = __realpath(pathname);
if(!full_path)
{
// errno is set by __realpath
return -1;
}
int ret = sceIoGetstat(full_path, &stat);
int ret = sceFiosStatSync(NULL, full_path, &stat);
if (ret < 0)
{
free(full_path);
Expand All @@ -94,7 +95,7 @@ int chmod(const char *pathname, mode_t mode)
}

stat.st_mode = mode;
ret = sceIoChstat(full_path, &stat, SCE_CST_MODE);
ret = sceFiosChangeStatSync(NULL, full_path, &stat, SCE_CST_MODE);
if (ret < 0)
{
free(full_path);
Expand All @@ -121,10 +122,13 @@ int fchmod(int fd, mode_t mode)
switch (fdmap->type)
{
case VITA_DESCRIPTOR_TTY:
case VITA_DESCRIPTOR_FILE:
case VITA_DESCRIPTOR_DIRECTORY:
ret = sceIoGetstatByFd(fdmap->sce_uid, &stat);
break;
case VITA_DESCRIPTOR_FILE:
case VITA_DESCRIPTOR_DIRECTORY:
ret = chmod(fdmap->filename, mode);
__vita_fd_drop(fdmap);
return ret;
case VITA_DESCRIPTOR_SOCKET:
case VITA_DESCRIPTOR_PIPE:
ret = __vita_make_sce_errno(EBADF);
Expand Down Expand Up @@ -156,15 +160,15 @@ int chown(const char *path, uid_t owner, gid_t group)
{
// Implementation note: there's no real chown on vita
// We only check for path correctness
struct SceIoStat stat = {0};
struct SceFiosStat stat = {0};
char* full_path = __realpath(path);
if(!full_path)
{
// errno is set by __realpath
return -1;
}

int ret = sceIoGetstat(full_path, &stat);
int ret = sceFiosStatSync(NULL, full_path, &stat);
if (ret < 0)
{
free(full_path);
Expand All @@ -180,7 +184,7 @@ int fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag)
{
// Implementation note: there's no real chown on vita
// We only check for path correctness
struct SceIoStat stat = {0};
struct SceFiosStat stat = {0};
int ret = 0;

DescriptorTranslation *fdmap = __vita_fd_grab(fd);
Expand All @@ -195,7 +199,7 @@ int fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag)
{
case VITA_DESCRIPTOR_FILE:
case VITA_DESCRIPTOR_DIRECTORY:
ret = sceIoGetstatByFd(fdmap->sce_uid, &stat);
ret = sceFiosStatSync(NULL, fdmap->filename, &stat);
break;
case VITA_DESCRIPTOR_TTY:
case VITA_DESCRIPTOR_SOCKET:
Expand Down Expand Up @@ -229,8 +233,10 @@ int fsync(int fd)
switch (fdmap->type)
{
case VITA_DESCRIPTOR_DIRECTORY:
ret = sceFiosSyncSync(NULL, fdmap->filename, 0);
break;
case VITA_DESCRIPTOR_FILE:
ret = sceIoSyncByFd(fdmap->sce_uid, 0);
ret = sceFiosFHSyncSync(NULL, fdmap->sce_uid);
break;
case VITA_DESCRIPTOR_TTY:
case VITA_DESCRIPTOR_SOCKET:
Expand Down Expand Up @@ -495,8 +501,8 @@ char *__realpath(const char *path)

int __is_dir(const char *path)
{
SceIoStat stat;
int ret = sceIoGetstat(path, &stat);
SceFiosStat stat;
int ret = sceFiosStatSync(NULL, path, &stat);
if (ret < 0)
{
return ret;
Expand All @@ -516,8 +522,8 @@ char *realpath(const char *path, char* resolved_path)
return NULL; // errno already set
}

SceIoStat stat;
int ret = sceIoGetstat(fullpath, &stat);
SceFiosStat stat;
int ret = sceFiosStatSync(NULL, fullpath, &stat);
if (ret < 0)
{
free(fullpath);
Expand Down Expand Up @@ -617,7 +623,7 @@ int statvfs(const char *__path, struct statvfs *__buf)

SceIoDevInfo info;
memset(&info, 0, sizeof(SceIoDevInfo));
int ret = sceIoDevctl(drive, 0x3001, NULL, 0, &info, sizeof(SceIoDevInfo));
int ret = sceFiosDevctlSync(NULL, drive, 0x3001, NULL, 0, &info, sizeof(SceIoDevInfo));
if (ret < 0)
{
errno = EIO;
Expand Down
Loading