diff options
author | mux <mux@FreeBSD.org> | 2002-04-07 13:22:47 +0000 |
---|---|---|
committer | mux <mux@FreeBSD.org> | 2002-04-07 13:22:47 +0000 |
commit | 00b6b344509d48b44a121b4cc49b13f5c2a7b12e (patch) | |
tree | b8641924a1992de3000787f95c4307e061ac0f45 /sys/kern | |
parent | b1825f705f4d4d8b761d19d60130f59f3597293a (diff) | |
download | FreeBSD-src-00b6b344509d48b44a121b4cc49b13f5c2a7b12e.zip FreeBSD-src-00b6b344509d48b44a121b4cc49b13f5c2a7b12e.tar.gz |
o Change kernel_vmount() interface to be more convenient : pass two
separate strings instead of passing "foo=bar".
o Don't forget to clear the VMOUNT flag on the vnode when vfs_nmount()
fails because the fs doesn't implement VFS_NMOUNT (and in vfs_mount()
when the fs doesn't implement VFS_MOUNT) ; also decrement the vfs
refcount in the !MNT_UPDATE case.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/vfs_extattr.c | 64 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 64 |
2 files changed, 68 insertions, 60 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 4308ec6..daf3ae0 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -215,48 +215,34 @@ kernel_mount(iovp, iovcnt, flags) int kernel_vmount(int flags, ...) { - struct iovec *iovp, *iov; + struct iovec *iovp; struct uio auio; va_list ap; - unsigned int iovcnt, iovlen, len, optcnt; - const char *opt; - char *sep, *buf, *pos; - int error, i; + unsigned int iovcnt, iovlen, len; + const char *cp; + char *buf, *pos; + int error, i, n; len = 0; va_start(ap, flags); - for (optcnt = 0; (opt = va_arg(ap, const char *)) != NULL; optcnt++) - len += strlen(opt) + 1; + for (iovcnt = 0; (cp = va_arg(ap, const char *)) != NULL; iovcnt++) + len += strlen(cp) + 1; va_end(ap); - if (optcnt < 2) + if (iovcnt < 4 || iovcnt & 1) return (EINVAL); - iovcnt = optcnt << 1; iovlen = iovcnt * sizeof (struct iovec); MALLOC(iovp, struct iovec *, iovlen, M_MOUNT, M_WAITOK); MALLOC(buf, char *, len, M_MOUNT, M_WAITOK); pos = buf; va_start(ap, flags); - for (i = 0; i < optcnt; i++) { - opt = va_arg(ap, const char *); - strcpy(pos, opt); - sep = index(pos, '='); - if (sep == NULL) { - FREE(iovp, M_MOUNT); - FREE(buf, M_MOUNT); - return (EINVAL); - } - *sep = '\0'; - iov = iovp + i * 2; - iov->iov_base = pos; - iov->iov_len = sep - pos + 1; - pos = sep + 1; - iov++; - iov->iov_base = pos; - iovlen = strlen(pos) + 1; - iov->iov_len = iovlen; - pos += iovlen; + for (i = 0; i < iovcnt; i++) { + cp = va_arg(ap, const char *); + copystr(cp, pos, len - (pos - buf), &n); + iovp[i].iov_base = pos; + iovp[i].iov_len = n; + pos += n; } va_end(ap); @@ -550,7 +536,16 @@ update: if (mp->mnt_op->vfs_mount != NULL) { printf("%s doesn't support the new mount syscall\n", mp->mnt_vfc->vfc_name); - vfs_unbusy(mp, td); + mtx_lock(&vp->v_interlock); + vp->v_flag &= ~VMOUNT; + mtx_unlock(&vp->v_interlock); + if (mp->mnt_flag & MNT_UPDATE) + vfs_unbusy(mp, td); + else { + mp->mnt_vfc->vfc_refcount--; + vfs_unbusy(mp, td); + free((caddr_t)mp, M_MOUNT); + } vput(vp); error = EOPNOTSUPP; goto bad; @@ -889,7 +884,16 @@ update: if (mp->mnt_op->vfs_mount == NULL) { printf("%s doesn't support the old mount syscall\n", mp->mnt_vfc->vfc_name); - vfs_unbusy(mp, td); + mtx_lock(&vp->v_interlock); + vp->v_flag &= ~VMOUNT; + mtx_unlock(&vp->v_interlock); + if (mp->mnt_flag & MNT_UPDATE) + vfs_unbusy(mp, td); + else { + mp->mnt_vfc->vfc_refcount--; + vfs_unbusy(mp, td); + free((caddr_t)mp, M_MOUNT); + } vput(vp); return (EOPNOTSUPP); } diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 4308ec6..daf3ae0 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -215,48 +215,34 @@ kernel_mount(iovp, iovcnt, flags) int kernel_vmount(int flags, ...) { - struct iovec *iovp, *iov; + struct iovec *iovp; struct uio auio; va_list ap; - unsigned int iovcnt, iovlen, len, optcnt; - const char *opt; - char *sep, *buf, *pos; - int error, i; + unsigned int iovcnt, iovlen, len; + const char *cp; + char *buf, *pos; + int error, i, n; len = 0; va_start(ap, flags); - for (optcnt = 0; (opt = va_arg(ap, const char *)) != NULL; optcnt++) - len += strlen(opt) + 1; + for (iovcnt = 0; (cp = va_arg(ap, const char *)) != NULL; iovcnt++) + len += strlen(cp) + 1; va_end(ap); - if (optcnt < 2) + if (iovcnt < 4 || iovcnt & 1) return (EINVAL); - iovcnt = optcnt << 1; iovlen = iovcnt * sizeof (struct iovec); MALLOC(iovp, struct iovec *, iovlen, M_MOUNT, M_WAITOK); MALLOC(buf, char *, len, M_MOUNT, M_WAITOK); pos = buf; va_start(ap, flags); - for (i = 0; i < optcnt; i++) { - opt = va_arg(ap, const char *); - strcpy(pos, opt); - sep = index(pos, '='); - if (sep == NULL) { - FREE(iovp, M_MOUNT); - FREE(buf, M_MOUNT); - return (EINVAL); - } - *sep = '\0'; - iov = iovp + i * 2; - iov->iov_base = pos; - iov->iov_len = sep - pos + 1; - pos = sep + 1; - iov++; - iov->iov_base = pos; - iovlen = strlen(pos) + 1; - iov->iov_len = iovlen; - pos += iovlen; + for (i = 0; i < iovcnt; i++) { + cp = va_arg(ap, const char *); + copystr(cp, pos, len - (pos - buf), &n); + iovp[i].iov_base = pos; + iovp[i].iov_len = n; + pos += n; } va_end(ap); @@ -550,7 +536,16 @@ update: if (mp->mnt_op->vfs_mount != NULL) { printf("%s doesn't support the new mount syscall\n", mp->mnt_vfc->vfc_name); - vfs_unbusy(mp, td); + mtx_lock(&vp->v_interlock); + vp->v_flag &= ~VMOUNT; + mtx_unlock(&vp->v_interlock); + if (mp->mnt_flag & MNT_UPDATE) + vfs_unbusy(mp, td); + else { + mp->mnt_vfc->vfc_refcount--; + vfs_unbusy(mp, td); + free((caddr_t)mp, M_MOUNT); + } vput(vp); error = EOPNOTSUPP; goto bad; @@ -889,7 +884,16 @@ update: if (mp->mnt_op->vfs_mount == NULL) { printf("%s doesn't support the old mount syscall\n", mp->mnt_vfc->vfc_name); - vfs_unbusy(mp, td); + mtx_lock(&vp->v_interlock); + vp->v_flag &= ~VMOUNT; + mtx_unlock(&vp->v_interlock); + if (mp->mnt_flag & MNT_UPDATE) + vfs_unbusy(mp, td); + else { + mp->mnt_vfc->vfc_refcount--; + vfs_unbusy(mp, td); + free((caddr_t)mp, M_MOUNT); + } vput(vp); return (EOPNOTSUPP); } |