之前在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