Currently the SnapRAID support for Btrfs is probably not ideal:
- SnapRAID is using the filesystem UUID as unique identifier (also in relation to the inode numbers), which in the case of Btrfs is maybe incorrect, since a Btrfs filesystem can have various subvolumes. There can be identical inode numbers across different subvolumes for different files. ⇒ Given the current logic, it might be more correct to not use the filesystem UUID, but the subvolume UUID instead.
- SnapRAID is unable to get the filesystem UUID, if the disk path is a pointing to a not explicitly mounted subvolume, since the device number does not appear in
/proc/self/mountinfo. This could be an actual distinct subvolume, but it would also be typical for a snapshot, which you usually don't mount explicitly. ⇒ Btrfs allows mounting subvolumes, at which point the current UUID detection "works" and returns the filesystem UUID, independently on which subvolume is mounted, but that's basically a bad hack and not practical.
- (SnapRAID does not support nested subvolumes in a disk directory. ⇒ Supporting that would probably be more complicated, also not necessary for my use case.)
Why does it matter? Using snapshots is a nice way to mitigate some SnapRAID issues. If you snapshot a Btrfs subvolume, the inode numbers of the snapshot are apparently cloned from the parent1 subvolume, so file move detection should be supported.
Therefore the UUID detection should be fixed to also work for not explicitly mounted subvolumes. The devuuid function already has the actual path and should use it. Some possible solutions regarding which UUID to use:
- [A] Keep using the filesystem UUID for better backwards compatibility. (See
BTRFS_IOC_FS_INFO ioctl. Regarding fsid vs metadata_uuid, see the comment below.)
- [B] Instead of using the filesystem UUID, use the subvolume UUID. For snapshots use the parent1 UUID. (See
BTRFS_IOC_GET_SUBVOL_INFO ioctl. Caveat: Have seen from ext4 converted filesystems, where the root subvolume had an empty/all-zero UUID, did not try to reproduce.)
- [C] Like [B], but for snapshots search for the parent1 subvolumes recursively (as there could be snapshots of snapshots), and use the top subvolume's UUID. (Maybe the most correct method, but looks way more tricky than the previous options. Starting point might be libbtrfsutil. And yes, I did read some of the source code, looks non-trivial...)
All variants should fix the snapshot issue and allow file move detection.
(Side node: The TODO file says "Keep track of the subvolumeid, along with the inode, and use it when searching/comparing inodes.", however, I think this is probably not the way to go. First, the numeric subvolume ID is not unique, quite the contrary. Second, it would prevent robust move detection using snapshots, or even worse result in random behavior, e.g. if you don't keep the old snapshot(s) and sometimes end up with the same subvolume ID.)
Currently the SnapRAID support for Btrfs is probably not ideal:
/proc/self/mountinfo. This could be an actual distinct subvolume, but it would also be typical for a snapshot, which you usually don't mount explicitly. ⇒ Btrfs allows mounting subvolumes, at which point the current UUID detection "works" and returns the filesystem UUID, independently on which subvolume is mounted, but that's basically a bad hack and not practical.Why does it matter? Using snapshots is a nice way to mitigate some SnapRAID issues. If you snapshot a Btrfs subvolume, the inode numbers of the snapshot are apparently cloned from the parent1 subvolume, so file move detection should be supported.
Therefore the UUID detection should be fixed to also work for not explicitly mounted subvolumes. The
devuuidfunction already has the actual path and should use it. Some possible solutions regarding which UUID to use:BTRFS_IOC_FS_INFOioctl. Regardingfsidvsmetadata_uuid, see the comment below.)BTRFS_IOC_GET_SUBVOL_INFOioctl. Caveat: Have seen from ext4 converted filesystems, where the root subvolume had an empty/all-zero UUID, did not try to reproduce.)All variants should fix the snapshot issue and allow file move detection.
(Side node: The TODO file says "Keep track of the subvolumeid, along with the inode, and use it when searching/comparing inodes.", however, I think this is probably not the way to go. First, the numeric subvolume ID is not unique, quite the contrary. Second, it would prevent robust move detection using snapshots, or even worse result in random behavior, e.g. if you don't keep the old snapshot(s) and sometimes end up with the same subvolume ID.)
Footnotes
Original snapshotted subvolume, so referring to the parent UUID, contrary to the parent ID, which has a different meaning. ↩ ↩2 ↩3