feat: vfs - add stat syscall
This commit is contained in:
@@ -1189,6 +1189,24 @@ namespace Fs::Ext2 {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int StatImpl(int inst, const char* path, Vfs::StatInfo* out) {
|
||||
if (!out) return -1;
|
||||
if (inst < 0 || inst >= g_instanceCount || !g_instances[inst].active) return -1;
|
||||
auto& self = g_instances[inst];
|
||||
|
||||
uint32_t inodeNum;
|
||||
Inode inode;
|
||||
if (!TraversePath(self, path, &inodeNum, &inode)) return -1;
|
||||
|
||||
out->size = inode.i_size;
|
||||
out->mtime = (int64_t)inode.i_mtime;
|
||||
out->ctime = (int64_t)inode.i_ctime;
|
||||
out->atime = (int64_t)inode.i_atime;
|
||||
out->mode = inode.i_mode;
|
||||
out->isDir = (inode.i_mode & IMODE_TYPE_MASK) == IMODE_DIR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ReadImpl(int inst, int handle, uint8_t* buffer,
|
||||
uint64_t offset, uint64_t size) {
|
||||
if (inst < 0 || inst >= g_instanceCount) return -1;
|
||||
@@ -1764,6 +1782,7 @@ namespace Fs::Ext2 {
|
||||
static int Mkdir(const char* p) { return MkdirImpl(N, p); }
|
||||
static int Rename(const char* o, const char* n) { return RenameImpl(N, o, n); }
|
||||
static const char* GetLabel() { return GetLabelImpl(N); }
|
||||
static int Stat(const char* p, Vfs::StatInfo* o) { return StatImpl(N, p, o); }
|
||||
};
|
||||
|
||||
template<int N>
|
||||
@@ -1781,6 +1800,7 @@ namespace Fs::Ext2 {
|
||||
Thunks<N>::Rename,
|
||||
Thunks<N>::GetLabel,
|
||||
Thunks<N>::ReadDirAt,
|
||||
Thunks<N>::Stat,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -288,6 +288,25 @@ namespace Fs::Vfs {
|
||||
return result;
|
||||
}
|
||||
|
||||
int VfsStat(const char* path, StatInfo& out) {
|
||||
int drive;
|
||||
const char* localPath;
|
||||
|
||||
out = StatInfo{};
|
||||
|
||||
if (!ParsePath(path, drive, localPath)) return -1;
|
||||
if (drive < 0 || drive >= MaxDrives || !driveActive[drive] || driveTable[drive] == nullptr) return -1;
|
||||
if (driveTable[drive]->Stat == nullptr) return -1;
|
||||
|
||||
vfsLock.Acquire();
|
||||
FsDriver* driver = driveTable[drive];
|
||||
int result = (driveActive[drive] && driver && driver->Stat)
|
||||
? driver->Stat(localPath, &out)
|
||||
: -1;
|
||||
vfsLock.Release();
|
||||
return result;
|
||||
}
|
||||
|
||||
int VfsMkdir(const char* path) {
|
||||
int drive;
|
||||
const char* localPath;
|
||||
|
||||
@@ -18,6 +18,17 @@ namespace Fs::Vfs {
|
||||
uint32_t generation;
|
||||
};
|
||||
|
||||
// Metadata for a single path, filled by FsDriver::Stat. Timestamps are UTC
|
||||
// unix seconds; a filesystem that does not record a given time leaves it 0.
|
||||
struct StatInfo {
|
||||
uint64_t size; // file size in bytes
|
||||
int64_t mtime; // last data modification time
|
||||
int64_t ctime; // last inode (metadata) change time
|
||||
int64_t atime; // last access time
|
||||
uint32_t mode; // ext2/POSIX i_mode bits (type + permissions)
|
||||
bool isDir; // true if the entry is a directory
|
||||
};
|
||||
|
||||
struct FsDriver {
|
||||
int (*Open)(const char* path);
|
||||
int (*Read)(int handle, uint8_t* buffer, uint64_t offset, uint64_t size);
|
||||
@@ -33,6 +44,9 @@ namespace Fs::Vfs {
|
||||
// Optional: paginated directory read returning entries [startIndex, startIndex+maxEntries).
|
||||
// Drivers that leave this null are read via ReadDir at startIndex 0 only.
|
||||
int (*ReadDirAt)(const char* path, const char** outNames, int maxEntries, int startIndex);
|
||||
// Optional: fill metadata for a path. Drivers that leave this null do
|
||||
// not support stat and VfsStat returns -1 for their paths.
|
||||
int (*Stat)(const char* path, StatInfo* out);
|
||||
};
|
||||
|
||||
void Initialize();
|
||||
@@ -51,6 +65,7 @@ namespace Fs::Vfs {
|
||||
void CloseBackendFile(BackendFile& file);
|
||||
|
||||
int VfsDelete(const char* path);
|
||||
int VfsStat(const char* path, StatInfo& out);
|
||||
int VfsReadDir(const char* path, const char** outNames, int maxEntries);
|
||||
int VfsReadDirAt(const char* path, const char** outNames, int maxEntries, int startIndex);
|
||||
int VfsMkdir(const char* path);
|
||||
|
||||
Reference in New Issue
Block a user