9
9
#include < Kernel/Debug.h>
10
10
#include < Kernel/FileSystem/FATFS/Inode.h>
11
11
#include < Kernel/Library/KBufferBuilder.h>
12
+ #include < Kernel/Tasks/Process.h>
12
13
13
14
namespace Kernel {
14
15
@@ -544,7 +545,7 @@ InodeMetadata FATInode::metadata() const
544
545
.gid = 0 ,
545
546
.link_count = 0 ,
546
547
.atime = time_from_packed_dos (m_entry.last_accessed_date , { 0 }),
547
- .ctime = time_from_packed_dos (m_entry.creation_date , m_entry.creation_time ),
548
+ .ctime = time_from_packed_dos (m_entry.creation_date , m_entry.creation_time ) + Duration::from_milliseconds (m_entry. creation_time_seconds * 10 ) ,
548
549
.mtime = time_from_packed_dos (m_entry.modification_date , m_entry.modification_time ),
549
550
.dtime = {},
550
551
.block_count = cluster_count * fs ().m_parameter_block ->common_bpb ()->sectors_per_cluster ,
@@ -623,6 +624,24 @@ ErrorOr<size_t> FATInode::write_bytes_locked(off_t offset, size_t size, UserOrKe
623
624
return size;
624
625
}
625
626
627
+ ErrorOr<void > FATInode::fill_in_creation_time (FATEntry& entry, UnixDateTime const & timestamp)
628
+ {
629
+ auto packed_date = TRY (to_packed_dos_date (timestamp));
630
+ auto packed_time = TRY (to_packed_dos_time (timestamp));
631
+
632
+ entry.creation_date = move (packed_date);
633
+ entry.creation_time = move (packed_time);
634
+
635
+ // NOTE: The "creation_time_seconds" field not only compensates for the fact that seconds are counted in intervals of two,
636
+ // it also adds in rudimentary support for millisecond precision, though this is limited to only two digits.
637
+ auto day_start_precision = days_since_epoch (entry.creation_date .year + AK::first_dos_year, entry.creation_date .month , entry.creation_date .day ) * 86'400 ;
638
+ auto day_precision = entry.creation_time .hour * 60 * 60 + entry.creation_time .minute * 60 + entry.creation_time .second * 2 ;
639
+ entry.creation_time_seconds = (timestamp.truncated_milliseconds_since_epoch () - day_start_precision * 1000 - day_precision * 1000 ) / 10 ;
640
+ VERIFY (entry.creation_time_seconds < 200 );
641
+
642
+ return {};
643
+ }
644
+
626
645
ErrorOr<NonnullRefPtr<Inode>> FATInode::create_child (StringView name, mode_t mode, dev_t , UserID, GroupID)
627
646
{
628
647
MutexLocker locker (m_inode_lock);
@@ -649,7 +668,12 @@ ErrorOr<NonnullRefPtr<Inode>> FATInode::create_child(StringView name, mode_t mod
649
668
if (mode & S_IFDIR)
650
669
entry.attributes |= FATAttributes::Directory;
651
670
652
- // FIXME: Set the dates
671
+ auto now = kgettimeofday ();
672
+ if (auto error_or_void = fill_in_creation_time (entry, now); !error_or_void.is_error ()) {
673
+ entry.modification_date = entry.creation_date ;
674
+ entry.modification_time = entry.creation_time ;
675
+ entry.last_accessed_date = entry.creation_date ;
676
+ }
653
677
654
678
Vector<FATLongFileNameEntry> lfn_entries = {};
655
679
if (!valid_sfn)
@@ -906,9 +930,36 @@ ErrorOr<void> FATInode::flush_metadata()
906
930
return {};
907
931
}
908
932
909
- ErrorOr<void > FATInode::update_timestamps (Optional<UnixDateTime>, Optional<UnixDateTime>, Optional<UnixDateTime>)
933
+ ErrorOr<void > FATInode::update_timestamps (Optional<UnixDateTime> atime , Optional<UnixDateTime> ctime , Optional<UnixDateTime> mtime )
910
934
{
911
- // FIXME: Implement FATInode::update_timestamps
935
+ MutexLocker locker (m_inode_lock);
936
+
937
+ Optional<DOSPackedDate> packed_last_accessed_date;
938
+ Optional<DOSPackedDate> packed_modified_date;
939
+ Optional<DOSPackedTime> packed_modified_time;
940
+
941
+ if (atime.has_value ())
942
+ packed_last_accessed_date = TRY (to_packed_dos_date (atime.value ()));
943
+
944
+ if (mtime.has_value ()) {
945
+ packed_modified_date = TRY (to_packed_dos_date (mtime.value ()));
946
+ packed_modified_time = TRY (to_packed_dos_time (mtime.value ()));
947
+ }
948
+
949
+ // NOTE: This is initialized after we've parsed everything else
950
+ // to ensure that no changes will be made if we fail to parse
951
+ // any of the arguments.
952
+ if (ctime.has_value ())
953
+ TRY (fill_in_creation_time (m_entry, ctime.value ()));
954
+
955
+ if (atime.has_value ())
956
+ m_entry.last_accessed_date = packed_last_accessed_date.release_value ();
957
+
958
+ if (mtime.has_value ()) {
959
+ m_entry.modification_date = packed_modified_date.release_value ();
960
+ m_entry.modification_time = packed_modified_time.release_value ();
961
+ }
962
+
912
963
return {};
913
964
}
914
965
0 commit comments