For nmount(), allow a text string error message to be propagated back
to user-space if a parameter named "errmsg" is passed into the iovec. Used in conjunction with vfs_mount_error(), more useful error messages than errno can be passed back to userspace when mounting a filesystem fails. Discussed with: phk, pjd
This commit is contained in:
parent
90e0829525
commit
4560dfb5b1
@ -390,6 +390,18 @@ nmount(td, uap)
|
||||
iov++;
|
||||
}
|
||||
error = vfs_donmount(td, uap->flags, auio);
|
||||
|
||||
/* copyout the errmsg */
|
||||
for (i = 0; (error != 0) && (i < iovcnt); i += 2) {
|
||||
const char *name = (const char *)auio->uio_iov[i].iov_base;
|
||||
if (!strcmp(name, "errmsg")) {
|
||||
copyout(auio->uio_iov[i+1].iov_base,
|
||||
uap->iovp[i+1].iov_base, uap->iovp[i+1].iov_len);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(auio, M_IOV);
|
||||
return (error);
|
||||
}
|
||||
@ -464,8 +476,15 @@ static int
|
||||
vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions)
|
||||
{
|
||||
struct vfsoptlist *optlist;
|
||||
struct iovec *iov_errmsg = NULL;
|
||||
char *fstype, *fspath;
|
||||
int error, fstypelen, fspathlen;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < fsoptions->uio_iovcnt; i += 2) {
|
||||
if (!strcmp((char *)fsoptions->uio_iov[i].iov_base, "errmsg"))
|
||||
iov_errmsg = &fsoptions->uio_iov[i+1];
|
||||
}
|
||||
|
||||
error = vfs_buildopts(fsoptions, &optlist);
|
||||
if (error)
|
||||
@ -480,12 +499,18 @@ vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions)
|
||||
error = vfs_getopt(optlist, "fstype", (void **)&fstype, &fstypelen);
|
||||
if (error || fstype[fstypelen - 1] != '\0') {
|
||||
error = EINVAL;
|
||||
if (iov_errmsg)
|
||||
strncpy((char *)iov_errmsg->iov_base, "Invalid fstype",
|
||||
iov_errmsg->iov_len);
|
||||
goto bail;
|
||||
}
|
||||
fspathlen = 0;
|
||||
error = vfs_getopt(optlist, "fspath", (void **)&fspath, &fspathlen);
|
||||
if (error || fspath[fspathlen - 1] != '\0') {
|
||||
error = EINVAL;
|
||||
if (iov_errmsg != NULL)
|
||||
strncpy((char *)iov_errmsg->iov_base, "Invalid fspath",
|
||||
iov_errmsg->iov_len);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
@ -503,6 +528,17 @@ vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions)
|
||||
error = vfs_domount(td, fstype, fspath, fsflags, optlist);
|
||||
mtx_unlock(&Giant);
|
||||
bail:
|
||||
if (error && iov_errmsg != NULL) {
|
||||
/* save the errmsg */
|
||||
char *errmsg;
|
||||
int len, ret;
|
||||
ret = vfs_getopt(optlist, "errmsg", (void **)&errmsg, &len);
|
||||
if(ret == 0 && len > 0)
|
||||
strncpy((char *)iov_errmsg->iov_base, errmsg,
|
||||
iov_errmsg->iov_len);
|
||||
|
||||
}
|
||||
|
||||
if (error)
|
||||
vfs_freeopts(optlist);
|
||||
return (error);
|
||||
@ -1195,9 +1231,8 @@ vfs_mount_error(struct mount *mp, const char *fmt, ...)
|
||||
char *errmsg;
|
||||
|
||||
error = vfs_getopt(moptlist, "errmsg", (void **)&errmsg, &len);
|
||||
if (error || errmsg == NULL || len <= 0) {
|
||||
if (error || errmsg == NULL || len <= 0)
|
||||
return;
|
||||
}
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(errmsg, (size_t)len, fmt, ap);
|
||||
|
Loading…
Reference in New Issue
Block a user