-------------------------------------------- On Fri, 24/1/14, Vyacheslav Dubeyko <slava@xxxxxxxxxxx> wrote: Subject: [PATCH v2 00/15] hfsplus: introduce journal replay functionality To: "Linux FS devel list" <linux-fsdevel@xxxxxxxxxxxxxxx> Cc: "Al Viro" <viro@xxxxxxxxxxxxxxxxxx>, "ChristophHellwig" <hch@xxxxxxxxxxxxx>, "Hin-Tak Leung" <htl10@xxxxxxxxxxxxxxxxxxxxx>, "Andrew Morton" <akpm@xxxxxxxxxxxxxxxxxxxx> Date: Friday, 24 January, 2014, 15:25 Hi, This second version of patchset that implements journal replay functionality in HFS+ file system driver. v1->v2 * Fix error messages incorrectness (Hin-Tak Leung) * Fix issue with remount "mount -o remount,rw <device> <folder>" * Rework "force" and "norecovery" mount options support (Hin-Tak Leung) Technical Note TN1150: "The purpose of the journal is to ensure that when a group of related changes are being made, that either all of those changes are actually made, or none of them are made. This is done by gathering up all of the changes, and storing them in a separate place (in the journal). Once the journal copy of the changes is completely written to disk, the changes can actually be written to their normal locations on disk. If a failure happens at that time, the changes can simply be copied from the journal to their normal locations. If a failure happens when the changes are being written to the journal, but before they are marked complete, then all of those changes are ignored." "A group of related changes is called a transaction. When all of the changes of a transaction have been written to their normal locations on disk, that transaction has been committed, and is removed from the journal. The journal may contain several transactions. Copying changes from all transactions to their normal locations on disk is called replaying the journal." "In order to replay the journal, an implementation just loops over the transactions, copying each individual block in the transaction from the journal to its proper location on the volume. Once those blocks have been flushed to the media (not just the driver!), it may update the journal header to remove the transactions." "Here are the steps to replay the journal: 1. Read the volume header into variable vhb. The volume may have an HFS wrapper; if so, you will need to use it to determine the location of the volume header. 2. Test the kHFSVolumeJournaledBit in the attributes field of the volume header. If it is not set, there is no journal to replay, and you are done. 3. Read the journal info block from the allocation block number vhb.journalInfoBlock, into variable jib. 4. If kJIJournalNeedsInitMask is set in jib.flags, the journal was never initialized, so there is no journal to replay. 5. Verify that kJIJournalInFSMask is set and kJIJournalOnOtherDeviceMask is clear in jib.flags. 6. Read the journal header at jib.offset bytes from the start of the volume, and place it in variable jhdr. 7. If jhdr.start equals jhdr.end, the journal does not have any transactions, so there is nothing to replay. 8. Set the current offset in the journal (typically a local variable) to the start of the journal buffer, jhdr.start. 9. While jhdr.start does not equal jhdr.end, perform the following steps: 1. Read a block list header of jhdr.blhdr_size bytes from the current offset in the journal into variable blhdr. 2. For each block in bhdr.binfo[1] to bhdr.binfo[blhdr.num_blocks], inclusive, copy bsize bytes from the current offset in the journal to sector bnum on the volume (to byte offset bnum*jdhr.jhdr_size). Remember that jhdr_size is the size of a sector, in bytes. 3. If bhdr.binfo[0].next is zero, you have completed the last block list of the current transaction; set jhdr.start to the current offset in the journal." It was reworked concept of "force" mount option. It is used to force write access to volumes that are marked as locked, only. This option doesn't work for journaled volumes with non-empty journal. HFS+ drive tries to replay journal and ignores forcing write access in the case of journal replay failure. It is possible to access HFS+ volume in read-only mode only for such case. The "force" option is ignored for the case of "norecovery" option request also. With the best regards, Vyacheslav Dubeyko. --- Documentation/filesystems/hfsplus.txt | 16 +- fs/hfsplus/Makefile | 3 +- fs/hfsplus/hfsplus_fs.h | 33 +- fs/hfsplus/hfsplus_raw.h | 53 +- fs/hfsplus/journal.c | 1215 +++++++++++++++++++++++++++++++++ fs/hfsplus/options.c | 17 +- fs/hfsplus/part_tbl.c | 4 +- fs/hfsplus/super.c | 105 ++- fs/hfsplus/wrapper.c | 28 +- 9 files changed, 1435 insertions(+), 39 deletions(-) -- 1.7.9.5 Thanks, Vyacheslav, for presisting on this. I'll give the new patchset a try at somepoint. About inter-operability, I thought of one idea - it would be useful to wrap genuine OS X code around some kind of fuse framework to run under linux? I don't know how difficult it is, but at some point I think besides the specification (tn1150, we need to look at the actual implementation for inter-operability anyhow. The fs code in the OS X kernel is under the xnu component, in the bsd layer, I seem to remember. Another left-over issue I forgot to mention again: some disk images (I came across one, one of the xcode devtool download from Apple - so it is "official", not some random 3rd party who did broken things) have the secondary header at a slightly different offset from the end. The details I don't have in hand but I believe I posted the details publicly at some stage - possibly at the redhat bugzilla(!). Hin-Tak -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html