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.
This commit is contained in:
parent
b1825f705f
commit
00b6b34450
@ -215,48 +215,34 @@ kernel_mount(iovp, iovcnt, flags)
|
|||||||
int
|
int
|
||||||
kernel_vmount(int flags, ...)
|
kernel_vmount(int flags, ...)
|
||||||
{
|
{
|
||||||
struct iovec *iovp, *iov;
|
struct iovec *iovp;
|
||||||
struct uio auio;
|
struct uio auio;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
unsigned int iovcnt, iovlen, len, optcnt;
|
unsigned int iovcnt, iovlen, len;
|
||||||
const char *opt;
|
const char *cp;
|
||||||
char *sep, *buf, *pos;
|
char *buf, *pos;
|
||||||
int error, i;
|
int error, i, n;
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
va_start(ap, flags);
|
va_start(ap, flags);
|
||||||
for (optcnt = 0; (opt = va_arg(ap, const char *)) != NULL; optcnt++)
|
for (iovcnt = 0; (cp = va_arg(ap, const char *)) != NULL; iovcnt++)
|
||||||
len += strlen(opt) + 1;
|
len += strlen(cp) + 1;
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
if (optcnt < 2)
|
if (iovcnt < 4 || iovcnt & 1)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
iovcnt = optcnt << 1;
|
|
||||||
iovlen = iovcnt * sizeof (struct iovec);
|
iovlen = iovcnt * sizeof (struct iovec);
|
||||||
MALLOC(iovp, struct iovec *, iovlen, M_MOUNT, M_WAITOK);
|
MALLOC(iovp, struct iovec *, iovlen, M_MOUNT, M_WAITOK);
|
||||||
MALLOC(buf, char *, len, M_MOUNT, M_WAITOK);
|
MALLOC(buf, char *, len, M_MOUNT, M_WAITOK);
|
||||||
pos = buf;
|
pos = buf;
|
||||||
va_start(ap, flags);
|
va_start(ap, flags);
|
||||||
for (i = 0; i < optcnt; i++) {
|
for (i = 0; i < iovcnt; i++) {
|
||||||
opt = va_arg(ap, const char *);
|
cp = va_arg(ap, const char *);
|
||||||
strcpy(pos, opt);
|
copystr(cp, pos, len - (pos - buf), &n);
|
||||||
sep = index(pos, '=');
|
iovp[i].iov_base = pos;
|
||||||
if (sep == NULL) {
|
iovp[i].iov_len = n;
|
||||||
FREE(iovp, M_MOUNT);
|
pos += n;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
@ -550,7 +536,16 @@ update:
|
|||||||
if (mp->mnt_op->vfs_mount != NULL) {
|
if (mp->mnt_op->vfs_mount != NULL) {
|
||||||
printf("%s doesn't support the new mount syscall\n",
|
printf("%s doesn't support the new mount syscall\n",
|
||||||
mp->mnt_vfc->vfc_name);
|
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);
|
vput(vp);
|
||||||
error = EOPNOTSUPP;
|
error = EOPNOTSUPP;
|
||||||
goto bad;
|
goto bad;
|
||||||
@ -889,7 +884,16 @@ update:
|
|||||||
if (mp->mnt_op->vfs_mount == NULL) {
|
if (mp->mnt_op->vfs_mount == NULL) {
|
||||||
printf("%s doesn't support the old mount syscall\n",
|
printf("%s doesn't support the old mount syscall\n",
|
||||||
mp->mnt_vfc->vfc_name);
|
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);
|
vput(vp);
|
||||||
return (EOPNOTSUPP);
|
return (EOPNOTSUPP);
|
||||||
}
|
}
|
||||||
|
@ -215,48 +215,34 @@ kernel_mount(iovp, iovcnt, flags)
|
|||||||
int
|
int
|
||||||
kernel_vmount(int flags, ...)
|
kernel_vmount(int flags, ...)
|
||||||
{
|
{
|
||||||
struct iovec *iovp, *iov;
|
struct iovec *iovp;
|
||||||
struct uio auio;
|
struct uio auio;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
unsigned int iovcnt, iovlen, len, optcnt;
|
unsigned int iovcnt, iovlen, len;
|
||||||
const char *opt;
|
const char *cp;
|
||||||
char *sep, *buf, *pos;
|
char *buf, *pos;
|
||||||
int error, i;
|
int error, i, n;
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
va_start(ap, flags);
|
va_start(ap, flags);
|
||||||
for (optcnt = 0; (opt = va_arg(ap, const char *)) != NULL; optcnt++)
|
for (iovcnt = 0; (cp = va_arg(ap, const char *)) != NULL; iovcnt++)
|
||||||
len += strlen(opt) + 1;
|
len += strlen(cp) + 1;
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
if (optcnt < 2)
|
if (iovcnt < 4 || iovcnt & 1)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
iovcnt = optcnt << 1;
|
|
||||||
iovlen = iovcnt * sizeof (struct iovec);
|
iovlen = iovcnt * sizeof (struct iovec);
|
||||||
MALLOC(iovp, struct iovec *, iovlen, M_MOUNT, M_WAITOK);
|
MALLOC(iovp, struct iovec *, iovlen, M_MOUNT, M_WAITOK);
|
||||||
MALLOC(buf, char *, len, M_MOUNT, M_WAITOK);
|
MALLOC(buf, char *, len, M_MOUNT, M_WAITOK);
|
||||||
pos = buf;
|
pos = buf;
|
||||||
va_start(ap, flags);
|
va_start(ap, flags);
|
||||||
for (i = 0; i < optcnt; i++) {
|
for (i = 0; i < iovcnt; i++) {
|
||||||
opt = va_arg(ap, const char *);
|
cp = va_arg(ap, const char *);
|
||||||
strcpy(pos, opt);
|
copystr(cp, pos, len - (pos - buf), &n);
|
||||||
sep = index(pos, '=');
|
iovp[i].iov_base = pos;
|
||||||
if (sep == NULL) {
|
iovp[i].iov_len = n;
|
||||||
FREE(iovp, M_MOUNT);
|
pos += n;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
@ -550,7 +536,16 @@ update:
|
|||||||
if (mp->mnt_op->vfs_mount != NULL) {
|
if (mp->mnt_op->vfs_mount != NULL) {
|
||||||
printf("%s doesn't support the new mount syscall\n",
|
printf("%s doesn't support the new mount syscall\n",
|
||||||
mp->mnt_vfc->vfc_name);
|
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);
|
vput(vp);
|
||||||
error = EOPNOTSUPP;
|
error = EOPNOTSUPP;
|
||||||
goto bad;
|
goto bad;
|
||||||
@ -889,7 +884,16 @@ update:
|
|||||||
if (mp->mnt_op->vfs_mount == NULL) {
|
if (mp->mnt_op->vfs_mount == NULL) {
|
||||||
printf("%s doesn't support the old mount syscall\n",
|
printf("%s doesn't support the old mount syscall\n",
|
||||||
mp->mnt_vfc->vfc_name);
|
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);
|
vput(vp);
|
||||||
return (EOPNOTSUPP);
|
return (EOPNOTSUPP);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user