summaryrefslogtreecommitdiffstats
path: root/sys
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
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')
-rw-r--r--sys/amd64/linux32/syscalls.master6
-rw-r--r--sys/compat/freebsd32/syscalls.master6
-rw-r--r--sys/i386/linux/syscalls.master6
-rw-r--r--sys/kern/syscalls.master6
-rw-r--r--sys/kern/vfs_mount.c35
5 files changed, 35 insertions, 24 deletions
diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master
index a29068a..9af73d9 100644
--- a/sys/amd64/linux32/syscalls.master
+++ b/sys/amd64/linux32/syscalls.master
@@ -75,10 +75,10 @@
19 AUE_LSEEK MSTD { int linux_lseek(l_uint fdes, l_off_t off, \
l_int whence); }
20 AUE_GETPID MSTD { int linux_getpid(void); }
-21 AUE_MOUNT STD { int linux_mount(char *specialfile, \
+21 AUE_MOUNT MSTD { int linux_mount(char *specialfile, \
char *dir, char *filesystemtype, \
l_ulong rwflag, void *data); }
-22 AUE_UMOUNT STD { int linux_oldumount(char *path); }
+22 AUE_UMOUNT MSTD { int linux_oldumount(char *path); }
23 AUE_SETUID MSTD { int linux_setuid16(l_uid16_t uid); }
24 AUE_GETUID MSTD { int linux_getuid16(void); }
25 AUE_SETTIMEOFDAY MSTD { int linux_stime(void); }
@@ -111,7 +111,7 @@
49 AUE_GETEUID MSTD { int linux_geteuid16(void); }
50 AUE_GETEGID MSTD { int linux_getegid16(void); }
51 AUE_ACCT MNOPROTO { int acct(char *path); }
-52 AUE_UMOUNT STD { int linux_umount(char *path, l_int flags); }
+52 AUE_UMOUNT MSTD { int linux_umount(char *path, l_int flags); }
53 AUE_NULL UNIMPL lock
54 AUE_IOCTL STD { int linux_ioctl(l_uint fd, l_uint cmd, \
uintptr_t arg); }
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
index 7033e9b..a0ce10b 100644
--- a/sys/compat/freebsd32/syscalls.master
+++ b/sys/compat/freebsd32/syscalls.master
@@ -79,9 +79,9 @@
int flags); }
19 AUE_LSEEK OBSOL olseek
20 AUE_GETPID MNOPROTO { pid_t getpid(void); }
-21 AUE_MOUNT NOPROTO { int mount(char *type, char *path, \
+21 AUE_MOUNT MNOPROTO { int mount(char *type, char *path, \
int flags, caddr_t data); }
-22 AUE_UMOUNT NOPROTO { int unmount(char *path, int flags); }
+22 AUE_UMOUNT MNOPROTO { int unmount(char *path, int flags); }
23 AUE_SETUID MNOPROTO { int setuid(uid_t uid); }
24 AUE_GETUID MNOPROTO { uid_t getuid(void); }
25 AUE_GETEUID MNOPROTO { uid_t geteuid(void); }
@@ -644,7 +644,7 @@
375 AUE_NULL UNIMPL nfsclnt
376 AUE_NULL MNOPROTO { int eaccess(char *path, int flags); }
377 AUE_NULL UNIMPL afs_syscall
-378 AUE_NULL NOPROTO { int nmount(struct iovec *iovp, \
+378 AUE_NULL MNOPROTO { int nmount(struct iovec *iovp, \
unsigned int iovcnt, int flags); }
379 AUE_NULL MNOPROTO { int kse_exit(void); }
380 AUE_NULL MNOPROTO { int kse_wakeup(struct kse_mailbox *mbx); }
diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master
index e5807f4..285cb66 100644
--- a/sys/i386/linux/syscalls.master
+++ b/sys/i386/linux/syscalls.master
@@ -74,10 +74,10 @@
19 AUE_LSEEK MSTD { int linux_lseek(l_uint fdes, l_off_t off, \
l_int whence); }
20 AUE_GETPID MSTD { int linux_getpid(void); }
-21 AUE_MOUNT STD { int linux_mount(char *specialfile, \
+21 AUE_MOUNT MSTD { int linux_mount(char *specialfile, \
char *dir, char *filesystemtype, \
l_ulong rwflag, void *data); }
-22 AUE_UMOUNT STD { int linux_oldumount(char *path); }
+22 AUE_UMOUNT MSTD { int linux_oldumount(char *path); }
23 AUE_SETUID MSTD { int linux_setuid16(l_uid16_t uid); }
24 AUE_GETUID MSTD { int linux_getuid16(void); }
25 AUE_SETTIMEOFDAY MSTD { int linux_stime(void); }
@@ -111,7 +111,7 @@
49 AUE_GETEUID MSTD { int linux_geteuid16(void); }
50 AUE_GETEGID MSTD { int linux_getegid16(void); }
51 AUE_ACCT MNOPROTO { int acct(char *path); }
-52 AUE_UMOUNT STD { int linux_umount(char *path, l_int flags); }
+52 AUE_UMOUNT MSTD { int linux_umount(char *path, l_int flags); }
53 AUE_NULL UNIMPL lock
54 AUE_IOCTL STD { int linux_ioctl(l_uint fd, l_uint cmd, \
l_ulong arg); }
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index c29cd2e..1209e13 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -82,10 +82,10 @@
19 AUE_LSEEK MCOMPAT { long lseek(int fd, long offset, \
int whence); }
20 AUE_GETPID MSTD { pid_t getpid(void); }
-21 AUE_MOUNT STD { int mount(char *type, char *path, \
+21 AUE_MOUNT MSTD { int mount(char *type, char *path, \
int flags, caddr_t data); }
; XXX `path' should have type `const char *' but we're not ready for that.
-22 AUE_UMOUNT STD { int unmount(char *path, int flags); }
+22 AUE_UMOUNT MSTD { int unmount(char *path, int flags); }
23 AUE_SETUID MSTD { int setuid(uid_t uid); }
24 AUE_GETUID MSTD { uid_t getuid(void); }
25 AUE_GETEUID MSTD { uid_t geteuid(void); }
@@ -662,7 +662,7 @@
375 AUE_NULL NOIMPL { int nfsclnt(int flag, caddr_t argp); }
376 AUE_EACCESS MSTD { int eaccess(char *path, int flags); }
377 AUE_NULL UNIMPL afs_syscall
-378 AUE_NMOUNT STD { int nmount(struct iovec *iovp, \
+378 AUE_NMOUNT MSTD { int nmount(struct iovec *iovp, \
unsigned int iovcnt, int flags); }
379 AUE_NULL MSTD { int kse_exit(void); }
380 AUE_NULL MSTD { int kse_wakeup(struct kse_mailbox *mbx); }
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