sys/vfs/hammer: Fix mount issue after volume-del
authorTomohiro Kusumi <kusumi.tomohiro@gmail.com>
Mon, 3 Aug 2015 11:01:48 +0000 (20:01 +0900)
committerTomohiro Kusumi <kusumi.tomohiro@gmail.com>
Sat, 8 Aug 2015 17:32:24 +0000 (02:32 +0900)
commit78249d7f7c218296742a9f9c46fa094704306a4d
tree5b8e25de6486de4bfc81605f8a6547b6cac0c2ce
parent5185d7e14350cf040c5731edcbe186cf1216a7b3
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()).
sys/vfs/hammer/hammer.h
sys/vfs/hammer/hammer_ondisk.c