summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_mount.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2006-06-27 14:46:31 +0000
committerjhb <jhb@FreeBSD.org>2006-06-27 14:46:31 +0000
commit5ceeece21bffcdccb3823f3ec15fdfee5c78ccf4 (patch)
treed5a08cf255dc8bc07767dea638e8aefbdc9bba89 /sys/kern/vfs_mount.c
parentac91121b51ad6277ad5b07ba3cca46ef2ccb0a70 (diff)
downloadFreeBSD-src-5ceeece21bffcdccb3823f3ec15fdfee5c78ccf4.zip
FreeBSD-src-5ceeece21bffcdccb3823f3ec15fdfee5c78ccf4.tar.gz
- Expand the scope of Giant some in mount(2) to protect the vfsp structure
from going away. mount(2) is now MPSAFE. - Expand the scope of Giant some in unmount(2) to protect the mp structure (or rather, to handle concurrent unmount races) from going away. umount(2) is now MPSAFE, as well as linux_umount() and linux_oldumount(). - nmount(2) and linux_mount() were already MPSAFE.
Diffstat (limited to 'sys/kern/vfs_mount.c')
-rw-r--r--sys/kern/vfs_mount.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 66a2fea..cd725ba 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -744,19 +744,23 @@ mount(td, uap)
fstype = malloc(MFSNAMELEN, M_TEMP, M_WAITOK);
error = copyinstr(uap->type, fstype, MFSNAMELEN, NULL);
- if (!error) {
- AUDIT_ARG(text, fstype);
- mtx_lock(&Giant); /* XXX ? */
- vfsp = vfs_byname_kld(fstype, td, &error);
- mtx_unlock(&Giant);
+ if (error) {
+ free(fstype, M_TEMP);
+ return (error);
}
+
+ AUDIT_ARG(text, fstype);
+ mtx_lock(&Giant);
+ vfsp = vfs_byname_kld(fstype, td, &error);
free(fstype, M_TEMP);
- if (error)
- return (error);
- if (vfsp == NULL)
+ if (vfsp == NULL) {
+ mtx_unlock(&Giant);
return (ENOENT);
- if (vfsp->vfc_vfsops->vfs_cmount == NULL)
+ }
+ if (vfsp->vfc_vfsops->vfs_cmount == NULL) {
+ mtx_unlock(&Giant);
return (EOPNOTSUPP);
+ }
ma = mount_argsu(ma, "fstype", uap->type, MNAMELEN);
ma = mount_argsu(ma, "fspath", uap->path, MNAMELEN);
@@ -765,6 +769,7 @@ mount(td, uap)
ma = mount_argb(ma, !(uap->flags & MNT_NOEXEC), "noexec");
error = vfsp->vfc_vfsops->vfs_cmount(ma, uap->data, uap->flags, td);
+ mtx_unlock(&Giant);
return (error);
}
@@ -1063,9 +1068,11 @@ unmount(td, uap)
return (error);
}
AUDIT_ARG(upath, td, pathbuf, ARG_UPATH1);
+ mtx_lock(&Giant);
if (uap->flags & MNT_BYFSID) {
/* Decode the filesystem ID. */
if (sscanf(pathbuf, "FSID:%d:%d", &id0, &id1) != 2) {
+ mtx_unlock(&Giant);
free(pathbuf, M_TEMP);
return (EINVAL);
}
@@ -1093,6 +1100,7 @@ unmount(td, uap)
* now, so in the !MNT_BYFSID case return the more likely
* EINVAL for compatibility.
*/
+ mtx_unlock(&Giant);
return ((uap->flags & MNT_BYFSID) ? ENOENT : EINVAL);
}
@@ -1101,15 +1109,18 @@ unmount(td, uap)
* original mount is permitted to unmount this filesystem.
*/
error = vfs_suser(mp, td);
- if (error)
+ if (error) {
+ mtx_unlock(&Giant);
return (error);
+ }
/*
* Don't allow unmounting the root filesystem.
*/
- if (mp->mnt_flag & MNT_ROOTFS)
+ if (mp->mnt_flag & MNT_ROOTFS) {
+ mtx_unlock(&Giant);
return (EINVAL);
- mtx_lock(&Giant);
+ }
error = dounmount(mp, uap->flags, td);
mtx_unlock(&Giant);
return (error);
OpenPOWER on IntegriCloud