feat: ext2 - save timestamp metadata

This commit is contained in:
2026-07-21 14:09:17 +02:00
parent 48e5d31e07
commit 5c02c5fe79
2 changed files with 67 additions and 3 deletions
+1 -1
View File
@@ -12,4 +12,4 @@
#pragma once #pragma once
#define MONTAUK_BUILD_NUMBER 1 #define MONTAUK_BUILD_NUMBER 2
+66 -2
View File
@@ -10,6 +10,7 @@
#include <Terminal/Terminal.hpp> #include <Terminal/Terminal.hpp>
#include <Libraries/Memory.hpp> #include <Libraries/Memory.hpp>
#include <Memory/PageFrameAllocator.hpp> #include <Memory/PageFrameAllocator.hpp>
#include <Timekeeping/Time.hpp>
using namespace Kt; using namespace Kt;
@@ -261,6 +262,15 @@ namespace Fs::Ext2 {
return WriteBlock(inst, inodeTableBlock + blockOffset, inst.blockBuf); return WriteBlock(inst, inodeTableBlock + blockOffset, inst.blockBuf);
} }
// Current wall-clock time as an ext2 timestamp (UTC unix seconds, 32-bit).
// Returns 0 before timekeeping is initialized so we never write a bogus
// date; a zero timestamp is the same "unknown" value ext2 already tolerates.
static uint32_t Ext2Now() {
int64_t ts = Timekeeping::GetUnixTimestamp();
if (ts < 0) ts = 0;
return (uint32_t)ts;
}
// ========================================================================= // =========================================================================
// Block addressing — resolve logical block index to physical block number // Block addressing — resolve logical block index to physical block number
// ========================================================================= // =========================================================================
@@ -1320,6 +1330,9 @@ namespace Fs::Ext2 {
// Write updated inode to disk // Write updated inode to disk
if (bytesWritten > 0) { if (bytesWritten > 0) {
uint32_t now = Ext2Now();
file.inode.i_mtime = now;
file.inode.i_ctime = now;
WriteInode(self, file.inodeNum, &file.inode); WriteInode(self, file.inodeNum, &file.inode);
} }
@@ -1353,6 +1366,9 @@ namespace Fs::Ext2 {
FreeInodeBlocks(self, existInode); FreeInodeBlocks(self, existInode);
existInode.i_size = 0; existInode.i_size = 0;
existInode.i_blocks = 0; existInode.i_blocks = 0;
uint32_t now = Ext2Now();
existInode.i_mtime = now;
existInode.i_ctime = now;
WriteInode(self, existing.inodeNum, &existInode); WriteInode(self, existing.inodeNum, &existInode);
// Open a handle // Open a handle
@@ -1378,6 +1394,10 @@ namespace Fs::Ext2 {
memset(&newInode, 0, sizeof(Inode)); memset(&newInode, 0, sizeof(Inode));
newInode.i_mode = IMODE_REG | 0644; // regular file, rw-r--r-- newInode.i_mode = IMODE_REG | 0644; // regular file, rw-r--r--
newInode.i_links_count = 1; newInode.i_links_count = 1;
uint32_t nowTs = Ext2Now();
newInode.i_atime = nowTs;
newInode.i_ctime = nowTs;
newInode.i_mtime = nowTs;
WriteInode(self, newInodeNum, &newInode); WriteInode(self, newInodeNum, &newInode);
// Add directory entry // Add directory entry
@@ -1387,6 +1407,14 @@ namespace Fs::Ext2 {
return -1; return -1;
} }
// Parent directory's contents changed; bump its mtime/ctime.
// Re-read first since AddDirEntry may have grown the parent inode.
if (ReadInode(self, parentInodeNum, &parentInode)) {
parentInode.i_mtime = nowTs;
parentInode.i_ctime = nowTs;
WriteInode(self, parentInodeNum, &parentInode);
}
// Open a handle // Open a handle
for (int i = 0; i < MaxFilesPerInstance; i++) { for (int i = 0; i < MaxFilesPerInstance; i++) {
if (!self.files[i].inUse) { if (!self.files[i].inUse) {
@@ -1432,19 +1460,26 @@ namespace Fs::Ext2 {
// Remove directory entry // Remove directory entry
if (!RemoveDirEntry(self, parentInode, fileName)) return -1; if (!RemoveDirEntry(self, parentInode, fileName)) return -1;
uint32_t now = Ext2Now();
// Parent directory's contents changed
parentInode.i_mtime = now;
parentInode.i_ctime = now;
// If we deleted a subdirectory, decrement parent's link count (for "..") // If we deleted a subdirectory, decrement parent's link count (for "..")
if (isDir) { if (isDir) {
parentInode.i_links_count--; parentInode.i_links_count--;
WriteInode(self, parentInodeNum, &parentInode);
} }
WriteInode(self, parentInodeNum, &parentInode);
// Decrement link count // Decrement link count
targetInode.i_links_count--; targetInode.i_links_count--;
if (isDir) targetInode.i_links_count--; // account for "." self-link if (isDir) targetInode.i_links_count--; // account for "." self-link
targetInode.i_ctime = now;
if (targetInode.i_links_count <= 0) { if (targetInode.i_links_count <= 0) {
// Free all blocks and the inode // Free all blocks and the inode
FreeInodeBlocks(self, targetInode); FreeInodeBlocks(self, targetInode);
targetInode.i_mode = 0; targetInode.i_mode = 0;
targetInode.i_dtime = now;
WriteInode(self, existing.inodeNum, &targetInode); WriteInode(self, existing.inodeNum, &targetInode);
FreeInode(self, existing.inodeNum); FreeInode(self, existing.inodeNum);
} else { } else {
@@ -1535,6 +1570,10 @@ namespace Fs::Ext2 {
newInode.i_blocks = blockSize / 512; newInode.i_blocks = blockSize / 512;
newInode.i_links_count = 2; // . and parent's entry newInode.i_links_count = 2; // . and parent's entry
newInode.i_block[0] = dirBlock; newInode.i_block[0] = dirBlock;
uint32_t dirNowTs = Ext2Now();
newInode.i_atime = dirNowTs;
newInode.i_ctime = dirNowTs;
newInode.i_mtime = dirNowTs;
WriteInode(self, newInodeNum, &newInode); WriteInode(self, newInodeNum, &newInode);
// Add entry to parent directory // Add entry to parent directory
@@ -1547,8 +1586,11 @@ namespace Fs::Ext2 {
return -1; return -1;
} }
// Increment parent's link count (for ".." in the new dir) // Increment parent's link count (for ".." in the new dir) and record
// that its contents changed.
parentInode.i_links_count++; parentInode.i_links_count++;
parentInode.i_mtime = dirNowTs;
parentInode.i_ctime = dirNowTs;
WriteInode(self, parentInodeNum, &parentInode); WriteInode(self, parentInodeNum, &parentInode);
// Update used_dirs_count in block group descriptor // Update used_dirs_count in block group descriptor
@@ -1675,6 +1717,28 @@ namespace Fs::Ext2 {
// TODO: update ".." entry inside the moved directory to point to new parent // TODO: update ".." entry inside the moved directory to point to new parent
} }
uint32_t now = Ext2Now();
// A rename changes the moved inode's ctime (metadata changed).
Inode movedInode;
if (ReadInode(self, oldEntry.inodeNum, &movedInode)) {
movedInode.i_ctime = now;
WriteInode(self, oldEntry.inodeNum, &movedInode);
}
// Both affected directories had their contents change.
if (ReadInode(self, oldParentInodeNum, &oldParentInode)) {
oldParentInode.i_mtime = now;
oldParentInode.i_ctime = now;
WriteInode(self, oldParentInodeNum, &oldParentInode);
}
if (newParentInodeNum != oldParentInodeNum &&
ReadInode(self, newParentInodeNum, &newParentInode)) {
newParentInode.i_mtime = now;
newParentInode.i_ctime = now;
WriteInode(self, newParentInodeNum, &newParentInode);
}
return 0; return 0;
} }