All of lore.kernel.org
 help / color / mirror / Atom feed
From: Miklos Szeredi <mszeredi@redhat.com>
To: linux-unionfs@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 26/39] ovl: copy-up on MAP_SHARED
Date: Tue, 29 May 2018 16:43:26 +0200	[thread overview]
Message-ID: <20180529144339.16538-27-mszeredi@redhat.com> (raw)
In-Reply-To: <20180529144339.16538-1-mszeredi@redhat.com>

A corner case of a corner case is when

 - file opened for O_RDONLY
 - which is then memory mapped SHARED
 - file opened for O_WRONLY
 - contents modified
 - contents read back though the shared mapping

Unfortunately it looks very difficult to do anything about the established
shared map after the file is copied up.

Instead, when a read-only file is mapped shared, copy up the file before
actually doing the map.  This may result in unnecessary copy-ups (but so
may copy-up on open(O_RDWR) for exampe).

We can revisit this later if it turns out to be a performance problem in
real life.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
---
 fs/overlayfs/Kconfig     | 21 +++++++++++++++++++++
 fs/overlayfs/file.c      | 22 ++++++++++++++++++++++
 fs/overlayfs/overlayfs.h |  7 +++++++
 fs/overlayfs/ovl_entry.h |  1 +
 fs/overlayfs/super.c     | 22 ++++++++++++++++++++++
 5 files changed, 73 insertions(+)

diff --git a/fs/overlayfs/Kconfig b/fs/overlayfs/Kconfig
index 17032631c5cf..5d1d40d745c5 100644
--- a/fs/overlayfs/Kconfig
+++ b/fs/overlayfs/Kconfig
@@ -103,3 +103,24 @@ config OVERLAY_FS_XINO_AUTO
 	  For more information, see Documentation/filesystems/overlayfs.txt
 
 	  If unsure, say N.
+
+config OVERLAY_FS_COPY_UP_SHARED
+	bool "Overlayfs: copy up when mapping a file shared"
+	default n
+	depends on OVERLAY_FS
+	help
+	  If this option is enabled then on mapping a file with MAP_SHARED
+	  overlayfs copies up the file in anticipation of it being modified
+	  (just like we copy up the file on O_WRONLY and O_RDWR in anticipation
+	  of modification).  This does not interfere with shared library
+	  loading, as that uses MAP_PRIVATE.  But there might be use cases out
+	  there where this impacts performance and disk usage.
+
+	  This just selects the default, the feature can also be enabled or
+	  disabled in the running kernel or individually on each overlay mount.
+
+	  To get maximally standard compliant behavior, enable this option.
+
+	  To get a maximally backward compatible kernel, disable this option.
+
+	  If unsure, say N.
diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
index ef4bcc80572f..266692ce9a9a 100644
--- a/fs/overlayfs/file.c
+++ b/fs/overlayfs/file.c
@@ -10,6 +10,7 @@
 #include <linux/file.h>
 #include <linux/mount.h>
 #include <linux/xattr.h>
+#include <linux/mman.h>
 #include <linux/uio.h>
 #include "overlayfs.h"
 
@@ -259,6 +260,26 @@ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
 	return ret;
 }
 
+static int ovl_pre_mmap(struct file *file, unsigned long prot,
+			unsigned long flag)
+{
+	int err = 0;
+
+	/*
+	 * Take MAP_SHARED as hint about future writes to the file (through
+	 * another file descriptor).  Caller might not have had such an intent,
+	 * but we hope MAP_PRIVATE will be used in most such cases.
+	 *
+	 * If we don't copy up now and the file is modified, it becomes really
+	 * difficult to change the mapping to match that of the file's content
+	 * later.
+	 */
+	if ((flag & MAP_SHARED) && ovl_copy_up_shared(file_inode(file)->i_sb))
+		err = ovl_copy_up(file_dentry(file));
+
+	return err;
+}
+
 static int ovl_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	struct fd real;
@@ -476,6 +497,7 @@ const struct file_operations ovl_file_operations = {
 	.read_iter	= ovl_read_iter,
 	.write_iter	= ovl_write_iter,
 	.fsync		= ovl_fsync,
+	.pre_mmap	= ovl_pre_mmap,
 	.mmap		= ovl_mmap,
 	.fallocate	= ovl_fallocate,
 	.unlocked_ioctl	= ovl_ioctl,
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 3f6e39a2f51e..be4f1664f662 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -266,6 +266,13 @@ static inline unsigned int ovl_xino_bits(struct super_block *sb)
 	return ofs->xino_bits;
 }
 
+static inline bool ovl_copy_up_shared(struct super_block *sb)
+{
+	struct ovl_fs *ofs = sb->s_fs_info;
+
+	return !(sb->s_flags & SB_RDONLY) && ofs->config.copy_up_shared;
+}
+
 
 /* namei.c */
 int ovl_check_fh_len(struct ovl_fh *fh, int fh_len);
diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h
index 41655a7d6894..3bea47c63fd9 100644
--- a/fs/overlayfs/ovl_entry.h
+++ b/fs/overlayfs/ovl_entry.h
@@ -18,6 +18,7 @@ struct ovl_config {
 	const char *redirect_mode;
 	bool index;
 	bool nfs_export;
+	bool copy_up_shared;
 	int xino;
 };
 
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 211975921a90..900ed4c39919 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -56,6 +56,12 @@ module_param_named(xino_auto, ovl_xino_auto_def, bool, 0644);
 MODULE_PARM_DESC(ovl_xino_auto_def,
 		 "Auto enable xino feature");
 
+static bool ovl_copy_up_shared_def =
+	IS_ENABLED(CONFIG_OVERLAY_FS_COPY_UP_SHARED);
+module_param_named(copy_up_shared, ovl_copy_up_shared_def, bool, 0644);
+MODULE_PARM_DESC(ovl_copy_up_shared_def,
+		 "Copy up when mapping a file shared");
+
 static void ovl_entry_stack_free(struct ovl_entry *oe)
 {
 	unsigned int i;
@@ -380,6 +386,9 @@ static int ovl_show_options(struct seq_file *m, struct dentry *dentry)
 						"on" : "off");
 	if (ofs->config.xino != ovl_xino_def())
 		seq_printf(m, ",xino=%s", ovl_xino_str[ofs->config.xino]);
+	if (ofs->config.copy_up_shared != ovl_copy_up_shared_def)
+		seq_printf(m, ",copy_up_shared=%s",
+			   ofs->config.copy_up_shared ? "on" : "off");
 	return 0;
 }
 
@@ -417,6 +426,8 @@ enum {
 	OPT_XINO_ON,
 	OPT_XINO_OFF,
 	OPT_XINO_AUTO,
+	OPT_COPY_UP_SHARED_ON,
+	OPT_COPY_UP_SHARED_OFF,
 	OPT_ERR,
 };
 
@@ -433,6 +444,8 @@ static const match_table_t ovl_tokens = {
 	{OPT_XINO_ON,			"xino=on"},
 	{OPT_XINO_OFF,			"xino=off"},
 	{OPT_XINO_AUTO,			"xino=auto"},
+	{OPT_COPY_UP_SHARED_ON,		"copy_up_shared=on"},
+	{OPT_COPY_UP_SHARED_OFF,	"copy_up_shared=off"},
 	{OPT_ERR,			NULL}
 };
 
@@ -559,6 +572,14 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
 			config->xino = OVL_XINO_AUTO;
 			break;
 
+		case OPT_COPY_UP_SHARED_ON:
+			config->copy_up_shared = true;
+			break;
+
+		case OPT_COPY_UP_SHARED_OFF:
+			config->copy_up_shared = false;
+			break;
+
 		default:
 			pr_err("overlayfs: unrecognized mount option \"%s\" or missing value\n", p);
 			return -EINVAL;
@@ -1379,6 +1400,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
 	ofs->config.index = ovl_index_def;
 	ofs->config.nfs_export = ovl_nfs_export_def;
 	ofs->config.xino = ovl_xino_def();
+	ofs->config.copy_up_shared = ovl_copy_up_shared_def;
 	err = ovl_parse_opt((char *) data, &ofs->config);
 	if (err)
 		goto out_err;
-- 
2.14.3

  parent reply	other threads:[~2018-05-29 14:43 UTC|newest]

Thread overview: 90+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-29 14:43 [PATCH 00/39] overlayfs: stack file operations Miklos Szeredi
2018-05-29 14:43 ` [PATCH 01/39] vfs: dedpue: return loff_t Miklos Szeredi
2018-06-04  8:43   ` Christoph Hellwig
2018-06-04  8:43     ` [Ocfs2-devel] " Christoph Hellwig
2018-06-05  8:33     ` Miklos Szeredi
2018-06-06 15:09       ` Darrick J. Wong
2018-06-06 15:09         ` [Ocfs2-devel] " Darrick J. Wong
2018-06-18 20:08         ` Miklos Szeredi
2018-05-29 14:43 ` [PATCH 02/39] vfs: dedupe: rationalize args Miklos Szeredi
2018-06-06 15:02   ` Darrick J. Wong
2018-05-29 14:43 ` [PATCH 03/39] vfs: dedupe: extract helper for a single dedup Miklos Szeredi
2018-05-29 15:41   ` Amir Goldstein
2018-05-29 16:04     ` Amir Goldstein
2018-06-04  8:44   ` Christoph Hellwig
2018-05-29 14:43 ` [PATCH 04/39] vfs: add path_open() Miklos Szeredi
2018-06-04  8:46   ` Christoph Hellwig
2018-06-10  4:36     ` Al Viro
2018-05-29 14:43 ` [PATCH 05/39] vfs: optionally don't account file in nr_files Miklos Szeredi
2018-06-04  8:47   ` Christoph Hellwig
2018-06-04  8:57     ` Miklos Szeredi
2018-06-10  4:41   ` Al Viro
2018-05-29 14:43 ` [PATCH 06/39] vfs: add f_op->pre_mmap() Miklos Szeredi
2018-06-04  8:48   ` Christoph Hellwig
2018-06-05 11:36     ` Miklos Szeredi
2018-06-06 18:52       ` Amir Goldstein
2018-06-06 19:47         ` Miklos Szeredi
2018-06-27 12:07           ` Amir Goldstein
2018-07-20  7:18             ` Amir Goldstein
2018-07-20  8:04               ` Miklos Szeredi
2018-05-29 14:43 ` [PATCH 07/39] vfs: export vfs_ioctl() to modules Miklos Szeredi
2018-06-04  8:49   ` Christoph Hellwig
2018-06-10  4:57     ` Al Viro
2018-06-11  7:19       ` Miklos Szeredi
2018-06-11 16:24         ` Christoph Hellwig
2018-06-19 14:04           ` Miklos Szeredi
2018-06-19 14:24             ` Christoph Hellwig
2018-06-19 14:34               ` Miklos Szeredi
2018-06-19 14:54                 ` Al Viro
2018-05-29 14:43 ` [PATCH 08/39] vfs: export vfs_dedupe_file_range_one() " Miklos Szeredi
2018-05-29 14:43 ` [PATCH 09/39] ovl: copy up times Miklos Szeredi
2018-05-29 14:43 ` [PATCH 10/39] ovl: copy up inode flags Miklos Szeredi
2018-05-29 14:43 ` [PATCH 11/39] Revert "Revert "ovl: get_write_access() in truncate"" Miklos Szeredi
2018-05-29 14:43 ` [PATCH 12/39] ovl: copy up file size as well Miklos Szeredi
2018-05-29 14:43 ` [PATCH 13/39] ovl: deal with overlay files in ovl_d_real() Miklos Szeredi
2018-05-29 14:43 ` [PATCH 14/39] ovl: stack file ops Miklos Szeredi
2018-06-10  4:13   ` Al Viro
2018-06-11  7:09     ` Miklos Szeredi
2018-06-12  2:29       ` Al Viro
2018-06-12  2:40         ` Al Viro
2018-06-12  9:24           ` Miklos Szeredi
2018-06-12 18:24             ` Al Viro
2018-06-12 18:31               ` Al Viro
2018-06-13  9:21                 ` Miklos Szeredi
2018-06-15  5:47                   ` Al Viro
2018-06-18 11:50                     ` Miklos Szeredi
2018-06-13 11:56               ` J. R. Okajima
2018-05-29 14:43 ` [PATCH 15/39] ovl: add helper to return real file Miklos Szeredi
2018-06-10  5:42   ` Al Viro
2018-06-11  8:11     ` Miklos Szeredi
2018-05-29 14:43 ` [PATCH 16/39] ovl: add ovl_read_iter() Miklos Szeredi
2018-05-29 14:43 ` [PATCH 17/39] ovl: add ovl_write_iter() Miklos Szeredi
2018-05-29 14:43 ` [PATCH 18/39] ovl: add ovl_fsync() Miklos Szeredi
2018-05-29 14:43 ` [PATCH 19/39] ovl: add ovl_mmap() Miklos Szeredi
2018-06-10  5:24   ` Al Viro
2018-06-11  7:58     ` Miklos Szeredi
2018-05-29 14:43 ` [PATCH 20/39] ovl: add ovl_fallocate() Miklos Szeredi
2018-05-29 14:43 ` [PATCH 21/39] ovl: add lsattr/chattr support Miklos Szeredi
2018-05-29 14:43 ` [PATCH 22/39] ovl: add ovl_fiemap() Miklos Szeredi
2018-05-29 14:43 ` [PATCH 23/39] ovl: add O_DIRECT support Miklos Szeredi
2018-06-10  5:31   ` Al Viro
2018-06-11  8:08     ` Miklos Szeredi
2018-05-29 14:43 ` [PATCH 24/39] ovl: add reflink/copyfile/dedup support Miklos Szeredi
2018-05-29 14:43 ` [PATCH 25/39] vfs: don't open real Miklos Szeredi
2018-05-29 14:43 ` Miklos Szeredi [this message]
2018-05-29 14:43 ` [PATCH 27/39] ovl: obsolete "check_copy_up" module option Miklos Szeredi
2018-05-29 15:13   ` Amir Goldstein
2018-05-30  8:26     ` Miklos Szeredi
2018-05-29 14:43 ` [PATCH 28/39] ovl: fix documentation of non-standard behavior Miklos Szeredi
2018-05-29 14:43 ` [PATCH 29/39] vfs: simplify dentry_open() Miklos Szeredi
2018-05-29 14:43 ` [PATCH 30/39] Revert "ovl: fix may_write_real() for overlayfs directories" Miklos Szeredi
2018-05-29 14:43 ` [PATCH 31/39] Revert "ovl: don't allow writing ioctl on lower layer" Miklos Szeredi
2018-05-29 14:43 ` [PATCH 32/39] vfs: fix freeze protection in mnt_want_write_file() for overlayfs Miklos Szeredi
2018-06-04  8:50   ` Christoph Hellwig
2018-05-29 14:43 ` [PATCH 33/39] Revert "ovl: fix relatime for directories" Miklos Szeredi
2018-05-29 14:43 ` [PATCH 34/39] Revert "vfs: update ovl inode before relatime check" Miklos Szeredi
2018-05-29 14:43 ` [PATCH 35/39] Revert "vfs: add flags to d_real()" Miklos Szeredi
2018-05-29 14:43 ` [PATCH 36/39] Revert "vfs: do get_write_access() on upper layer of overlayfs" Miklos Szeredi
2018-05-29 14:43 ` [PATCH 37/39] Partially revert "locks: fix file locking on overlayfs" Miklos Szeredi
2018-05-29 14:43 ` [PATCH 38/39] Revert "fsnotify: support overlayfs" Miklos Szeredi
2018-05-29 14:43 ` [PATCH 39/39] vfs: remove open_flags from d_real() Miklos Szeredi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180529144339.16538-27-mszeredi@redhat.com \
    --to=mszeredi@redhat.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-unionfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.