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,
	Al Viro <viro@zeniv.linux.org.uk>
Subject: [PATCH v2 02/35] vfs: optionally don't account file in nr_files
Date: Mon,  7 May 2018 10:37:34 +0200	[thread overview]
Message-ID: <20180507083807.28792-3-mszeredi@redhat.com> (raw)
In-Reply-To: <20180507083807.28792-1-mszeredi@redhat.com>

Stacking file operations in overlay will store an extra open file for each
overlay file opened.

The overhead is just that of "struct file" which is about 256bytes, because
overlay already pins an extra dentry and inode when the file is open, which
add up to a much larger overhead.

For fear of breaking working setups, don't start accounting the extra file.

The implementation adds a bool argument to path_open() to control whether
the returned file is to be accounted or not.  If the file is not accounted,
f_mode will contain FMODE_NOACCOUNT, so that when freeing the file the
count is not decremented.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
---
 fs/file_table.c    | 13 +++++++++----
 fs/internal.h      |  7 ++++++-
 fs/open.c          | 10 +++++-----
 include/linux/fs.h |  5 ++++-
 4 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/fs/file_table.c b/fs/file_table.c
index 7ec0b3e5f05d..60376bfa04cf 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -51,7 +51,8 @@ static void file_free_rcu(struct rcu_head *head)
 
 static inline void file_free(struct file *f)
 {
-	percpu_counter_dec(&nr_files);
+	if (!(f->f_mode & FMODE_NOACCOUNT))
+		percpu_counter_dec(&nr_files);
 	call_rcu(&f->f_u.fu_rcuhead, file_free_rcu);
 }
 
@@ -100,7 +101,7 @@ int proc_nr_files(struct ctl_table *table, int write,
  * done, you will imbalance int the mount's writer count
  * and a warning at __fput() time.
  */
-struct file *get_empty_filp(void)
+struct file *__get_empty_filp(bool account)
 {
 	const struct cred *cred = current_cred();
 	static long old_max;
@@ -110,7 +111,8 @@ struct file *get_empty_filp(void)
 	/*
 	 * Privileged users can go above max_files
 	 */
-	if (get_nr_files() >= files_stat.max_files && !capable(CAP_SYS_ADMIN)) {
+	if (account &&
+	    get_nr_files() >= files_stat.max_files && !capable(CAP_SYS_ADMIN)) {
 		/*
 		 * percpu_counters are inaccurate.  Do an expensive check before
 		 * we go and fail.
@@ -123,7 +125,10 @@ struct file *get_empty_filp(void)
 	if (unlikely(!f))
 		return ERR_PTR(-ENOMEM);
 
-	percpu_counter_inc(&nr_files);
+	if (account)
+		percpu_counter_inc(&nr_files);
+	else
+		f->f_mode = FMODE_NOACCOUNT;
 	f->f_cred = get_cred(cred);
 	error = security_file_alloc(f);
 	if (unlikely(error)) {
diff --git a/fs/internal.h b/fs/internal.h
index e08972db0303..b82725ba3054 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -93,7 +93,12 @@ extern void chroot_fs_refs(const struct path *, const struct path *);
 /*
  * file_table.c
  */
-extern struct file *get_empty_filp(void);
+extern struct file *__get_empty_filp(bool account);
+
+static inline struct file *get_empty_filp(void)
+{
+	return __get_empty_filp(true);
+}
 
 /*
  * super.c
diff --git a/fs/open.c b/fs/open.c
index d0bf7f061a1a..6e52fd6fea7c 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -732,8 +732,8 @@ static int do_dentry_open(struct file *f,
 	static const struct file_operations empty_fops = {};
 	int error;
 
-	f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK |
-				FMODE_PREAD | FMODE_PWRITE;
+	f->f_mode = (f->f_mode & FMODE_NOACCOUNT) | OPEN_FMODE(f->f_flags) |
+		FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
 
 	path_get(&f->f_path);
 	f->f_inode = inode;
@@ -743,7 +743,7 @@ static int do_dentry_open(struct file *f,
 	f->f_wb_err = filemap_sample_wb_err(f->f_mapping);
 
 	if (unlikely(f->f_flags & O_PATH)) {
-		f->f_mode = FMODE_PATH;
+		f->f_mode = (f->f_mode & FMODE_NOACCOUNT) | FMODE_PATH;
 		f->f_op = &empty_fops;
 		goto done;
 	}
@@ -917,12 +917,12 @@ int vfs_open(const struct path *path, struct file *file,
  * Return: A pointer to a struct file or an IS_ERR pointer.  Cannot return NULL.
  */
 struct file *path_open(const struct path *path, int flags, struct inode *inode,
-		       const struct cred *cred)
+		       const struct cred *cred, bool account)
 {
 	struct file *file;
 	int retval;
 
-	file = get_empty_filp();
+	file = __get_empty_filp(account);
 	if (IS_ERR(file))
 		return file;
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index d97a661342c8..af49b55ff439 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -153,6 +153,9 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 /* File is capable of returning -EAGAIN if I/O will block */
 #define FMODE_NOWAIT	((__force fmode_t)0x8000000)
 
+/* File does not contribute to nr_files count */
+#define FMODE_NOACCOUNT	((__force fmode_t)0x10000000)
+
 /*
  * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector
  * that indicates that they should check the contents of the iovec are
@@ -2402,7 +2405,7 @@ extern struct file *file_open_root(struct dentry *, struct vfsmount *,
 				   const char *, int, umode_t);
 extern struct file * dentry_open(const struct path *, int, const struct cred *);
 extern struct file *path_open(const struct path *, int, struct inode *,
-			      const struct cred *);
+			      const struct cred *, bool);
 extern int filp_close(struct file *, fl_owner_t id);
 
 extern struct filename *getname_flags(const char __user *, int, int *);
-- 
2.14.3

  parent reply	other threads:[~2018-05-07  8:37 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-07  8:37 [PATCH v2 00/35] overlayfs: stack file operations Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 01/35] vfs: add path_open() Miklos Szeredi
2018-05-07  8:37 ` Miklos Szeredi [this message]
2018-05-07  8:37 ` [PATCH v2 03/35] vfs: add f_op->pre_mmap() Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 04/35] vfs: export vfs_ioctl() to modules Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 05/35] vfs: export vfs_dedupe_file_range_one() " Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 06/35] ovl: copy up times Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 07/35] ovl: copy up inode flags Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 08/35] Revert "Revert "ovl: get_write_access() in truncate"" Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 09/35] ovl: copy up file size as well Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 10/35] ovl: deal with overlay files in ovl_d_real() Miklos Szeredi
2018-05-07 13:17   ` Vivek Goyal
2018-05-07  8:37 ` [PATCH v2 11/35] ovl: stack file ops Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 12/35] ovl: add helper to return real file Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 13/35] ovl: add ovl_read_iter() Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 14/35] ovl: add ovl_write_iter() Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 15/35] ovl: add ovl_fsync() Miklos Szeredi
2018-05-08  5:14   ` Amir Goldstein
2018-05-08 14:57     ` Miklos Szeredi
2018-05-08 15:02       ` Amir Goldstein
2018-05-07  8:37 ` [PATCH v2 16/35] ovl: add ovl_mmap() Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 17/35] ovl: add ovl_fallocate() Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 18/35] ovl: add lsattr/chattr support Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 19/35] ovl: add ovl_fiemap() Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 20/35] ovl: add O_DIRECT support Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 21/35] ovl: add reflink/copyfile/dedup support Miklos Szeredi
2018-05-07 20:43   ` Darrick J. Wong
2018-05-08 14:13     ` Miklos Szeredi
2018-05-08 14:38       ` Darrick J. Wong
2018-05-07  8:37 ` [PATCH v2 22/35] vfs: don't open real Miklos Szeredi
2018-05-07 10:27   ` Amir Goldstein
2018-05-07 10:29     ` Miklos Szeredi
2018-05-11 18:54   ` Vivek Goyal
2018-05-11 18:54     ` Vivek Goyal
2018-05-11 19:42     ` Vivek Goyal
2018-05-11 19:42       ` Vivek Goyal
2018-05-14 13:58       ` Vivek Goyal
2018-05-14 13:58         ` Vivek Goyal
2018-05-15 20:42         ` Vivek Goyal
2018-05-15 20:42           ` Vivek Goyal
2018-05-14 14:03       ` Daniel Walsh
2018-05-14 14:03         ` Daniel Walsh
2018-05-07  8:37 ` [PATCH v2 23/35] ovl: copy-up on MAP_SHARED Miklos Szeredi
2018-05-07 19:28   ` Randy Dunlap
2018-05-08 15:03     ` Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 24/35] vfs: simplify dentry_open() Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 25/35] Revert "ovl: fix may_write_real() for overlayfs directories" Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 26/35] Revert "ovl: don't allow writing ioctl on lower layer" Miklos Szeredi
2018-05-07  8:37 ` [PATCH v2 27/35] vfs: fix freeze protection in mnt_want_write_file() for overlayfs Miklos Szeredi
2018-05-07  8:38 ` [PATCH v2 28/35] Revert "ovl: fix relatime for directories" Miklos Szeredi
2018-05-07  8:38 ` [PATCH v2 29/35] Revert "vfs: update ovl inode before relatime check" Miklos Szeredi
2018-05-07  8:38 ` [PATCH v2 30/35] Revert "vfs: add flags to d_real()" Miklos Szeredi
2018-05-07  8:38 ` [PATCH v2 31/35] Revert "vfs: do get_write_access() on upper layer of overlayfs" Miklos Szeredi
2018-05-07  8:38 ` [PATCH v2 32/35] Partially revert "locks: fix file locking on overlayfs" Miklos Szeredi
2018-05-08 15:15   ` Jeff Layton
2018-05-07  8:38 ` [PATCH v2 33/35] Revert "fsnotify: support overlayfs" Miklos Szeredi
2018-05-07  8:38 ` [PATCH v2 34/35] vfs: remove open_flags from d_real() Miklos Szeredi
2018-05-07  8:38 ` [PATCH v2 35/35] ovl: fix documentation of non-standard behavior 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=20180507083807.28792-3-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 \
    --cc=viro@zeniv.linux.org.uk \
    /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.