feat: ext2 - save timestamp metadata
This commit is contained in:
@@ -12,4 +12,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define MONTAUK_BUILD_NUMBER 1
|
||||
#define MONTAUK_BUILD_NUMBER 2
|
||||
|
||||
+66
-2
@@ -10,6 +10,7 @@
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <Libraries/Memory.hpp>
|
||||
#include <Memory/PageFrameAllocator.hpp>
|
||||
#include <Timekeeping/Time.hpp>
|
||||
|
||||
using namespace Kt;
|
||||
|
||||
@@ -261,6 +262,15 @@ namespace Fs::Ext2 {
|
||||
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
|
||||
// =========================================================================
|
||||
@@ -1320,6 +1330,9 @@ namespace Fs::Ext2 {
|
||||
|
||||
// Write updated inode to disk
|
||||
if (bytesWritten > 0) {
|
||||
uint32_t now = Ext2Now();
|
||||
file.inode.i_mtime = now;
|
||||
file.inode.i_ctime = now;
|
||||
WriteInode(self, file.inodeNum, &file.inode);
|
||||
}
|
||||
|
||||
@@ -1353,6 +1366,9 @@ namespace Fs::Ext2 {
|
||||
FreeInodeBlocks(self, existInode);
|
||||
existInode.i_size = 0;
|
||||
existInode.i_blocks = 0;
|
||||
uint32_t now = Ext2Now();
|
||||
existInode.i_mtime = now;
|
||||
existInode.i_ctime = now;
|
||||
WriteInode(self, existing.inodeNum, &existInode);
|
||||
|
||||
// Open a handle
|
||||
@@ -1378,6 +1394,10 @@ namespace Fs::Ext2 {
|
||||
memset(&newInode, 0, sizeof(Inode));
|
||||
newInode.i_mode = IMODE_REG | 0644; // regular file, rw-r--r--
|
||||
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);
|
||||
|
||||
// Add directory entry
|
||||
@@ -1387,6 +1407,14 @@ namespace Fs::Ext2 {
|
||||
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
|
||||
for (int i = 0; i < MaxFilesPerInstance; i++) {
|
||||
if (!self.files[i].inUse) {
|
||||
@@ -1432,19 +1460,26 @@ namespace Fs::Ext2 {
|
||||
// Remove directory entry
|
||||
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 (isDir) {
|
||||
parentInode.i_links_count--;
|
||||
WriteInode(self, parentInodeNum, &parentInode);
|
||||
}
|
||||
WriteInode(self, parentInodeNum, &parentInode);
|
||||
|
||||
// Decrement link count
|
||||
targetInode.i_links_count--;
|
||||
if (isDir) targetInode.i_links_count--; // account for "." self-link
|
||||
targetInode.i_ctime = now;
|
||||
if (targetInode.i_links_count <= 0) {
|
||||
// Free all blocks and the inode
|
||||
FreeInodeBlocks(self, targetInode);
|
||||
targetInode.i_mode = 0;
|
||||
targetInode.i_dtime = now;
|
||||
WriteInode(self, existing.inodeNum, &targetInode);
|
||||
FreeInode(self, existing.inodeNum);
|
||||
} else {
|
||||
@@ -1535,6 +1570,10 @@ namespace Fs::Ext2 {
|
||||
newInode.i_blocks = blockSize / 512;
|
||||
newInode.i_links_count = 2; // . and parent's entry
|
||||
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);
|
||||
|
||||
// Add entry to parent directory
|
||||
@@ -1547,8 +1586,11 @@ namespace Fs::Ext2 {
|
||||
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_mtime = dirNowTs;
|
||||
parentInode.i_ctime = dirNowTs;
|
||||
WriteInode(self, parentInodeNum, &parentInode);
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user