diff options
-rw-r--r-- | sbin/mount_unionfs/mount_unionfs.c | 34 | ||||
-rw-r--r-- | sys/fs/unionfs/union.h | 1 | ||||
-rw-r--r-- | sys/fs/unionfs/union_vfsops.c | 21 |
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: |