From: Karel Zak Date: Tue, 3 Mar 2020 10:39:10 +0000 (+0100) Subject: libmount: try read-only mount on write-protected superblock too X-Git-Tag: v2.36-rc1~200 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=11b916cdabd9f57a4cddf10fd743af2165930dcd;p=thirdparty%2Futil-linux.git 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 --- diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c index 0c4b7657bb..efd70502a7 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 698b0f0115..eddf05a2f5 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.