feat: add 'vol' command
This commit is contained in:
1 parent
420a7c996c
commit
80b5beb17d
17 files changed
+284
-17
No files matched your search
@@ -67,6 +67,7 @@ namespace Fs {
|
||||
int RdMkdir(void*, const char* p) { return Ramdisk::Mkdir(p); }
|
||||
int RdRename(void*, const char* o, const char* n) { return Ramdisk::Rename(o, n); }
|
||||
const char* RdGetLabel(void*) { return Ramdisk::GetLabel(); }
|
||||
const char* RdGetFsType(void*) { return "ramdisk"; }
|
||||
int RdReadDirAt(void*, const char* p, const char** o, int m, int s) { return Ramdisk::ReadDirAt(p, o, m, s); }
|
||||
|
||||
int RdStat(void*, const char* p, Vfs::StatInfo* out) {
|
||||
@@ -99,6 +100,7 @@ namespace Fs {
|
||||
.Mkdir = RdMkdir,
|
||||
.Rename = RdRename,
|
||||
.GetLabel = RdGetLabel,
|
||||
.GetFsType = RdGetFsType,
|
||||
.ReadDirAt = RdReadDirAt,
|
||||
.Stat = RdStat,
|
||||
.SetTimes = nullptr,
|
||||
|
||||
@@ -1861,6 +1861,7 @@ namespace Fs::Ext2 {
|
||||
static int DrvMkdir(void* c, const char* p) { return MkdirImpl(CtxToInst(c), p); }
|
||||
static int DrvRename(void* c, const char* o, const char* n) { return RenameImpl(CtxToInst(c), o, n); }
|
||||
static const char* DrvGetLabel(void* c) { return GetLabelImpl(CtxToInst(c)); }
|
||||
static const char* DrvGetFsType(void*) { return "ext2"; }
|
||||
static int DrvStat(void* c, const char* p, Vfs::StatInfo* o) { return StatImpl(CtxToInst(c), p, o); }
|
||||
static int DrvSetTimes(void* c, const char* p, int64_t a, int64_t m) { return SetTimesImpl(CtxToInst(c), p, a, m); }
|
||||
|
||||
@@ -2071,6 +2072,7 @@ namespace Fs::Ext2 {
|
||||
.Mkdir = DrvMkdir,
|
||||
.Rename = DrvRename,
|
||||
.GetLabel = DrvGetLabel,
|
||||
.GetFsType = DrvGetFsType,
|
||||
.ReadDirAt = DrvReadDirAt,
|
||||
.Stat = DrvStat,
|
||||
.SetTimes = DrvSetTimes,
|
||||
|
||||
@@ -1894,6 +1894,7 @@ namespace Fs::Fat32 {
|
||||
static int DrvMkdir(void* c, const char* p) { return MkdirImpl(CtxToInst(c), p); }
|
||||
static int DrvRename(void* c, const char* o, const char* n) { return RenameImpl(CtxToInst(c), o, n); }
|
||||
static const char* DrvGetLabel(void* c) { return GetLabelImpl(CtxToInst(c)); }
|
||||
static const char* DrvGetFsType(void*) { return "FAT32"; }
|
||||
static int DrvStat(void* c, const char* p, Vfs::StatInfo* o) { return StatImpl(CtxToInst(c), p, o); }
|
||||
|
||||
// Release everything the mount owns. The driver is either not registered
|
||||
@@ -2101,6 +2102,7 @@ namespace Fs::Fat32 {
|
||||
.Mkdir = DrvMkdir,
|
||||
.Rename = DrvRename,
|
||||
.GetLabel = DrvGetLabel,
|
||||
.GetFsType = DrvGetFsType,
|
||||
.ReadDirAt = DrvReadDirAt,
|
||||
.Stat = DrvStat,
|
||||
.SetTimes = nullptr,
|
||||
|
||||
@@ -154,18 +154,22 @@ namespace Fs::FsProbe {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GetBlockDeviceForDrive(int driveNum) {
|
||||
int GetPartitionForDrive(int driveNum) {
|
||||
if (driveNum < 0) return -1;
|
||||
int partCount = Drivers::Storage::Gpt::GetPartitionCount();
|
||||
for (int i = 0; i < partCount && i < Drivers::Storage::Gpt::MaxPartitions; i++) {
|
||||
if (g_mounted[i] && g_driveForPart[i] == driveNum) {
|
||||
auto* part = Drivers::Storage::Gpt::GetPartition(i);
|
||||
if (part) return part->BlockDevIndex;
|
||||
}
|
||||
if (g_mounted[i] && g_driveForPart[i] == driveNum) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GetBlockDeviceForDrive(int driveNum) {
|
||||
int partIndex = GetPartitionForDrive(driveNum);
|
||||
if (partIndex < 0) return -1;
|
||||
auto* part = Drivers::Storage::Gpt::GetPartition(partIndex);
|
||||
return part ? part->BlockDevIndex : -1;
|
||||
}
|
||||
|
||||
int UnmountPartitionsForBlockDevice(int blockDevIndex) {
|
||||
int partCount = Drivers::Storage::Gpt::GetPartitionCount();
|
||||
int unmounted = 0;
|
||||
|
||||
@@ -38,6 +38,10 @@ namespace Fs::FsProbe {
|
||||
// drive isn't backed by a partition (e.g. ramdisk).
|
||||
int GetBlockDeviceForDrive(int driveNum);
|
||||
|
||||
// Return the global GPT partition index backing a mounted VFS drive, or -1
|
||||
// if the drive isn't backed by a partition (e.g. ramdisk).
|
||||
int GetPartitionForDrive(int driveNum);
|
||||
|
||||
// Prepare persistent storage for power-off: flush every block device's
|
||||
// write cache to media, then cleanly unmount all disk-backed VFS drives.
|
||||
// The ramdisk (which has no backing block device) is left mounted. Returns
|
||||
|
||||
+18
-10
@@ -350,10 +350,10 @@ namespace Fs::Vfs {
|
||||
vfsLock.Release();
|
||||
return count;
|
||||
}
|
||||
|
||||
int VfsDriveLabel(int driveNumber, char* outLabel, int maxLen) {
|
||||
if (outLabel == nullptr || maxLen <= 0) return -1;
|
||||
outLabel[0] = '\0';
|
||||
static int CopyDriveString(int driveNumber, const char* (*FsDriver::*hook)(void*),
|
||||
char* out, int maxLen) {
|
||||
if (out == nullptr || maxLen <= 0) return -1;
|
||||
out[0] = '\0';
|
||||
|
||||
vfsLock.Acquire();
|
||||
FsDriver* driver = DriverForLocked(driveNumber);
|
||||
@@ -362,28 +362,36 @@ namespace Fs::Vfs {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (driver->GetLabel == nullptr) {
|
||||
if (driver->*hook == nullptr) {
|
||||
vfsLock.Release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* label = driver->GetLabel(driver->ctx);
|
||||
if (label == nullptr || label[0] == '\0') {
|
||||
const char* value = (driver->*hook)(driver->ctx);
|
||||
if (value == nullptr || value[0] == '\0') {
|
||||
vfsLock.Release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copied = 0;
|
||||
while (label[copied] != '\0' && copied < maxLen - 1) {
|
||||
outLabel[copied] = label[copied];
|
||||
while (value[copied] != '\0' && copied < maxLen - 1) {
|
||||
out[copied] = value[copied];
|
||||
copied++;
|
||||
}
|
||||
outLabel[copied] = '\0';
|
||||
out[copied] = '\0';
|
||||
|
||||
vfsLock.Release();
|
||||
return copied;
|
||||
}
|
||||
|
||||
int VfsDriveLabel(int driveNumber, char* outLabel, int maxLen) {
|
||||
return CopyDriveString(driveNumber, &FsDriver::GetLabel, outLabel, maxLen);
|
||||
}
|
||||
|
||||
int VfsDriveFsType(int driveNumber, char* outType, int maxLen) {
|
||||
return CopyDriveString(driveNumber, &FsDriver::GetFsType, outType, maxLen);
|
||||
}
|
||||
|
||||
int VfsRename(const char* oldPath, const char* newPath) {
|
||||
int oldDrive, newDrive;
|
||||
const char* oldLocal;
|
||||
|
||||
@@ -59,6 +59,9 @@ namespace Fs::Vfs {
|
||||
int (*Mkdir)(void* ctx, const char* path);
|
||||
int (*Rename)(void* ctx, const char* oldPath, const char* newPath);
|
||||
const char* (*GetLabel)(void* ctx);
|
||||
// Optional: short name of the on-disk format ("ext2", "FAT32", ...).
|
||||
// Drivers that leave this null report an empty type string.
|
||||
const char* (*GetFsType)(void* ctx);
|
||||
// Optional: paginated directory read returning entries [startIndex, startIndex+maxEntries).
|
||||
// Drivers that leave this null are read via ReadDir at startIndex 0 only.
|
||||
int (*ReadDirAt)(void* ctx, const char* path, const char** outNames, int maxEntries, int startIndex);
|
||||
@@ -103,5 +106,6 @@ namespace Fs::Vfs {
|
||||
// Returns number of registered drives, fills outDrives[] with their indices
|
||||
int VfsDriveList(int* outDrives, int maxEntries);
|
||||
int VfsDriveLabel(int driveNumber, char* outLabel, int maxLen);
|
||||
int VfsDriveFsType(int driveNumber, char* outType, int maxLen);
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user