Yah, I agree. Here's a quick summary of the issues:
* UNDO records are used to compartmentalize atomic changes which
cover multiple disk blocks. For example, if you 'rm' a file
and a crash occurs, you want the state of the filesystem to
either show the file and its directory entry both removed, or show
the file and its directory entry both still present.
* Updates to the inode_data, which holds the stat/chmod info for
a file object, typically requires rolling a new inode_data record
with the old one still available via the filesystem history. For
example, if you append some stuff to an existing file an old
version of the inode_data must be present in order to 'see' the
previous state of the file (in particular, the previous st_size
of the file).
* BUT, having to do any of the above when updating atime and mtime
would be really expensive.
- atime gets updated all the time. We definitely do not want to
roll UNDO records *or* new inode_data records.
- mtime gets updated all the time in certain situations, such as
when overwriting a file (e.g. in ways that do not modify the
file's size).
- mtime is often used to uniquely determine whether a file has
been modified.
* And, finally, we want mirroring to work properly even if the
filesystem is mounted 'nohistory' (told not to roll new
inode_data records). Or, for that matter, if individual files
are chflagged 'nohistory'.
The bane of HAMMER's design is that we absolutely do not want to roll
new inode_data records unless we have to, so here is what I am going to
do:
* ATime will be updated asynchronously and will not be CRCd, so
the B-Tree element's CRC field does not have to be updated.
(thus no UNDO records need to be generated either).
* MTime will be updated semi-synchronously and will be CRCd.
(It will be fully synchronous from the point of view of
anyone using the filesystem, of course). UNDO ...