summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorrodrigc <rodrigc@FreeBSD.org>2005-11-09 02:26:38 +0000
committerrodrigc <rodrigc@FreeBSD.org>2005-11-09 02:26:38 +0000
commit2cbc12617e8c6974b4bda15456acae526d368800 (patch)
tree8eddfac7b29b5a7fad453c44b20affc562348555 /sys/kern
parent709559d97f388b2395bb9ba4b76d96975cbb5113 (diff)
downloadFreeBSD-src-2cbc12617e8c6974b4bda15456acae526d368800.zip
FreeBSD-src-2cbc12617e8c6974b4bda15456acae526d368800.tar.gz
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
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/vfs_mount.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 508fd7b..449231f 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -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);
OpenPOWER on IntegriCloud