准备环境
首先,在EXT4文件系统下,创建另一个测试文件
# echo Time for knowledge >testfile # touch -a -t 211101231917.42 testfile # touch -m -t 204005160308.19 testfile使用touch命令可以直接修改文件的atime(最后访问时间)、mtime(最后修改时间),这样可以把这些时间戳设置为我们想要的时间,否则这个新创建文件的atime、mtime时间戳将会是创建文件的时间。有一点需要指出,我刚才设置的atime、mtime都是遥远的未来的一个时间点,而在旧的Unix的文件系统中,由于时间信息是32位的,所以会引起一些麻烦(比如“ 2038年问题”,或称unix千年虫)。 现在,让我们比较一下标准的linux下的stat命令、Sleuthkit工具包里的istat、debugfs版本的stat的输出结果:
# stat testfile File: `testfile' Size: 19 Blocks: 8 IO Block: 4096 regular file Device: fc03h/64515d Inode: 6554914 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2111-01-23 19:17:42.000000000 -0800 Modify: 2040-05-16 03:08:19.000000000 -0700 Change: 2011-03-12 07:36:13.872411014 -0800 # istat /dev/mapper/RD-home 6554914 inode: 6554914 Allocated Group: 800 [...] Inode Times: Accessed: Tue Dec 17 12:49:26 1974 File Modified: Wed May 16 03:08:19 2040 Inode Modified: Sat Mar 12 07:36:13 2011 [...] # debugfs -R 'stat ' /dev/mapper/RD-home [...] ctime: 0x4d7b92ed:cfffbe18 -- Sat Mar 12 07:36:13 2011 atime: 0x0954b156:00000001 -- Tue Dec 17 12:49:26 1974 mtime: 0x845e5913:00000000 -- Wed May 16 03:08:19 2040 crtime: 0x4d7b92e4:148af06c -- Sat Mar 12 07:36:04 2011 [...]我已经对输出进行了编辑,使时间戳比较明显。正如你所看到的,这三个命令输出了相同的mtime和ctime,但是istat和debugfs在解析2111年的atime的时候出现了问题,只有stat命令获得了正确值。
你可能已经也注意到了EXT4的一些新功能:
- stat命令、debugfs命令输出的时间戳带有小数部分,现在EXT4时间戳支持精确到毫微秒(nanosecond)。
- 在debugfs的stat中可以看到"crtime"(create time)这一项,在EXT4中终于支持文件“诞生”的时间戳,就像NTFS一样,用来标记文件被创建的时间点。
- 至少在stat、touch命令已经可以完美的支持未来的时间戳。EXT4的实现方式已经解决了(事实上是推迟了)2038年问题。
显示细节
但是,就像我提到的,EXT4的开发者尽了最大的努力,使EXT4能够向下兼容EXT2、EXT3的inode结构。64位的时间戳、全新的文件创建时间项,明显与这个目标相矛盾。EXT4开发者解决这个问题的方法是通过在EXT4的256位inode中的高128位中,设置一个扩展部分。这是一个16位编辑器显示的结果(请参照第一部分):
将一个文件inode的开始作为0,则各个高亮的时间戳的区域如下所示:
Bytes 8 - 11: Access time seconds 12 - 15: Change time seconds 16 - 19: Modification time seconds
132 - 135: Change time "extra" 136 - 139: Modification time "extra" 140 - 143: Access time "extra" 144 - 147: Create time seconds 148 - 151: Create time "extra"
在inode起始位置的标准MACtime值本质上没有改变。它们以自1970年1月1日(unix元年)以来的秒数,然后,EXT4将这些值以无符号数而不是有符号数的形式保存。使用扩展位的方式使“2038年问题”变为“2106年问题”。你可以实际看到上面例子中的2040年的mtime。通过小端字节序传换而来,16进制的mtime值是0x845E5913, 或者十进制的2220775699,这个数将会引起32位有符号数产生溢出。可以通过以下命令将这个十进制数转换为可读的日期:
# date -d @2220775699
Wed May 16 03:08:19 PDT 2040