aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/mount_unionfs/mount_unionfs.c34
-rw-r--r--sys/fs/unionfs/union.h1
-rw-r--r--sys/fs/unionfs/union_vfsops.c21
3 files changed, 33 insertions, 23 deletions
diff --git a/sbin/mount_unionfs/mount_unionfs.c b/sbin/mount_unionfs/mount_unionfs.c
index 44861cbb9d6d..724c9b31cbb6 100644
--- a/sbin/mount_unionfs/mount_unionfs.c
+++ b/sbin/mount_unionfs/mount_unionfs.c
@@ -52,8 +52,6 @@ static const char rcsid[] =
#include <sys/param.h>
#include <sys/mount.h>
-#include <fs/unionfs/union.h>
-
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
@@ -77,26 +75,32 @@ main(argc, argv)
char *argv[];
{
struct iovec iov[8];
- int ch, mntflags, unionflags;
+ int ch, mntflags;
char source[MAXPATHLEN];
char target[MAXPATHLEN];
struct vfsconf vfc;
- int error;
+ int error, iovcnt;
+ iovcnt = 6;
mntflags = 0;
- unionflags = UNMNT_ABOVE;
while ((ch = getopt(argc, argv, "bo:r")) != -1)
switch (ch) {
case 'b':
- unionflags &= ~UNMNT_OPMASK;
- unionflags |= UNMNT_BELOW;
+ iov[6].iov_base = "below";
+ iov[6].iov_len = strlen(iov[6].iov_base) + 1;
+ iov[7].iov_base = NULL;
+ iov[7].iov_len = 0;
+ iovcnt = 8;
break;
case 'o':
getmntopts(optarg, mopts, &mntflags, 0);
break;
case 'r':
- unionflags &= ~UNMNT_OPMASK;
- unionflags |= UNMNT_REPLACE;
+ iov[6].iov_base = "replace";
+ iov[6].iov_len = strlen(iov[6].iov_base) + 1;
+ iov[7].iov_base = NULL;
+ iov[7].iov_len = 0;
+ iovcnt = 8;
break;
case '?':
default:
@@ -128,22 +132,18 @@ main(argc, argv)
errx(EX_OSERR, "union filesystem is not available");
iov[0].iov_base = "fstype";
- iov[0].iov_len = sizeof("fstype");
+ iov[0].iov_len = strlen(iov[0].iov_base) + 1;
iov[1].iov_base = vfc.vfc_name;
iov[1].iov_len = strlen(vfc.vfc_name) + 1;
iov[2].iov_base = "fspath";
- iov[2].iov_len = sizeof("fspath");
+ iov[2].iov_len = strlen(iov[2].iov_base) + 1;
iov[3].iov_base = source;
iov[3].iov_len = strlen(source) + 1;
iov[4].iov_base = "target";
- iov[4].iov_len = sizeof("target");
+ iov[4].iov_len = strlen(iov[4].iov_base) + 1;
iov[5].iov_base = target;
iov[5].iov_len = strlen(target) + 1;
- iov[6].iov_base = "unionflags";
- iov[6].iov_len = sizeof("unionflags");
- iov[7].iov_base = (char *)&unionflags;
- iov[7].iov_len = sizeof(unionflags);
- if (nmount(iov, 8, mntflags))
+ if (nmount(iov, iovcnt, mntflags))
err(EX_OSERR, "%s", target);
exit(0);
}
diff --git a/sys/fs/unionfs/union.h b/sys/fs/unionfs/union.h
index 28e153e6c092..3a2ee2a4c4f9 100644
--- a/sys/fs/unionfs/union.h
+++ b/sys/fs/unionfs/union.h
@@ -41,7 +41,6 @@
#define UNMNT_ABOVE 0x0001 /* Target appears above mount point */
#define UNMNT_BELOW 0x0002 /* Target appears below mount point */
#define UNMNT_REPLACE 0x0003 /* Target replaces mount point */
-#define UNMNT_OPMASK 0x0003
struct union_mount {
struct vnode *um_uppervp; /* UN_ULOCK holds locking state */
diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c
index eb214e94294e..c4d362c5c267 100644
--- a/sys/fs/unionfs/union_vfsops.c
+++ b/sys/fs/unionfs/union_vfsops.c
@@ -82,7 +82,7 @@ union_mount(mp, ndp, td)
struct union_mount *um = 0;
struct ucred *cred = 0;
char *cp = 0, *target;
- int *flags;
+ int op;
int len;
u_int size;
@@ -112,9 +112,20 @@ union_mount(mp, ndp, td)
if (error || target[len - 1] != '\0')
return (EINVAL);
- error = vfs_getopt(opts, "unionflags", (void **)&flags, &len);
- if (error || len != sizeof(int))
- return (EINVAL);
+ op = 0;
+ if (vfs_getopt(opts, "below", NULL, NULL) == 0)
+ op = UNMNT_BELOW;
+ if (vfs_getopt(opts, "replace", NULL, NULL) == 0) {
+ /* These options are mutually exclusive. */
+ if (op)
+ return (EINVAL);
+ op = UNMNT_REPLACE;
+ }
+ /*
+ * UNMNT_ABOVE is the default.
+ */
+ if (op == 0)
+ op = UNMNT_ABOVE;
/*
* Obtain lower vnode. Vnode is stored in mp->mnt_vnodecovered.
@@ -184,7 +195,7 @@ union_mount(mp, ndp, td)
um = (struct union_mount *) malloc(sizeof(struct union_mount),
M_UNIONFSMNT, M_WAITOK | M_ZERO);
- um->um_op = *flags & UNMNT_OPMASK;
+ um->um_op = op;
switch (um->um_op) {
case UNMNT_ABOVE: