kern/150206: nmount(2): can't switch root partition to rw using
mount flags
Aurelien Jarno
aurelien at aurel32.net
Wed Sep 1 22:50:02 UTC 2010
>Number: 150206
>Category: kern
>Synopsis: nmount(2): can't switch root partition to rw using mount flags
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Sep 01 22:50:01 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator: Aurelien Jarno
>Release: 8.1
>Organization:
>Environment:
FreeBSD freebsd.aurel32.net 8.1-RELEASE FreeBSD 8.1-RELEASE #0: Mon Jul 19 02:55:53 UTC 2010 root at almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386
>Description:
The nmount(2) syscall can take filesystem options in two different ways: either via the mount flags or via iovec.
When trying to switch a root partition from ro to rw using mount flags only (this is done for example by busybox to avoid diverging to much from the Linux code), that is using MNT_UPDATE but not MNT_RDONLY, this operation is ignored. This work correctly on a non-root filesystem though.
>How-To-Repeat:
>Fix:
Patch is attached.
Patch attached with submission follows:
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -559,10 +559,10 @@
struct vfsopt *opt, *noro_opt, *tmp_opt;
char *fstype, *fspath, *errmsg;
int error, fstypelen, fspathlen, errmsg_len, errmsg_pos;
- int has_rw, has_noro;
+ int has_noro;
errmsg = fspath = NULL;
- errmsg_len = has_noro = has_rw = fspathlen = 0;
+ errmsg_len = has_noro = fspathlen = 0;
errmsg_pos = -1;
error = vfs_buildopts(fsoptions, &optlist);
@@ -659,10 +659,8 @@
fsflags &= ~MNT_RDONLY;
has_noro = 1;
}
- else if (strcmp(opt->name, "rw") == 0) {
+ else if (strcmp(opt->name, "rw") == 0)
fsflags &= ~MNT_RDONLY;
- has_rw = 1;
- }
else if (strcmp(opt->name, "ro") == 0)
fsflags |= MNT_RDONLY;
else if (strcmp(opt->name, "rdonly") == 0) {
@@ -684,7 +682,7 @@
* 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) {
+ if (!(fsflags & MNT_RDONLY) && !has_noro) {
noro_opt = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK);
noro_opt->name = strdup("noro", M_MOUNT);
noro_opt->value = NULL;
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list