Mountd iterating over the mount points may race with the parallel

unmount, which causes error from nmount(2) call when performing
MNT_DELEXPORT over the directory which ceased to be a mount point.

The race is legitimate and innocent, but results in the chatty mountd.
Silence it by providing an distinguished error code for the situation,
and ignoring the error in mountd loop.

Based on the patch by:	Andreas Longwitz <longwitz@incore.de>
Prodded and tested by:	bdrewery
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
This commit is contained in:
Konstantin Belousov 2015-02-10 18:00:32 +00:00
parent 29836e077a
commit 5d6f5b24ca
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=278523
2 changed files with 13 additions and 3 deletions

View File

@ -888,12 +888,18 @@ vfs_domount_update(
ASSERT_VOP_ELOCKED(vp, __func__);
KASSERT((fsflags & MNT_UPDATE) != 0, ("MNT_UPDATE should be here"));
mp = vp->v_mount;
if ((vp->v_vflag & VV_ROOT) == 0) {
if (vfs_copyopt(*optlist, "export", &export, sizeof(export))
== 0)
error = EXDEV;
else
error = EINVAL;
vput(vp);
return (EINVAL);
return (error);
}
mp = vp->v_mount;
/*
* We only allow the filesystem to be reloaded if it
* is currently mounted read-only.

View File

@ -1747,8 +1747,12 @@ get_exportlist(void)
iov[5].iov_len = strlen(fsp->f_mntfromname) + 1;
errmsg[0] = '\0';
/*
* EXDEV is returned when path exists but is not a
* mount point. May happens if raced with unmount.
*/
if (nmount(iov, iovlen, fsp->f_flags) < 0 &&
errno != ENOENT && errno != ENOTSUP) {
errno != ENOENT && errno != ENOTSUP && errno != EXDEV) {
syslog(LOG_ERR,
"can't delete exports for %s: %m %s",
fsp->f_mntonname, errmsg);