Page MenuHomeFreeBSD

D13361.id40320.diff
No OneTemporary

D13361.id40320.diff

Index: sys/kern/vfs_mount.c
===================================================================
--- sys/kern/vfs_mount.c
+++ sys/kern/vfs_mount.c
@@ -546,6 +546,31 @@
uma_zfree(mount_zone, mp);
}
+static bool
+vfs_should_downgrade_to_ro_mount(uint64_t fsflags, int error)
+{
+ /* This is an upgrade of an exisiting mount. */
+ if ((fsflags & MNT_UPDATE) != 0)
+ return (false);
+ /* This is already an R/O mount. */
+ if ((fsflags & MNT_RDONLY) != 0)
+ return (false);
+
+ switch (error) {
+ case ENODEV: /* generic, geom, ... */
+ case EACCES: /* cam/scsi, ... */
+ case EROFS: /* md, mmcsd, ... */
+ /*
+ * These errors can be returned by the storage layer to signal
+ * that the media is read-only. No harm in the R/O mount
+ * attempt if the error is returned for some other reason.
+ */
+ return (true);
+ default:
+ return (false);
+ }
+}
+
int
vfs_donmount(struct thread *td, uint64_t fsflags, struct uio *fsoptions)
{
@@ -553,10 +578,12 @@
struct vfsopt *opt, *tmp_opt;
char *fstype, *fspath, *errmsg;
int error, fstypelen, fspathlen, errmsg_len, errmsg_pos;
+ int force_rw;
errmsg = fspath = NULL;
errmsg_len = fspathlen = 0;
errmsg_pos = -1;
+ force_rw = 0;
error = vfs_buildopts(fsoptions, &optlist);
if (error)
@@ -648,16 +675,23 @@
free(opt->name, M_MOUNT);
opt->name = strdup("nonosymfollow", M_MOUNT);
}
- else if (strcmp(opt->name, "noro") == 0)
+ else if (strcmp(opt->name, "noro") == 0) {
fsflags &= ~MNT_RDONLY;
- else if (strcmp(opt->name, "rw") == 0)
+ force_rw = 1;
+ }
+ else if (strcmp(opt->name, "rw") == 0) {
fsflags &= ~MNT_RDONLY;
- else if (strcmp(opt->name, "ro") == 0)
+ force_rw = 1;
+ }
+ else if (strcmp(opt->name, "ro") == 0) {
fsflags |= MNT_RDONLY;
+ force_rw = 0;
+ }
else if (strcmp(opt->name, "rdonly") == 0) {
free(opt->name, M_MOUNT);
opt->name = strdup("ro", M_MOUNT);
fsflags |= MNT_RDONLY;
+ force_rw = 0;
}
else if (strcmp(opt->name, "suiddir") == 0)
fsflags |= MNT_SUIDDIR;
@@ -682,6 +716,18 @@
}
error = vfs_domount(td, fstype, fspath, fsflags, &optlist);
+
+ /*
+ * See if we can mount in the read-only mode if the error code suggests
+ * that it could be possible and the mount options allow for that.
+ * Never try it if 'rw' or 'noro' have been explicitly requested.
+ */
+ if (!force_rw && vfs_should_downgrade_to_ro_mount(fsflags, error)) {
+ printf("%s: R/W mount failed, possibly R/O media,"
+ " trying R/O mount\n", __func__);
+ fsflags |= MNT_RDONLY;
+ error = vfs_domount(td, fstype, fspath, fsflags, &optlist);
+ }
bail:
/* copyout the errmsg */
if (errmsg_pos != -1 && ((2 * errmsg_pos + 1) < fsoptions->uio_iovcnt)

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 7, 8:30 AM (5 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31021005
Default Alt Text
D13361.id40320.diff (2 KB)

Event Timeline