feat: vfs - add stat syscall

This commit is contained in:
2026-07-21 14:23:06 +02:00
parent 5c02c5fe79
commit de7edaf623
12 changed files with 110 additions and 1 deletions
+20
View File
@@ -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,
};
}
+19
View File
@@ -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;
+15
View File
@@ -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);