sys/vfs/hammer: Fix mount issue after volume-del
When a volume other than the one with the max volume number
is removed from filesystem by volume-del, volume numbers are
no longer sequential. This makes unable to mount the filesystem
once it's unmounted because code assumes volumes numbers are
>=0 && <=(N-1) when N is the number of volumes. It needs to
be able to handle a hole in volume numbers.
For example, the following filesystem initially consists of
volumes A/B/C where volume A is the root volume(*). Each has
volume# 0/1/2 in its volume header written by newfs_hammer.
volume *A-B-C
volume# 0 1 2
Remove volume B by hammer volume-del. If the filesystem has
no data yet, it never fails.
volume *A-C
volume# 0 2
Unmount filesystem and try to mount again by specifying A:C,
but mount code assumes filesystem that consists of 2 volumes
means volume numbers are (A,C)=(0,1)|(1,0)
but not (A,C)=(0,2)|(2,0)
# newfs_hammer -L TEST /dev/da1 /dev/da2 /dev/da3 > /dev/null
# mount_hammer /dev/da1:/dev/da2:/dev/da3 /HAMMER
# hammer volume-blkdevs /HAMMER
/dev/da1:/dev/da2:/dev/da3
# hammer volume-del /dev/da2 /HAMMER
# hammer volume-blkdevs /HAMMER
/dev/da1:/dev/da3
# umount /HAMMER
# mount_hammer /dev/da1:/dev/da3 /HAMMER
mount_hammer: Unknown error: Invalid argument
# dmesg | tail -1
hammer_mount: Missing volumes, cannot mount!
This commit fixes that.
# newfs_hammer -L TEST /dev/da1 /dev/da2 /dev/da3 > /dev/null
# mount_hammer /dev/da1:/dev/da2:/dev/da3 /HAMMER
# hammer volume-blkdevs /HAMMER
/dev/da1:/dev/da2:/dev/da3
# hammer volume-del /dev/da2 /HAMMER
# hammer volume-blkdevs /HAMMER
/dev/da1:/dev/da3
# umount /HAMMER
# mount_hammer /dev/da1:/dev/da3 /HAMMER
# hammer volume-blkdevs /HAMMER
/dev/da1:/dev/da3
# umount /HAMMER
Note that hammer volume-add doesn't assume volume numbers are
sequential, so it can properly add a volume after removing a
volume with non-max volume number (see hammer_ioc_volume_add()).