tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[PATCH] Fixing soft NFS umount -f, round 3



Third attempt at fixing forced unmount for soft NFS mounts:
http://ftp.espci.fr/shadow/manu/umount_f3.patch

- The removal of sync(2) call in umount(8) has already been committed
and is not included in the patch anymore

- This new patch only touches NFS code. Fixing a small mistake from
previous patch made the genfs change useless.

- I uncovered a rare race condition, where nfsiod would use a nfs_mount
after it was freed. This patch adds a nfs_iodbusy() function to check
whether an nfsiod has a nfs_mount reference pending so that it can be
drained.

That patch fixes force unmount of NFS soft mounts, but I still have a
few areas of concerns

1) When mounting with -o intr, we have situation where force unmount
will not work: if ioflush is waiting on an unresponsive server, we
cannot interrupt it as it is a kernel thread

A possible workaround would be to set a non null slptimeo when
nmp->nm_flag & NFSMNT_INTR just like we do if nmp->nm_flag & NFSMNT_SOFT
in this patch. That would ensuire ioflush would not wait forever.
Opinions?

2) When umounting a soft mount, running the mount(8) command to see what
is going on will hang until unmount completes. This is because we go
through sys_getvfsstat/do_sys_getvfsstat/vfs_busy and wait for
mp->mnt_unmounting. It can be long until we get a timeout. We come there
with ST_NOWAIT, it would be nice to avoid waiting. 

This could be fixed somehow like this. It is probably broken, and fails
to print anything about the unmounting filesystem, but perhaps we can
improve on it?

Index: vfs_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.499
diff -u -4 -r1.499 vfs_syscalls.c
--- vfs_syscalls.c      12 Jun 2015 19:06:32 -0000      1.499
+++ vfs_syscalls.c      28 Jun 2015 17:06:31 -0000
@@ -1246,8 +1246,12 @@
        maxcount = bufsize / entry_sz;
        mutex_enter(&mountlist_lock);
        count = 0;
        for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
+               if (flags & ST_NOWAIT && mp->mnt_iflag & IMNT_UNMOUNT) {
+                       nmp = TAILQ_NEXT(mp, mnt_list);
+                       continue;
+               }
                if (vfs_busy(mp, &nmp)) {
                        continue;
                }
                if (sfsp && count < maxcount) {


-- 
Emmanuel Dreyfus
http://hcpnet.free.fr/pubz
manu%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index