diff options
author | rodrigc <rodrigc@FreeBSD.org> | 2006-05-14 01:51:38 +0000 |
---|---|---|
committer | rodrigc <rodrigc@FreeBSD.org> | 2006-05-14 01:51:38 +0000 |
commit | c3b6d6664791c450e208950b4b1f0740cf51d170 (patch) | |
tree | bcfe94fddc30bdc073cb58290f8ca1e35ddbef8b /sys | |
parent | 7015de091f9c60233dbeaec478ad3ad9297bd07e (diff) | |
download | FreeBSD-src-c3b6d6664791c450e208950b4b1f0740cf51d170.zip FreeBSD-src-c3b6d6664791c450e208950b4b1f0740cf51d170.tar.gz |
For nmount(), if "rw" is specified as a mount option,
add "noro" to the list of mount options. This allows
a read-only mount to be converted to read-write via:
mount -u -o rw
Requested by: kris
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_mount.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 688ce8f..1d1cc6c 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -566,12 +566,15 @@ static int vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions) { struct vfsoptlist *optlist; - struct vfsopt *opt; + struct vfsopt *opt, *noro_opt; char *fstype, *fspath, *errmsg; int error, fstypelen, fspathlen, errmsg_len, errmsg_pos; + int has_rw, has_noro; errmsg_len = 0; errmsg_pos = -1; + has_rw = 0; + has_noro = 0; error = vfs_buildopts(fsoptions, &optlist); if (error) @@ -633,9 +636,14 @@ vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions) fsflags |= MNT_NOSUID; else if (strcmp(opt->name, "nosymfollow") == 0) fsflags |= MNT_NOSYMFOLLOW; - else if (strcmp(opt->name, "noro") == 0 || - strcmp(opt->name, "rw") == 0) + else if (strcmp(opt->name, "noro") == 0) { + fsflags &= ~MNT_RDONLY; + has_noro = 1; + } + else if (strcmp(opt->name, "rw") == 0) { fsflags &= ~MNT_RDONLY; + has_rw = 1; + } else if (strcmp(opt->name, "ro") == 0 || strcmp(opt->name, "rdonly") == 0) fsflags |= MNT_RDONLY; @@ -650,6 +658,20 @@ vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions) } /* + * If "rw" was specified as a mount option, and we + * are trying to update a mount-point from "ro" to "rw", + * we need a mount option "noro", since in vfs_mergeopts(), + * "noro" will cancel "ro", but "rw" will not do anything. + */ + if (has_rw && !has_noro) { + noro_opt = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK); + noro_opt->name = strdup("noro", M_MOUNT); + noro_opt->value = NULL; + noro_opt->len = 0; + TAILQ_INSERT_TAIL(optlist, noro_opt, link); + } + + /* * Be ultra-paranoid about making sure the type and fspath * variables will fit in our mp buffers, including the * terminating NUL. |