More details about the tmpfs fixup

Venkatesh Srinivas wrote out a long description of what he’s doing with the removal of the Giant Lock from tmpfs.  I’m pasting it here verbatim, for your enjoyment.

Each filesystem in DragonFly has a set of flags, marking whether it
needs synchronization or not. Each mounted filesystem also has a token
for per-mount synchronization.

In DragonFly, when you call a file function such as read() on a file
from the filesystem, the system calls the file’s f_ops->read() function.
For files from a real filesystem such as HAMMER or tmpfs, we call
vop_read(). vop_read() checks the flags on the filesystem; if the
filesystem flags indicate that read() is self-synchronized, the
filesystem read() method is called directly and must take care of its
own synchronization, often by taking the per-mount token. If the
filesystem read method is not marked MPSAFE, the vop_read() code
automatically takes both the MPLOCK and a per-mount token and releases
it after the filesystem read method returns.

Merely flagging a filesystem as MPSAFE and moving token get/release calls
into the per-filesystem methods would improve concurrency on the system
because per-filesystem operations wouldn’t be taking the MPLOCK. However
operations on a filesystem wouldn’t be any more concurrent — they would
be serialized by the per-mount token.

What my patches do for TMPFS is to flag the read() and strategy()
routines as MPSAFE. In tmpfs_strategy(), I serialize the entire routine
with the per-mount token. However for tmpfs_read(), I do not take the
per-mount token for reads served directly from the buffer cache. This
means that concurrent cached reads can proceed on TMPFS, as is the case
on HAMMER. These patches depended on Matt’s recent work on

The eventual goal is to remove the code in the vop_* routines that
checks flags and gets tokens and move all synchronization into each
filesystem. The code is ugly and is a very heavy hammer; each filesystem
should be able to do a better and cleaner job synchronizing itself.