From patchwork Sun Jan 5 12:06:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Down X-Patchwork-Id: 11318181 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9B0A313A0 for ; Sun, 5 Jan 2020 12:06:04 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 5F216206F0 for ; Sun, 5 Jan 2020 12:06:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chrisdown.name header.i=@chrisdown.name header.b="d5rTJdZZ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5F216206F0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=chrisdown.name Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id A7AA88E0008; Sun, 5 Jan 2020 07:06:03 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id A2BD58E0003; Sun, 5 Jan 2020 07:06:03 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 91C378E0008; Sun, 5 Jan 2020 07:06:03 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0227.hostedemail.com [216.40.44.227]) by kanga.kvack.org (Postfix) with ESMTP id 7B8248E0003 for ; Sun, 5 Jan 2020 07:06:03 -0500 (EST) Received: from smtpin17.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with SMTP id 23915180AD801 for ; Sun, 5 Jan 2020 12:06:03 +0000 (UTC) X-FDA: 76343452206.17.rat82_8c11ef0354c61 X-Spam-Summary: 2,0,0,0db3a3c9f212142f,d41d8cd98f00b204,chris@chrisdown.name,::hughd@google.com:akpm@linux-foundation.org:viro@zeniv.linux.org.uk:willy@infradead.org:amir73il@gmail.com:jlayton@kernel.org:hannes@cmpxchg.org:tj@kernel.org:linux-fsdevel@vger.kernel.org:linux-kernel@vger.kernel.org:kernel-team@fb.com,RULES_HIT:41:355:379:800:960:966:973:988:989:1260:1277:1312:1313:1314:1345:1359:1431:1437:1516:1518:1519:1535:1544:1593:1594:1595:1596:1605:1711:1730:1747:1777:1792:2196:2198:2199:2200:2393:2559:2562:2910:3138:3139:3140:3141:3142:3865:3866:3867:3868:3870:3871:3872:3874:4118:4321:4385:4605:5007:6119:6261:6653:6742:7514:7875:7903:8603:9010:10004:11026:11232:11658:11914:12043:12291:12296:12297:12517:12519:12555:12683:12895:12986:13439:13846:13895:14096:14097:14181:14394:14721:21080:21433:21444:21451:21627:21990:30012:30034:30054:30064,0,RBL:209.85.221.65:@chrisdown.name:.lbl8.mailshell.net-62.2.0.100 66.100.201.201,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainC ache:0,M X-HE-Tag: rat82_8c11ef0354c61 X-Filterd-Recvd-Size: 7022 Received: from mail-wr1-f65.google.com (mail-wr1-f65.google.com [209.85.221.65]) by imf15.hostedemail.com (Postfix) with ESMTP for ; Sun, 5 Jan 2020 12:06:02 +0000 (UTC) Received: by mail-wr1-f65.google.com with SMTP id q10so7654133wrm.11 for ; Sun, 05 Jan 2020 04:06:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chrisdown.name; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=PyXhwAP0dYhaGmqpZ7PAPREHaom0BNi3zqsng9yVMcQ=; b=d5rTJdZZQpgUNSTm+xzjt/ISjZG8hkHvPnXc0PLs9c3qT7xcatTLfIveeIFwRr3Ogu gwu08CadMR/UGVLZV0bKzQOjZfXOa7OmNbboL927Ip01LCce95NMQQjLLvoiTLzzdP9Q lMCs0wvsHVdDWnO+0uoDCDzd7uxvSWB1viKlQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=PyXhwAP0dYhaGmqpZ7PAPREHaom0BNi3zqsng9yVMcQ=; b=d5bcA/wjxryivSoCkm0X0gE7QUfYBufKTQe9bgUGz34O7/oERSQuH6UedgWpGxeY99 H4xAOk+TROnweNXME1/xqrMY2QirNvUFze4U9IS9FCMOWvgWMUQpl4RAOp87rOJUPDEQ XMgbJ5xOl689cj1XyAjhJEL32bE6hlu0TWd+/QVyYla7mcmx7DhUZIUCd6tQRd1rtqVm yXkl1bELsIuJDevxwwCBOkF6DTAZY5a9XMzirMqtGSOs4M4rMs2vt0xgLY2J4WPiBaC4 lfRyk7q2KxwTeRhw9glNT7Xd6ooE4b3eszssgwHTqRZpJYNylJM+6HIWveRUJRd5znSs nDnA== X-Gm-Message-State: APjAAAWpKHKtBGDev5dvxSkDbCoNS4gH4t8q2tQDgmA8KumIcW2tXusL V+hnjAw/aDVtOK0HDq+DGYt/ZNbWE9o= X-Google-Smtp-Source: APXvYqzrEecwDHa5ggF6zIdBC628KNozDxyAb/8JE3Vsn+XnRMY5j95WuqlqI6zv3fAH/k0ig6fL7Q== X-Received: by 2002:adf:ee45:: with SMTP id w5mr94773037wro.352.1578225961144; Sun, 05 Jan 2020 04:06:01 -0800 (PST) Received: from localhost ([2620:10d:c092:180::1:e1d7]) by smtp.gmail.com with ESMTPSA id w19sm18753045wmc.22.2020.01.05.04.06.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 05 Jan 2020 04:06:00 -0800 (PST) Date: Sun, 5 Jan 2020 12:06:00 +0000 From: Chris Down To: linux-mm@kvack.org Cc: Hugh Dickins , Andrew Morton , Al Viro , Matthew Wilcox , Amir Goldstein , Jeff Layton , Johannes Weiner , Tejun Heo , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-team@fb.com Subject: [PATCH v5 1/2] tmpfs: Add per-superblock i_ino support Message-ID: <91b4ed6727712cb6d426cf60c740fe2f473f7638.1578225806.git.chris@chrisdown.name> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: get_next_ino has a number of problems: - It uses and returns a uint, which is susceptible to become overflowed if a lot of volatile inodes that use get_next_ino are created. - It's global, with no specificity per-sb or even per-filesystem. This means it's not that difficult to cause inode number wraparounds on a single device, which can result in having multiple distinct inodes with the same inode number. This patch adds a per-superblock counter that mitigates the second case. This design also allows us to later have a specific i_ino size per-device, for example, allowing users to choose whether to use 32- or 64-bit inodes for each tmpfs mount. This is implemented in the next commit. Signed-off-by: Chris Down Reviewed-by: Amir Goldstein Cc: Hugh Dickins Cc: Andrew Morton Cc: Al Viro Cc: Matthew Wilcox Cc: Jeff Layton Cc: Johannes Weiner Cc: Tejun Heo Cc: linux-mm@kvack.org Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: kernel-team@fb.com --- include/linux/shmem_fs.h | 1 + mm/shmem.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) v5: Nothing in code, just resending with correct linux-mm domain. diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index de8e4b71e3ba..7fac91f490dc 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -35,6 +35,7 @@ struct shmem_sb_info { unsigned char huge; /* Whether to try for hugepages */ kuid_t uid; /* Mount uid for root directory */ kgid_t gid; /* Mount gid for root directory */ + ino_t next_ino; /* The next per-sb inode number to use */ struct mempolicy *mpol; /* default memory policy for mappings */ spinlock_t shrinklist_lock; /* Protects shrinklist */ struct list_head shrinklist; /* List of shinkable inodes */ diff --git a/mm/shmem.c b/mm/shmem.c index 8793e8cc1a48..9e97ba972225 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2236,6 +2236,12 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma) return 0; } +/* + * shmem_get_inode - reserve, allocate, and initialise a new inode + * + * If this tmpfs is from kern_mount we use get_next_ino, which is global, since + * inum churn there is low and this avoids taking locks. + */ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode *dir, umode_t mode, dev_t dev, unsigned long flags) { @@ -2248,7 +2254,28 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode inode = new_inode(sb); if (inode) { - inode->i_ino = get_next_ino(); + if (sb->s_flags & SB_KERNMOUNT) { + /* + * __shmem_file_setup, one of our callers, is lock-free: + * it doesn't hold stat_lock in shmem_reserve_inode + * since max_inodes is always 0, and is called from + * potentially unknown contexts. As such, use the global + * allocator which doesn't require the per-sb stat_lock. + */ + inode->i_ino = get_next_ino(); + } else { + spin_lock(&sbinfo->stat_lock); + if (unlikely(sbinfo->next_ino > UINT_MAX)) { + /* + * Emulate get_next_ino uint wraparound for + * compatibility + */ + sbinfo->next_ino = 1; + } + inode->i_ino = sbinfo->next_ino++; + spin_unlock(&sbinfo->stat_lock); + } + inode_init_owner(inode, dir, mode); inode->i_blocks = 0; inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); @@ -3662,6 +3689,7 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc) #else sb->s_flags |= SB_NOUSER; #endif + sbinfo->next_ino = 1; sbinfo->max_blocks = ctx->blocks; sbinfo->free_inodes = sbinfo->max_inodes = ctx->inodes; sbinfo->uid = ctx->uid;