mount / unmount and mountcheckdirs()

Andriy Gapon avg at FreeBSD.org
Sun May 15 13:42:51 UTC 2016


I am curious about the purpose of mountcheckdirs() called when mounting and
unmounting a filesystem.

The function is described as such:
/*
 * Scan all active processes and prisons to see if any of them have a current
 * or root directory of `olddp'. If so, replace them with the new mount point.
 */
and it seems to be used to "lift" processes and jails to a root of a new
filesystem when it is mounted and to "lower" them onto a covered vnode (if any)
when a filesystem is unmounted.

What's the purpose of those actions?
It's strange that the machinations are done at all, but it is stranger that they
are applied only to processes and jails at exactly a covered vnode and a root
vnode.  Anything below in a filesystem's tree is left alone.  Is there anything
so very special about being at exactly those points?

IMO, the machinations can have unexpected security consequences.

A little bit of history.
mountcheckdirs() was first added in r22521 (circa 1997) as checkdirs with a
rather non-specific commit message.  Initially it was used only when a
filesystem was mounted.
Then, in r73241 (circa 2002) the function was added to dounmount():
    The checkdirs() function is called at mount time to find any process
    fd_cdir or fd_rdir pointers referencing the covered mountpoint
    vnode. It transfers these to point at the root of the new filesystem.
    However, this process was not reversed at unmount time, so processes
    with a cwd/root at a mount point would unexpectedly lose their
    cwd/root following a mount-unmount cycle at that mountpoint.
...
    Dounmount() now undoes the actions
    taken by checkdirs() at mount time; any process cdir/rdir pointers
    that reference the root vnode of the unmounted filesystem are
    transferred to the now-uncovered vnode.


-- 
Andriy Gapon


More information about the freebsd-fs mailing list