之前在samplefs中遇到了一個獲取當前時間戳的問題,源代碼中使用的是過時的宏CURRENT_TIME
獲取當前時間,在新內核中,inode的a_time
、c_time
和m_time
都調整為timespec64
類型,而且內核的時間模塊也經過了相當大的調整,所以需要進行修改來適應當前的內核(5.4.89)。
經過一番查閱后,使用如下的代碼獲取當前時間戳:
struct timespec64 ts;
ktime_get_ts64(&ts);
inode->m_time = ts;
但是發現得到的時間是1970年的初始時間戳,這個問題是因為對於linux的時間理解不夠詳細,主要是對於CLOCK_MONOTONIC
和CLOCK_REALTIME
的理解出現了偏差。簡單來說,CLOCK_MONOTONIC
指的是系統啟動到當前的時間,這個時間是不可以修改的,而CLOCK_REALTIME
也就是我們常說的牆鍾時間,即從1970年到現在經過的時間。
而在ktime_get_real
的官方文檔中也提到:
This is used for all timestamps that need to persist across a reboot, like inode times, but should be avoided for internal uses, since it can jump backwards due to a leap second update, NTP adjustment settimeofday() operation from user space.
所以對於inode的三個時間成員的時間戳獲取應該使用CLOCK_REALTIME
,代碼中改成ktime_get_real_ts64
即可正常獲取當前時間戳。
順便說一下,上文文檔中提到避免internal use,之后發現在新內核中,fs/inode.c中實現了一個struct timespec64 current_time(struct inode *inode)
函數,所以可以不用ktime_get_real_ts64
這個函數了。
另外:ctags真好用,比source insight高到不知道哪里去了。就拿current_time
這個函數來說,Source Insight一直表示找不到定義,ctags瞬間就找到了。。。
參考資料:
CLOCK_MONOTONIC與CLOCK_REALTIME區別
kernel.org/core-api/timekeeping.c
Linux下安裝和使用ctags