Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp674356imm; Wed, 18 Jul 2018 08:47:40 -0700 (PDT) X-Google-Smtp-Source: AAOMgpepltdz8D4pcmzoNoz40FaYXC56jW6Njgs/BjrYj/Uz4cfXS7pGwDqym9Mc4hWmr6+usCw1 X-Received: by 2002:a63:d518:: with SMTP id c24-v6mr6332487pgg.357.1531928860545; Wed, 18 Jul 2018 08:47:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531928860; cv=none; d=google.com; s=arc-20160816; b=biOtLSVWFQplsM550UhYwU1iIiwS4MS7FLwn4IISPbHEhNob93q8QJMRzK9dkJ8gMD Kzvl1Ag/NoTsiJvbJrSXlZEQw+ICJMS27pHADXzWhNQDdkSxAQzbuGfcXzxUTyAcCXyo 7Dq0+qpT3Md2yEvblnwv3/2ZbI+DQkhdQQ8GajaAOJ3sI66/tmXO0/QuOqDZ8R7D7EDp /Uz3WrwT1b7VQfh8/hU7jDw/JM/KLY7ewt7KWR0UQ8hSZa2mpsVyA1ovYB0L0CKM7HYp JDKdGPx8x5iU4vkHVOIi6s9yal3MvPVcTiOa2ujYHNJpA/mTquMXFZTbl9pX50y0IXse mWww== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :arc-authentication-results; bh=6UJBXYdZP+k+ZkiiwKeu0yb3LJS54AlqlSDRKQ5Am98=; b=MusUU8TQbJknBqLhpE+rZ3Bz7FGUx6IO+texTsAsGsgEyFimgwLsq+EZNTDT1S6Cx9 NrlhYo+6lswDW6bHrEI7rCYaKxPOQk2hySQ2U5F03tvkKzHwdiB0CwIlfYcYo4oaEp96 RUbI4onU4fmjXtKhePx3jyWmPZdoUStpufj7ZuF+uoX+HcUbX8z9wh40ERwfoC43T+Oy +6tJFqLWgy5ZRk/f6NN0wXow6O3Zmg+1TfWYhwc6A9v4ClCGCIAWomVL5ZPaLIBvqMGc tetoy3MnDMlNhSj59ztXFVZndU24/zifaQEO1PrJsMwF6OpUE64X02WhBBUwKWbC9JMM ZXcg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x3-v6si3665423pfj.289.2018.07.18.08.47.25; Wed, 18 Jul 2018 08:47:40 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731235AbeGRQZP (ORCPT + 99 others); Wed, 18 Jul 2018 12:25:15 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:35239 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730672AbeGRQZO (ORCPT ); Wed, 18 Jul 2018 12:25:14 -0400 Received: by mail-wm0-f68.google.com with SMTP id y22-v6so3410228wma.0 for ; Wed, 18 Jul 2018 08:46:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=6UJBXYdZP+k+ZkiiwKeu0yb3LJS54AlqlSDRKQ5Am98=; b=JrBuf4Ne121Yd77XflC7angosPREcgqJcJTkVRnLXahxowujWPxhihjnH5qUFldogS +iEXbIz2pwoJ6fTHIbZ/a/+Qy6pB/nkTS8q8iCJShkyDtN96PmMcNptZKk2GDFmjyyyV bhBOAKnw2Y/tWK9BPs0gfbEt9Zko7sscFpTtNyVWgNPFsUSBe1ApPoKydDGZeUcpDtgw Z1h60YCC1akMTl6Dvmz6IVfrf2aSG6DEdu83lE3uL3KUGUsGlmf58ANay0KC1LsOz6pk pb4GwsVwogRFzM6jHc0G81SGERQrQcM7HOmwu+rZlmwl0FDS3l2LbXn/opQ+6o79frF+ C1+A== X-Gm-Message-State: AOUpUlHsgPnqusiDiId9ESXv5OSqiAw8Ko0GOUIbFLSpLlUyztCWc4vD /O17Nachhaxutw33Vij3eABmeA== X-Received: by 2002:a1c:2d54:: with SMTP id t81-v6mr2076647wmt.31.1531928802067; Wed, 18 Jul 2018 08:46:42 -0700 (PDT) Received: from veci.piliscsaba.redhat.com (catv-212-96-48-140.catv.broadband.hu. [212.96.48.140]) by smtp.gmail.com with ESMTPSA id r17-v6sm5580197wrt.44.2018.07.18.08.46.40 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 18 Jul 2018 08:46:41 -0700 (PDT) From: Miklos Szeredi To: Al Viro Cc: linux-unionfs@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH] vfs: make open_with_fake_path() not contribute to nr_files Date: Wed, 18 Jul 2018 17:46:37 +0200 Message-Id: <20180718154637.31878-1-mszeredi@redhat.com> X-Mailer: git-send-email 2.14.3 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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. Signed-off-by: Miklos Szeredi --- fs/file_table.c | 69 +++++++++++++++++++++++++++++++++++++----------------- fs/internal.h | 1 + fs/open.c | 2 +- include/linux/fs.h | 3 +++ 4 files changed, 53 insertions(+), 22 deletions(-) diff --git a/fs/file_table.c b/fs/file_table.c index 9b70ed2bbc4e..0cc7bea6b51a 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -52,7 +52,8 @@ static void file_free_rcu(struct rcu_head *head) static inline void file_free(struct file *f) { security_file_free(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); } @@ -91,6 +92,34 @@ int proc_nr_files(struct ctl_table *table, int write, } #endif +static struct file *__alloc_file(int flags, const struct cred *cred) +{ + struct file *f; + int error; + + f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL); + if (unlikely(!f)) + return ERR_PTR(-ENOMEM); + + f->f_cred = get_cred(cred); + error = security_file_alloc(f); + if (unlikely(error)) { + file_free_rcu(&f->f_u.fu_rcuhead); + return ERR_PTR(error); + } + + atomic_long_set(&f->f_count, 1); + rwlock_init(&f->f_owner.lock); + spin_lock_init(&f->f_lock); + mutex_init(&f->f_pos_lock); + eventpoll_init_file(f); + f->f_flags = flags; + f->f_mode = OPEN_FMODE(flags); + /* f->f_version: 0 */ + + return f; +} + /* Find an unused file structure and return a pointer to it. * Returns an error pointer if some error happend e.g. we over file * structures limit, run out of memory or operation is not permitted. @@ -105,7 +134,6 @@ struct file *alloc_empty_file(int flags, const struct cred *cred) { static long old_max; struct file *f; - int error; /* * Privileged users can go above max_files @@ -119,26 +147,10 @@ struct file *alloc_empty_file(int flags, const struct cred *cred) goto over; } - f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL); - if (unlikely(!f)) - return ERR_PTR(-ENOMEM); - - f->f_cred = get_cred(cred); - error = security_file_alloc(f); - if (unlikely(error)) { - file_free_rcu(&f->f_u.fu_rcuhead); - return ERR_PTR(error); - } + f = __alloc_file(flags, cred); + if (!IS_ERR(f)) + percpu_counter_inc(&nr_files); - atomic_long_set(&f->f_count, 1); - rwlock_init(&f->f_owner.lock); - spin_lock_init(&f->f_lock); - mutex_init(&f->f_pos_lock); - eventpoll_init_file(f); - f->f_flags = flags; - f->f_mode = OPEN_FMODE(flags); - /* f->f_version: 0 */ - percpu_counter_inc(&nr_files); return f; over: @@ -150,6 +162,21 @@ struct file *alloc_empty_file(int flags, const struct cred *cred) return ERR_PTR(-ENFILE); } +/* + * Variant of alloc_empty_file() that doesn't check and modify nr_files. + * + * Should not be used unless there's a very good reason to do so. + */ +struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred) +{ + struct file *f = __alloc_file(flags, cred); + + if (!IS_ERR(f)) + f->f_mode |= FMODE_NOACCOUNT; + + return f; +} + /** * alloc_file - allocate and initialize a 'struct file' * diff --git a/fs/internal.h b/fs/internal.h index 52a346903748..442098fa0a84 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -94,6 +94,7 @@ extern void chroot_fs_refs(const struct path *, const struct path *); * file_table.c */ extern struct file *alloc_empty_file(int, const struct cred *); +extern struct file *alloc_empty_file_noaccount(int, const struct cred *); /* * super.c diff --git a/fs/open.c b/fs/open.c index dd15711eb658..9c6617dbb2c0 100644 --- a/fs/open.c +++ b/fs/open.c @@ -928,7 +928,7 @@ EXPORT_SYMBOL(dentry_open); struct file *open_with_fake_path(const struct path *path, int flags, struct inode *inode, const struct cred *cred) { - struct file *f = alloc_empty_file(flags, cred); + struct file *f = alloc_empty_file_noaccount(flags, cred); if (!IS_ERR(f)) { int error; diff --git a/include/linux/fs.h b/include/linux/fs.h index 5ce2b413abc6..e1884840d556 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -156,6 +156,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)0x20000000) + /* * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector * that indicates that they should check the contents of the iovec are -- 2.14.3