sfs is conceptually similar to gfs, but the former is written from scratch
for FreeBSD VFS. gfs comes from illumos and it had to be patched heavily
to work with FreeBSD VFS. Because of that it diverged quite a lot from
the original. But despite that it still didn't comply fully with FreeBSD
VFS. sfs should be cleaner and more correct.
zfsctl (.zfs) is switched to use sfs instead of gfs.
Some highlights.
sfs provides for two types of nodes, static and on-demand. The static nodes
are used for permanent directories like .zfs, .zfs/snapshot, etc. The
on-demand nodes are used for ephemeral directories that act as snapshot
mount points.
Initially only static nodes are created. Their vnodes are instantiated
when they are looked up. The on-demand nodes and vnodes are instantiated
as needed.
When a filesystem is unmount all snapshots under .zfs are unmounted first,
then all vnodes are flushed and finally the static .zfs vnodes are
destroyed.
There are some changes outside of zfsctl code too.
z_ctldir is never used directly (as it is an opaque sfs_node_t pointer),
zfsctl_root() has to be used instead.
zfsctl_root_lookup() is retired, instead of it VOP_LOOKUP() on the .zfs
vnode (obtained with zfsctl_root) is used.