Subject: Interface to change NFS exports
To: None <tech-kern@netbsd.org>
From: Julio M. Merino Vidal <jmmv84@gmail.com>
List: tech-kern
Date: 09/11/2005 13:20:58
Hi everybody,

while adding NFS support to tmpfs, I found that the current way to
change NFS export information is... how could I say it... very ugly.
It seems to be a bandaid over what was used in the past to mount
FFS systems, which makes it confusing and difficult to extend.
(Don't we aim for clean design? ;-)

First of all, the mountd(8) code expects that all file system's
mount arguments structures start with the following fields:

char *fspec;
struct export_args *export;

This is because it defines a big union of all known file systems,
assuming that all of them have these two fields at the very
beginning.  Furthermore, mountd(8) must know about all
NFS-aware file systems, needing patching every time you add
a new one.  (There are XXX marks in the code saying that this
should be improved.)

Then we get to the kernel part.  The MNT_UPDATE flag is
abused, together with the fspec field, to change the export
information.  A file system has to assume that, if MNT_UPDATE
is given and fspec is NULL, then it has to update the export
data.

Updating NFS export information is common to all NFS-aware
file systems, so I believe this can be abstracted into the VFS
layer to simplify the code in each file system.

What I have done is the following:

- Define two new mount flags, MNT_GETEXPORT and MNT_SETEXPORT.
  These change the semantics of the data parameter passed to
  mount(2), making it receive a struct export_args structure instead
  of the file system's custom one.  The purpose of each of them is
  clear from their name.

- Change the mount syscall routine to recognize these two flags
  and handle them completely on its own (the underlying fs never
  sees them).  It only needs to fetch a structure from userland and
  parse it or viceversa.

- As a side effect, as the information is now available in the generic
  mount point structure, define a vfs_stdcheckexp routine that can
  be used in most file systems (haven't checked yet if this will be
  useful in all cases), thus removing redundancy from them all.

- Simplify mountd(8) a lot by removing al fs-specific details from it,
  using struct export_args exclusively as a way to communicate
  between userland and the kernel.

- Remove NFS-specific bits from the mount_* utilities, as this can
  now be done as a default operation during the initial mount.

I don't know if this is the best way to do this (and the patch is
not yet "clean" [*]), so comments will be appreciated.  Even though,
I feel this is far better than the current approach.

As a proof of concept, I've converted ffs and tmpfs to follow these
ideas.  Note how the code is simpler overall.  The patch can be
found here:

    ftp://ftp.NetBSD.org/pub/NetBSD/misc/jmmv/export.diff

[*] I specially don't like very much the new mnt_nfs boolean flag,
    but couldn't find a better place for it.

Please comment.

Thank you,

--=20
Julio M. Merino Vidal <jmmv84@gmail.com>
http://www.livejournal.com/users/jmmv/
The NetBSD Project - http://www.NetBSD.org/