mountd: can't delete exports for ... Invalid argument

Andreas Longwitz longwitz at incore.de
Mon Aug 12 14:50:08 UTC 2013


I have a lot of messages like

mountd[2596]: can't delete exports for
/home/poudriere/data/build/j8sp64-PT2/01/new_packages: Invalid argument

in /var/log/messages on my server running poudriere and NFS (same server
as described in PR kern/180060). The poudriere software does a lot of
mount/umounts on zfs and nullfs file systems. After every successfull
mount the mount program sends SIGHUP to mountd. mountd starts calling
getmntinfo() to get a list of all mounts in the system (ca. 50 on my
system) and continues with nmount("update, export, export.ex_flags =
MNT_DELEXPORT") for every mountpoint in the system. If poudriere has
just unmounted a filesystem in the time gap between getmntinfo() and
nmount() then mountd prints the error message complaining about Invalid
argument.

In the described situation the kernel returns on the nmount() with
EINVAL in vfs_mount.c, because the concerned vnode is not the root of
the filesystem any more:

   /*
    * Get vnode to be covered
    */
    NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, UIO_SYSSPACE,
        fspath, td);
    if ((error = namei(&nd)) != 0)
            return (error);
    NDFREE(&nd, NDF_ONLY_PNBUF);
    vp = nd.ni_vp;
    if (fsflags & MNT_UPDATE) {
            if ((vp->v_vflag & VV_ROOT) == 0) {
                   vput(vp);
                   return (EINVAL);
            }

With the following patch mountd ignores the kernel returncode and I see
no "can't delete exports" messages anymore.

--- vfs_mount.c.1st     2013-04-03 20:01:16.000000000 +0200
+++ vfs_mount.c 2013-08-12 14:57:06.000000000 +0200
@@ -900,7 +900,11 @@
        if (fsflags & MNT_UPDATE) {
                if ((vp->v_vflag & VV_ROOT) == 0) {
                        vput(vp);
-                       return (EINVAL);
+                       if ((vfs_copyopt(fsdata, "export", &export,
sizeof(export)) == 0)
+                           && (export.ex_flags & MNT_DELEXPORT))
+                               return (ENOENT);
+                       else
+                               return (EINVAL);
                }
                mp = vp->v_mount;
                MNT_ILOCK(mp);

Maybe the kernel can return ENOENT instead of EINVAL all the time, but I
am not quite sure.

-- 
Andreas Longwitz



More information about the freebsd-fs mailing list