100 lines
3.7 KiB
Diff
100 lines
3.7 KiB
Diff
From 11b916cdabd9f57a4cddf10fd743af2165930dcd Mon Sep 17 00:00:00 2001
|
|
From: Karel Zak <kzak@redhat.com>
|
|
Date: Tue, 3 Mar 2020 11:39:10 +0100
|
|
Subject: [PATCH] libmount: try read-only mount on write-protected superblock
|
|
too
|
|
|
|
The classic mount(8) behavior is to try read-only on write-protected devices
|
|
if the first mount syscall attempt ends with EACCES.
|
|
|
|
It seems we can implement this feature also for EBUSY if the same mount source
|
|
is already mounted with "ro" superblock option.
|
|
|
|
The typical use-case is iso image (always read-only) mounted on two places.
|
|
|
|
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1809124
|
|
Signed-off-by: Karel Zak <kzak@redhat.com>
|
|
---
|
|
libmount/src/context_mount.c | 21 ++++++++++++++++++---
|
|
sys-utils/mount.8 | 13 +++++++++----
|
|
2 files changed, 27 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c
|
|
index 0c4b765..efd7050 100644
|
|
--- a/libmount/src/context_mount.c
|
|
+++ b/libmount/src/context_mount.c
|
|
@@ -1149,6 +1149,18 @@ static struct libmnt_fs *get_already_mounted_source(struct libmnt_context *cxt)
|
|
return NULL;
|
|
}
|
|
|
|
+/*
|
|
+ * Checks if source filesystem superblock is already ro-mounted. Note that we
|
|
+ * care about FS superblock as VFS node is irrelevant here.
|
|
+ */
|
|
+static int is_source_already_rdonly(struct libmnt_context *cxt)
|
|
+{
|
|
+ struct libmnt_fs *fs = get_already_mounted_source(cxt);
|
|
+ const char *opts = fs ? mnt_fs_get_fs_options(fs) : NULL;
|
|
+
|
|
+ return opts && mnt_optstr_get_option(opts, "ro", NULL, NULL) == 0;
|
|
+}
|
|
+
|
|
/**
|
|
* mnt_context_finalize_mount:
|
|
* @cxt: context
|
|
@@ -1250,11 +1262,14 @@ again:
|
|
rc = mnt_context_update_tabs(cxt);
|
|
|
|
/*
|
|
- * Read-only device; try mount filesystem read-only
|
|
+ * Read-only device or already read-only mounted FS.
|
|
+ * Try mount the filesystem read-only.
|
|
*/
|
|
if ((rc == -EROFS && !mnt_context_syscall_called(cxt)) /* before syscall; rdonly loopdev */
|
|
|| mnt_context_get_syscall_errno(cxt) == EROFS /* syscall failed with EROFS */
|
|
- || mnt_context_get_syscall_errno(cxt) == EACCES) /* syscall failed with EACCES */
|
|
+ || mnt_context_get_syscall_errno(cxt) == EACCES /* syscall failed with EACCES */
|
|
+ || (mnt_context_get_syscall_errno(cxt) == EBUSY /* already ro-mounted FS */
|
|
+ && is_source_already_rdonly(cxt)))
|
|
{
|
|
unsigned long mflags = 0;
|
|
|
|
@@ -1630,7 +1645,7 @@ int mnt_context_get_mount_excode(
|
|
* Libmount success && syscall success.
|
|
*/
|
|
if (buf && mnt_context_forced_rdonly(cxt))
|
|
- snprintf(buf, bufsz, _("WARNING: device write-protected, mounted read-only"));
|
|
+ snprintf(buf, bufsz, _("WARNING: source write-protected, mounted read-only"));
|
|
return MNT_EX_SUCCESS;
|
|
}
|
|
|
|
diff --git a/sys-utils/mount.8 b/sys-utils/mount.8
|
|
index 698b0f0..eddf05a 100644
|
|
--- a/sys-utils/mount.8
|
|
+++ b/sys-utils/mount.8
|
|
@@ -931,12 +931,17 @@ Mount the partition that has the specified
|
|
Verbose mode.
|
|
.TP
|
|
.BR \-w , " \-\-rw" , " \-\-read\-write"
|
|
-Mount the filesystem read/write. The read-write is kernel default. A synonym is
|
|
+Mount the filesystem read/write. The read-write is kernel default and
|
|
+.BR mount (8)
|
|
+default is to try read-only if the previous mount syscall with read-write flags
|
|
+on write-protected devices of filesystems failed.
|
|
+.sp
|
|
+A synonym is
|
|
.BR "\-o rw" .
|
|
|
|
-Note that specify \fB\-w\fR on command line forces \fBmount\fR command
|
|
-to never try read-only mount on write-protected devices. The default is
|
|
-try read-only if the previous mount syscall with read-write flags failed.
|
|
+Note that specify \fB\-w\fR on command line forces \fBmount\fR command to never
|
|
+try read-only mount on write-protected devices or already mounted read-only
|
|
+filesystems.
|
|
.TP
|
|
.BR \-V , " \-\-version"
|
|
Display version information and exit.
|
|
--
|
|
1.8.3.1
|
|
|