feat: ext2 - save timestamp metadata
This commit is contained in:
@@ -12,4 +12,4 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define MONTAUK_BUILD_NUMBER 1
|
#define MONTAUK_BUILD_NUMBER 2
|
||||||
|
|||||||
+66
-2
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user