feat: add sfsModeOf and sfsChmod to sfs

This commit is contained in:
dualfroz committed 2026-09-07 18:07:33 +02:00
1 parent 58b615e840
commit e03c0d5f7e
1 file changed
+158
+158
View File
@@ -1266,3 +1266,161 @@ uint64 sfsCtimeOf(int32 inodeNum)
return inode.ctime;
}
uint32 sfsModeOf(int32 inodeNum)
{
if (!isMounted || inodeNum <= 0)
return 0;
SfsInode inode;
if (!readInode(inodeNum, &inode))
return 0;
return inode.mode;
}
bool sfsChmod(int32 inodeNum, uint32 mode)
{
if (!isMounted || inodeNum <= 0)
return false;
SfsInode inode;
if (!readInode(inodeNum, &inode))
return false;
inode.mode = mode;
inode.ctime = (uint32)rtcNow();
return writeInodeRaw(inodeNum, &inode);
}
uint32 sfsUidOf(int32 inodeNum)
{
if (!isMounted || inodeNum <= 0)
return 0;
SfsInode inode;
if (!readInode(inodeNum, &inode))
return 0;
return inode.uid;
}
bool sfsChown(int32 inodeNum, uint32 newUid)
{
if (!isMounted || inodeNum <= 0)
return false;
SfsInode inode;
if (!readInode(inodeNum, &inode))
return false;
inode.uid = newUid;
inode.ctime = (uint32)rtcNow();
return writeInodeRaw(inodeNum, &inode);
}
uint32 sfsGidOf(int32 inodeNum)
{
if (!isMounted || inodeNum <= 0)
return 0;
SfsInode inode;
if (!readInode(inodeNum, &inode))
return 0;
return inode.gid;
}
bool sfsChgrp(int32 inodeNum, uint32 newGid)
{
if (!isMounted || inodeNum <= 0)
return false;
SfsInode inode;
if (!readInode(inodeNum, &inode))
return false;
inode.gid = newGid;
inode.ctime = (uint32)rtcNow();
return writeInodeRaw(inodeNum, &inode);
}
bool sfsTruncate(int32 inodeNum, uint64 newSize)
{
if (!isMounted || inodeNum <= 0 || newSize > 0xFFFFFFFFu)
return false;
SfsInode inode;
if (!readInode(inodeNum, &inode))
return false;
if (inode.type != sfsTypeFile)
return false;
return sfsTruncateInode(&inode, inodeNum, (uint32)newSize);
}
int64 sfsReadAt(int32 inodeNum, uint64 offset, void* buffer, uint64 length)
{
if (!isMounted || inodeNum <= 0)
return -1;
SfsInode inode;
if (!readInode(inodeNum, &inode))
return -1;
if (inode.type != sfsTypeFile && inode.type != sfsTypeDir && inode.type != sfsTypeSymlink)
return -1;
if (offset >= inode.size)
return 0;
uint64 want = length;
if (want > (uint64)inode.size - offset)
want = (uint64)inode.size - offset;
uint8* dst = (uint8*)buffer;
uint64 done = 0;
while (done < want) {
uint64 pos = offset + done;
uint32 logicalBlock = (uint32)(pos / sfsBlockSize);
uint32 within = (uint32)(pos % sfsBlockSize);
uint32 chunk = sfsBlockSize - within;
if ((uint64)chunk > want - done)
chunk = (uint32)(want - done);
uint32 blockAbs;
if (getBlockForRead(&inode, logicalBlock, &blockAbs)) {
uint8 blockBuf[sfsBlockSize];
if (!blockRead(blockAbs, blockBuf))
break;
memcpy(dst + done, blockBuf + within, chunk);
} else {
memset(dst + done, 0, chunk);
}
done += chunk;
}
return (int64)done;
}
int64 sfsWriteAt(int32 inodeNum, uint64 offset, const void* buffer, uint64 length)
{
if (!isMounted || inodeNum <= 0)
return -1;
SfsInode inode;
if (!readInode(inodeNum, &inode))
return -1;
if (inode.type != sfsTypeFile && inode.type != sfsTypeDir && inode.type != sfsTypeSymlink)
return -1;
if (length == 0)
return 0;
if (offset > inode.size) {
if (!sfsWriteRaw(&inode, inodeNum, inode.size, nullptr, offset - inode.size))
return -1;
}
if (!sfsWriteRaw(&inode, inodeNum, offset, buffer, length))
return -1;
return (int64)length;
}
bool sfsReaddirAt(int32 dirInode, uint32 index, char* nameOut, uint32 nameCap, uint32* typeOut)
{
if (!isMounted || sfsTypeOf(dirInode) != sfsTypeDir)
return false;
SfsDirEntry entry;
uint64 pos = (uint64)index * sizeof(SfsDirEntry);
if (sfsReadAt(dirInode, pos, &entry, sizeof(entry)) != (int64)sizeof(entry))
return false;
uint64 nlen = strlen(entry.name);
if (nlen >= nameCap)
nlen = nameCap - 1;
memcpy(nameOut, entry.name, nlen);
nameOut[nlen] = 0;
if (typeOut)
*typeOut = entry.type;
return true;
}