Re: [PATCH 5/6] btrfs: only copy dir index keys when logging a directory
From: Josef Bacik <josef@toxicpanda.com>
Date: 2021-10-25 15:36:35
On Mon, Oct 25, 2021 at 10:56:25AM +0100, fdmanana@kernel.org wrote:
From: Filipe Manana <redacted> Currently, when logging a directory, we copy both dir items and dir index items from the fs/subvolume tree to the log tree. Both items have exactly the same data (same struct btrfs_dir_item), the difference lies in the key values, where a dir index key contains the index number of a directory entry while the dir item key does not, as it's used for doing fast lookups of an entry by name, while the former is used for sorting entries when listing a directory. We can exploit that and log only the dir index items, since they contain all the information needed to correctly add, replace and delete directory entries when replaying a log tree. Logging only the dir index items is also backward and forward compatible: an unpatched kernel (without this change) can correctly replay a log tree generated by a patched kernel (with this patch), and a patched kernel can correctly replay a log tree generated by an unpatched kernel.
This took me a very long time to grok, so it deserves more explanation. The problem I had was how this worked in general, and I was missing the fact that we're only calling drop_dir_item() if we find the name in the root, otherwise we either goto insert if we're DIR_INDEX or bail if we're DIR_ITEM. So whichever we find first in the log, we call drop_dir_item() only if there's a conflict. Then the heavy work is done once we find the DIR_INDEX item. Which means that the only work we do if we find DIR_ITEM is drop_dir_item(), which we do in the case if we find DIR_INDEX and the item is there. This is why we don't actually need the DIR_ITEM to properly replay the log for older kernels, because DIR_INDEX does the same work, and actually does the heavy lifting of adding the BACKREF's and such. This took probably 30-45 minutes for me to work out, and I'm only 90% sure I have it right, so an explanation as to why it's ok for older kernels would be very helpful. Thanks, Josef