Subject: Re: PR 698
To: None <gnats-bugs@netbsd.org>
From: Simon J. Gerraty <sjg@quick.com.au>
List: tech-kern
Date: 11/23/1999 01:56:21
[cc'd tech-kern in case anyone has any better ideas]

> So, w.r.t. PR 698, why should there be an 
> umount_{ffs,nfs,null,union,etc}, other than symmetry with mount? What 
> does there need to be done to unmount any of the filesystem that we 
> now support, besides calling unmount(2)?

Firstly umount_* need only exist if there is something meaningful for
it to do.  Take snfs as an example (http://www.quick.com.au/Products/sNFS.html)

This filesystem implements NFS over SSL.  The client snfsc does the
talking to the remote machine and tells the kernel to mount an "NFS" fs
using a handle that points at its own socket.  This is a pretty
standard way of implementing "interesting" filesystems without need
for the client OS to support anything but NFS over udp.

In the case of snfs there is no portmap involved - snfsd runs
under inetd and won't grok anything that does not arrive over the
encrypted channel.

This means that on NetBSD, while you can arrange for mount /foo to
work - by invoking mount_snfs, umount /foo will _not_ work as the only
thing the kernel knows about is an NFS mount, and umount(8) because it
"knows" NFS, attempts to send an MOUNTPROC_UMNT rpc to the server -
which is doomed to fail.

On systems like SunOS, Solaris etc which record the mount options
somewhere outside the kernel and will invoke umount_snfs things work
much better.

I understand why NetBSD stores the stuff in the kernel and agree that
it is better.  But we still lose due to the lack of info stored.  On
NetBSD you simply find the pid of the snfsc process and kill it -
shuts down the connection to the server and then dags around until it
can extricate itself from the kernel.  It would be wonderful if all
umount(2)'s took an option to say - "for heaven sake, no further
operations are going to work so just forget about this mount point!"
:-)

I don't claim to know what the correct solution is btw but
one approach I thought of was to add a couple of fields to struct
statfs.  Hmm I see that f_fstypename[] is already there (its been some
years since I looked), which may be part of what I want, but I can't
find where the values for f_type are defined - which I presume is what
the kernel cares about?

Ie. if f_type were set to indicate NFS and f_fstypename could be set
to indicate the real fs type, then the correct umount_foo could be
found.  If that is not the correct use of those fields, then perhaps a
new field is needed.

If we also had say f_mntopts[MNAMELEN] to record the mount options
needed to ensure that umount_foo could do its thing (just the snfsc
pid would do for umount_snfs) then we'd be in business.  Note that the
content of f_mntopts[] need only be meaningful to umount_foo.

Of course one then needs a means of getting the extra info into the
kernel.  

We'd need to either:

1. add an extra arg to mount(2) which could be null.
2. add a struct statfs* (which could be null) to struct nfs_args etc.
3. make the arg passed to mount(2)  something like:

struct dummyfs_args {
	struct statfs *sfs;
	void *data;	/* the real data for sfs->f_type */
};

there may well be a better option that I've not thought of.
I'd expect that each of the above has disadvantages.

Hope that helps.

--sjg