From patchwork Wed Aug 9 04:30:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hugh Dickins X-Patchwork-Id: 13347412 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81AC8C04A94 for ; Wed, 9 Aug 2023 04:31:06 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id F182F6B0071; Wed, 9 Aug 2023 00:31:05 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id EC7FF8D0002; Wed, 9 Aug 2023 00:31:05 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id D689C8D0001; Wed, 9 Aug 2023 00:31:05 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id C508B6B0071 for ; Wed, 9 Aug 2023 00:31:05 -0400 (EDT) Received: from smtpin19.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id 7F57A1407A3 for ; Wed, 9 Aug 2023 04:31:05 +0000 (UTC) X-FDA: 81103291290.19.6B43DE5 Received: from mail-yw1-f175.google.com (mail-yw1-f175.google.com [209.85.128.175]) by imf26.hostedemail.com (Postfix) with ESMTP id A951F140007 for ; Wed, 9 Aug 2023 04:31:03 +0000 (UTC) Authentication-Results: imf26.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=HJptNXYy; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf26.hostedemail.com: domain of hughd@google.com designates 209.85.128.175 as permitted sender) smtp.mailfrom=hughd@google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1691555463; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=0QEq4BtWj7XF+SzsAQAvfuVLV+e829beqWHSxHJfrd4=; b=wPWNyAqwilS+O8sWKCRhR+rgMcjDvRvCVfFHHdyDoIuakd1zVCE1Cs6c5Hm2UTx9XXoZ0A W4Tq7xDhlzUBE0FBo9VZRgcDroKf3oSV7/Rg0bmYzH7xBq45YsXK3u63lKVMGBL/BVKpbn zaUHkwA4zfBZZaYKw9k1FFb3XYKIaeI= ARC-Authentication-Results: i=1; imf26.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=HJptNXYy; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf26.hostedemail.com: domain of hughd@google.com designates 209.85.128.175 as permitted sender) smtp.mailfrom=hughd@google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1691555463; a=rsa-sha256; cv=none; b=wtcUEpPKv0EmVjfhkbCU1/C7AEZg0wFL37eZEPatwJQBB0lQKoYtOhAx5ZzyLddAl6OpU2 siyvPGT9LgDLo8dOPXj2VBhX13fpt5wK1zBgYCVm+JEryupIi/JWnSC/Ga3NdpiR2RTN42 f2sm4SIGVAf6dLHdVMINcHsOXjjMzLE= Received: by mail-yw1-f175.google.com with SMTP id 00721157ae682-583a8596e2aso62130337b3.1 for ; Tue, 08 Aug 2023 21:31:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1691555463; x=1692160263; h=mime-version:references:message-id:in-reply-to:subject:cc:to:from :date:from:to:cc:subject:date:message-id:reply-to; bh=0QEq4BtWj7XF+SzsAQAvfuVLV+e829beqWHSxHJfrd4=; b=HJptNXYyAYDNQBptp9KJN1ynN6d4xCu37HYicEN6u5bGotYv6/fxImpozw/WEF6Omm XWZa6948pq1yCfnYIPHZt+ZWG2sDZc0Ek3Xbq0KkHEJlVzDyOWyGO8vqhhio9SGnt+Gy kOUV4G21FiiPWrRBz6qOkWN/8WOKiZKJYBFV/QHl7tlDTu8sZGSQA/DMCaL8SEQ93aJE uIpYmLvLAp3D+BDbdhvTkCuWCOAj3CaJr9KZksD2j4vtQiUBkOMnE2VLOA4pSN3BwmEi ktY+0MhDjLeXRwsjx0AQKAbXt2oJQjNezKGDyUzB6awQdWLnvZ9a/RuBiLKePQBxQa0x YziQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1691555463; x=1692160263; h=mime-version:references:message-id:in-reply-to:subject:cc:to:from :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=0QEq4BtWj7XF+SzsAQAvfuVLV+e829beqWHSxHJfrd4=; b=ONOiyNMxatUsyiBhPc9ID4RLv1sFkcN8JVSA050fYnYHAT+4HA2ME/+MIW7T3XpeqW P5WlRIYte7u/Ehe2jTtSBbgdxunzYSkI9VSdVneAMkznrtuohPAAgRTQdOMc3xKuB/Fn EGX13zlLHk42PnZKUkEvKzh9H0mDQELxYMkw16eoNFSSz3QcrdhlZxXKqQaOv3vSpQoI qiJ1bZGV2ib6rDzLh/AZd+7PoxsvMGwD336XcmXsZD6GpSuYJ9kM3LmmRKRUxIp3fFKj 2wNlKtPffhpZlqOui5WcYUSYEbGcSEw2RjI43jwxowisMeEPPh/Tdzc5RgGjoR/QaCmy 4eVw== X-Gm-Message-State: AOJu0Yy2oRLFhYc5m5/h/ljx3Gf/SLLanyMHUSBjkZLsb5k2wSjDP7iI 1+hDb2iXxgelBEvgrBBNlmjA2Q== X-Google-Smtp-Source: AGHT+IFC/9yEPmxQ2d3jqattfPdMdJ9f0tThZS9o2vogrFxNROEZWWPd9XKK26aiRb6Kf73SCBCPeA== X-Received: by 2002:a25:361d:0:b0:d06:d1ae:dcf2 with SMTP id d29-20020a25361d000000b00d06d1aedcf2mr1670959yba.13.1691555462645; Tue, 08 Aug 2023 21:31:02 -0700 (PDT) Received: from ripple.attlocal.net (172-10-233-147.lightspeed.sntcca.sbcglobal.net. [172.10.233.147]) by smtp.gmail.com with ESMTPSA id d130-20020a254f88000000b00d0b0bbe574asm3212321ybb.44.2023.08.08.21.31.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Aug 2023 21:31:02 -0700 (PDT) Date: Tue, 8 Aug 2023 21:30:59 -0700 (PDT) From: Hugh Dickins X-X-Sender: hugh@ripple.attlocal.net To: Christian Brauner cc: Andrew Morton , Oleksandr Tymoshenko , Carlos Maiolino , Jeff Layton , Chuck Lever , Jan Kara , Miklos Szeredi , Daniel Xu , Chris Down , Tejun Heo , Greg Kroah-Hartman , Matthew Wilcox , Christoph Hellwig , Pete Zaitcev , Helge Deller , Topi Miettinen , Yu Kuai , linux-fsdevel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH vfs.tmpfs 1/5] xattr: simple_xattr_set() return old_xattr to be freed In-Reply-To: Message-ID: <158c6585-2aa7-d4aa-90ff-f7c3f8fe407c@google.com> References: MIME-Version: 1.0 X-Rspamd-Queue-Id: A951F140007 X-Rspam-User: X-Rspamd-Server: rspam04 X-Stat-Signature: rw64iwaimtyjfzsa1bkskcn8tjnsdu3m X-HE-Tag: 1691555463-563650 X-HE-Meta: U2FsdGVkX19gjlA5qVZZOmyo90nwpBKCyZM53nhebqiiYSSn4mr/KYeKM0yqJOtQ3F8M9ZPvjJzvjRdMUlzPHYCBW9MAM54qApWLxyKELP+q7Yb8xkVQcRY7nRSi0Ze+ShpEFucBqvM2NBqWqeSMymQBKuwyabwCSikrToLJgI49PxpA2SORuGyU1fcS4Bj7M3uTGRtP5KJZ1hwDXmOz62TFWYsFtuonjI08yAqzZfv1tybvtkUC5q4hSZv1WD010iB3uFe2F1xTfQ1Z58OCfg2KMY6QUFtpoOOv1rm9sZq1LVWA6DQF2UxUXWJdXR+NIUGdRnhEcgdPW+10JLj09TUPTBWGbsTNFktXBe8PmdGdu5q5dq8WZH8sbOUuj53vXPQRxmg6vqypzc4Bc2x3cL6gPe6EPwa77dMzPyENpM+EXuIp3EZCllM/3KNM1zR5eqKpTfu/RojpqDkLBlJ+mvujSobUsRHYLDlDf+r6u+vM/uRWV5feO1G2tX939eHLbfIj+pCxI/cCa8XT/dxq6xS5WHCvB7po1+kPQKQBum/+1s4+G8x7nokpg5aCcg8WS8mxp1d5pNyz3YTgCVqc23gFnY4/sHyd8+WuS3iO/HjXSG7DAfJ+JGkqSua9h3sJpslvPvYVWGDdUo5KNDTm/dgEAtllTTaKe1y95x0EumzBwk6HG07RWpa6CHxs8wPfd0SlQBNyAVItS/PWG132WRkkoZrK3JpiD3UzNMk3u5fG4PzeyQsa8QzKJ9L9Ii9Jm1WTonArQbblq/fADzH5Qap9BDrj8qVCMUq9ips6+bK0k7jQMNf4KbgnG7Fe+jbrJ5xunusTM3tL/hV9i7DNXNFDqdppAxE06OEVLaj+yjZ/pv2xvMOy5UlONRVjir8cSon2CNKQpc6qXWja4rpFOCa3qu38ubvk8dAwUlyBaXsoASabj1ybfEOK2HRqEmFrbaimVlGHKyUoD6bH2Lp puSombwQ irEM0ztTgxWLP3jC+Hx9OShw9LtX0erFY5eyWZq9JkyA+WDU53pWi5JL+f4ay/LnZjt/G8MK1skr2zNf6vbISiCDZ8psNz1d2DBGZETK0WvIMWM0gGcEE793Nd4YB7H3pp89PPGJ+r+U7t1toKlP5sFzlnBJgSeolG1eMkH4oM0QQ4iHSJvBXHhBZYVuhc9TPcaaGKC6daANr3gq/qLS0g2ZsfY9wq0GbD/HTKSOEpHFmscBD5AZjRczxCk6jEfIoCV9UejBQKcRxhSsL1pztq3Sy3mMHKizGmqE9yHsxguMTGlL9C8r1dxmgc2phmzkzy2tHzfFKE2gTwX5NLXir5J1l3juM1dh0K4UgTeU3Y/0xdsZdmg+WnvpHcRKbRmD5a5UI9SOoRaSEIu8bpt7gatD1LDk/69CflD46/RM1raNIkhrxcyyhiRDkr96jGdMSEGztl3ES1ENMldLX0IiqIPU8uA== 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: tmpfs wants to support limited user extended attributes, but kernfs (or cgroupfs, the only kernfs with KERNFS_ROOT_SUPPORT_USER_XATTR) already supports user extended attributes through simple xattrs: but limited by a policy (128KiB per inode) too liberal to be used on tmpfs. To allow a different limiting policy for tmpfs, without affecting the policy for kernfs, change simple_xattr_set() to return the replaced or removed xattr (if any), leaving the caller to update their accounting then free the xattr (by simple_xattr_free(), renamed from the static free_simple_xattr()). Signed-off-by: Hugh Dickins Reviewed-by: Jan Kara Reviewed-by: Christian Brauner Reviewed-by: Carlos Maiolino --- fs/kernfs/inode.c | 46 +++++++++++++++++++++++++--------------- fs/xattr.c | 51 +++++++++++++++++++-------------------------- include/linux/xattr.h | 7 ++++--- mm/shmem.c | 10 +++++---- 4 files changed, 61 insertions(+), 53 deletions(-) diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index b22b74d1a115..fec5d5f78f07 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -306,11 +306,17 @@ int kernfs_xattr_get(struct kernfs_node *kn, const char *name, int kernfs_xattr_set(struct kernfs_node *kn, const char *name, const void *value, size_t size, int flags) { + struct simple_xattr *old_xattr; struct kernfs_iattrs *attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; - return simple_xattr_set(&attrs->xattrs, name, value, size, flags, NULL); + old_xattr = simple_xattr_set(&attrs->xattrs, name, value, size, flags); + if (IS_ERR(old_xattr)) + return PTR_ERR(old_xattr); + + simple_xattr_free(old_xattr); + return 0; } static int kernfs_vfs_xattr_get(const struct xattr_handler *handler, @@ -342,7 +348,7 @@ static int kernfs_vfs_user_xattr_add(struct kernfs_node *kn, { atomic_t *sz = &kn->iattr->user_xattr_size; atomic_t *nr = &kn->iattr->nr_user_xattrs; - ssize_t removed_size; + struct simple_xattr *old_xattr; int ret; if (atomic_inc_return(nr) > KERNFS_MAX_USER_XATTRS) { @@ -355,13 +361,18 @@ static int kernfs_vfs_user_xattr_add(struct kernfs_node *kn, goto dec_size_out; } - ret = simple_xattr_set(xattrs, full_name, value, size, flags, - &removed_size); - - if (!ret && removed_size >= 0) - size = removed_size; - else if (!ret) + old_xattr = simple_xattr_set(xattrs, full_name, value, size, flags); + if (!old_xattr) return 0; + + if (IS_ERR(old_xattr)) { + ret = PTR_ERR(old_xattr); + goto dec_size_out; + } + + ret = 0; + size = old_xattr->size; + simple_xattr_free(old_xattr); dec_size_out: atomic_sub(size, sz); dec_count_out: @@ -376,18 +387,19 @@ static int kernfs_vfs_user_xattr_rm(struct kernfs_node *kn, { atomic_t *sz = &kn->iattr->user_xattr_size; atomic_t *nr = &kn->iattr->nr_user_xattrs; - ssize_t removed_size; - int ret; + struct simple_xattr *old_xattr; - ret = simple_xattr_set(xattrs, full_name, value, size, flags, - &removed_size); + old_xattr = simple_xattr_set(xattrs, full_name, value, size, flags); + if (!old_xattr) + return 0; - if (removed_size >= 0) { - atomic_sub(removed_size, sz); - atomic_dec(nr); - } + if (IS_ERR(old_xattr)) + return PTR_ERR(old_xattr); - return ret; + atomic_sub(old_xattr->size, sz); + atomic_dec(nr); + simple_xattr_free(old_xattr); + return 0; } static int kernfs_vfs_user_xattr_set(const struct xattr_handler *handler, diff --git a/fs/xattr.c b/fs/xattr.c index e7bbb7f57557..ba37a8f5cfd1 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -1040,12 +1040,12 @@ const char *xattr_full_name(const struct xattr_handler *handler, EXPORT_SYMBOL(xattr_full_name); /** - * free_simple_xattr - free an xattr object + * simple_xattr_free - free an xattr object * @xattr: the xattr object * * Free the xattr object. Can handle @xattr being NULL. */ -static inline void free_simple_xattr(struct simple_xattr *xattr) +void simple_xattr_free(struct simple_xattr *xattr) { if (xattr) kfree(xattr->name); @@ -1164,7 +1164,6 @@ int simple_xattr_get(struct simple_xattrs *xattrs, const char *name, * @value: the value to store along the xattr * @size: the size of @value * @flags: the flags determining how to set the xattr - * @removed_size: the size of the removed xattr * * Set a new xattr object. * If @value is passed a new xattr object will be allocated. If XATTR_REPLACE @@ -1181,29 +1180,27 @@ int simple_xattr_get(struct simple_xattrs *xattrs, const char *name, * nothing if XATTR_CREATE is specified in @flags or @flags is zero. For * XATTR_REPLACE we fail as mentioned above. * - * Return: On success zero and on error a negative error code is returned. + * Return: On success, the removed or replaced xattr is returned, to be freed + * by the caller; or NULL if none. On failure a negative error code is returned. */ -int simple_xattr_set(struct simple_xattrs *xattrs, const char *name, - const void *value, size_t size, int flags, - ssize_t *removed_size) +struct simple_xattr *simple_xattr_set(struct simple_xattrs *xattrs, + const char *name, const void *value, + size_t size, int flags) { - struct simple_xattr *xattr = NULL, *new_xattr = NULL; + struct simple_xattr *old_xattr = NULL, *new_xattr = NULL; struct rb_node *parent = NULL, **rbp; int err = 0, ret; - if (removed_size) - *removed_size = -1; - /* value == NULL means remove */ if (value) { new_xattr = simple_xattr_alloc(value, size); if (!new_xattr) - return -ENOMEM; + return ERR_PTR(-ENOMEM); new_xattr->name = kstrdup(name, GFP_KERNEL); if (!new_xattr->name) { - free_simple_xattr(new_xattr); - return -ENOMEM; + simple_xattr_free(new_xattr); + return ERR_PTR(-ENOMEM); } } @@ -1217,12 +1214,12 @@ int simple_xattr_set(struct simple_xattrs *xattrs, const char *name, else if (ret > 0) rbp = &(*rbp)->rb_right; else - xattr = rb_entry(*rbp, struct simple_xattr, rb_node); - if (xattr) + old_xattr = rb_entry(*rbp, struct simple_xattr, rb_node); + if (old_xattr) break; } - if (xattr) { + if (old_xattr) { /* Fail if XATTR_CREATE is requested and the xattr exists. */ if (flags & XATTR_CREATE) { err = -EEXIST; @@ -1230,12 +1227,10 @@ int simple_xattr_set(struct simple_xattrs *xattrs, const char *name, } if (new_xattr) - rb_replace_node(&xattr->rb_node, &new_xattr->rb_node, - &xattrs->rb_root); + rb_replace_node(&old_xattr->rb_node, + &new_xattr->rb_node, &xattrs->rb_root); else - rb_erase(&xattr->rb_node, &xattrs->rb_root); - if (!err && removed_size) - *removed_size = xattr->size; + rb_erase(&old_xattr->rb_node, &xattrs->rb_root); } else { /* Fail if XATTR_REPLACE is requested but no xattr is found. */ if (flags & XATTR_REPLACE) { @@ -1260,12 +1255,10 @@ int simple_xattr_set(struct simple_xattrs *xattrs, const char *name, out_unlock: write_unlock(&xattrs->lock); - if (err) - free_simple_xattr(new_xattr); - else - free_simple_xattr(xattr); - return err; - + if (!err) + return old_xattr; + simple_xattr_free(new_xattr); + return ERR_PTR(err); } static bool xattr_is_trusted(const char *name) @@ -1386,7 +1379,7 @@ void simple_xattrs_free(struct simple_xattrs *xattrs) rbp_next = rb_next(rbp); xattr = rb_entry(rbp, struct simple_xattr, rb_node); rb_erase(&xattr->rb_node, &xattrs->rb_root); - free_simple_xattr(xattr); + simple_xattr_free(xattr); rbp = rbp_next; } } diff --git a/include/linux/xattr.h b/include/linux/xattr.h index d591ef59aa98..e37fe667ae04 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h @@ -116,11 +116,12 @@ struct simple_xattr { void simple_xattrs_init(struct simple_xattrs *xattrs); void simple_xattrs_free(struct simple_xattrs *xattrs); struct simple_xattr *simple_xattr_alloc(const void *value, size_t size); +void simple_xattr_free(struct simple_xattr *xattr); int simple_xattr_get(struct simple_xattrs *xattrs, const char *name, void *buffer, size_t size); -int simple_xattr_set(struct simple_xattrs *xattrs, const char *name, - const void *value, size_t size, int flags, - ssize_t *removed_size); +struct simple_xattr *simple_xattr_set(struct simple_xattrs *xattrs, + const char *name, const void *value, + size_t size, int flags); ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs, char *buffer, size_t size); void simple_xattr_add(struct simple_xattrs *xattrs, diff --git a/mm/shmem.c b/mm/shmem.c index 0f83d86fd8b4..df3cabf54206 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -3595,15 +3595,17 @@ static int shmem_xattr_handler_set(const struct xattr_handler *handler, size_t size, int flags) { struct shmem_inode_info *info = SHMEM_I(inode); - int err; + struct simple_xattr *old_xattr; name = xattr_full_name(handler, name); - err = simple_xattr_set(&info->xattrs, name, value, size, flags, NULL); - if (!err) { + old_xattr = simple_xattr_set(&info->xattrs, name, value, size, flags); + if (!IS_ERR(old_xattr)) { + simple_xattr_free(old_xattr); + old_xattr = NULL; inode->i_ctime = current_time(inode); inode_inc_iversion(inode); } - return err; + return PTR_ERR(old_xattr); } static const struct xattr_handler shmem_security_xattr_handler = { From patchwork Wed Aug 9 04:32:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hugh Dickins X-Patchwork-Id: 13347420 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 20804C001B0 for ; Wed, 9 Aug 2023 04:32:28 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id B96406B0071; Wed, 9 Aug 2023 00:32:27 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id B47308D0002; Wed, 9 Aug 2023 00:32:27 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 9E89F8D0001; Wed, 9 Aug 2023 00:32:27 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 8FDAD6B0071 for ; Wed, 9 Aug 2023 00:32:27 -0400 (EDT) Received: from smtpin13.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id 68A518077A for ; Wed, 9 Aug 2023 04:32:27 +0000 (UTC) X-FDA: 81103294734.13.4BEB258 Received: from mail-yw1-f172.google.com (mail-yw1-f172.google.com [209.85.128.172]) by imf07.hostedemail.com (Postfix) with ESMTP id A3D9C4000D for ; Wed, 9 Aug 2023 04:32:25 +0000 (UTC) Authentication-Results: imf07.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=5Alg+xen; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf07.hostedemail.com: domain of hughd@google.com designates 209.85.128.172 as permitted sender) smtp.mailfrom=hughd@google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1691555545; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=fwvZIfkWxNDBAA2VDHz4cV0MGL3i8yqkmn2UYcR8Z9E=; b=1FEOx+ozZVV6JLxxX066JMwVZPXEHcAlc6csDTF+GoaABu4EQQqpDp7aOXKa/fsfOJG+Jz 6HsUexkJNXVJqhwpRfd0cVLcQ9I+ERh0XnJ4wxwT5cql029MmiLQZYHOMbduEEmO1EPnJR TwM2dbfPoH2PVKKVd6ZML+UL/FHyd4U= ARC-Authentication-Results: i=1; imf07.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=5Alg+xen; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf07.hostedemail.com: domain of hughd@google.com designates 209.85.128.172 as permitted sender) smtp.mailfrom=hughd@google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1691555545; a=rsa-sha256; cv=none; b=hJe3J51jJ3MBDA5wAar40oy/uXN1t7LAbCKcD8SgmPO7LkruuKbuvPOpkiEDmL3/hmMtw0 tbvWKouUJIU9aHuS4MisJgOxKlFQZTloEw1T5jRUld5y4UbwvdprlQooeXgAyh32YBhiNY wGjlcUpc2lGPthYIoSi+5xIpT/G8l7c= Received: by mail-yw1-f172.google.com with SMTP id 00721157ae682-583d63ca1e9so73852217b3.1 for ; Tue, 08 Aug 2023 21:32:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1691555545; x=1692160345; h=mime-version:references:message-id:in-reply-to:subject:cc:to:from :date:from:to:cc:subject:date:message-id:reply-to; bh=fwvZIfkWxNDBAA2VDHz4cV0MGL3i8yqkmn2UYcR8Z9E=; b=5Alg+xenp1VtdRcTTiXegQmvVx8wy8aB4AnR3TYfFwxSSxxPNENMNSt97yEdGrUomF NVZb/9pCOJoouoToNfrQBTHhZBj1EesKjIvAxP6VCdurukvN0Q8leXUyfg2LOat9CP31 Q5FWQVPkNrMwaPA2S0kCOX/DeVEZl+iG2xcwrtiUoANuf8nGtYz5QN7xi0CTGFxuSqbN PSRfnYgOr2B3jxdIuMkYej0ebVCRGknFkxX6EnXyoSXhG5MW6xZasEahhgUijN4NRvYh V6baPuomPigc6GllJHR8SBcrJsJayUbJgFKFUTJSIvtzrUi6egvr428yal/Y3mjtHP4e Zetw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1691555545; x=1692160345; h=mime-version:references:message-id:in-reply-to:subject:cc:to:from :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=fwvZIfkWxNDBAA2VDHz4cV0MGL3i8yqkmn2UYcR8Z9E=; b=et0CGzo+9xzFWY2wCQUlrehYfvSKm2vHNM4TMxWjZFE8Rvqq2nEoACceKet0XnsBYp iJwYuM6qebtkFoZw6ysZJVeAOKOH8qiNulDCq0Tln98nJo3vQ1fjLRlUT098S7QKUgel y4u+urbckboPOGyx2XPd3ZNTjFDGbPMeM2M3NkPtdXQABhniOu4rVJqwC1cKbTrFInEW blfEKSOl5npdb+TSuOoGopU1QYec4N9iToUvrmMWjUOwTum2oa40f/UiTNl73t/zxbhX hIXL0aHBTZMQYF3QY+g/rRjjDTZA+4Z7jCIJ646q+eTNSXUw3A8U7UraDjqdWGPjR6Hw AHEg== X-Gm-Message-State: AOJu0Yw4hxGtpEiiT0RogMQbzRncTfJynhB3CeAO6iUY5gDoapHCF/UC ysXrB6OSWHogZYAhqmKYM9z4YQ== X-Google-Smtp-Source: AGHT+IFRq2+oQxP1jY8hLbXzDUaZNnkuiKMnohvmGHSRa3VzhKzvm1cl65r3lJF2CoEm8sENiDLztQ== X-Received: by 2002:a0d:dfd7:0:b0:571:bd3e:73ca with SMTP id i206-20020a0ddfd7000000b00571bd3e73camr1696829ywe.16.1691555544708; Tue, 08 Aug 2023 21:32:24 -0700 (PDT) Received: from ripple.attlocal.net (172-10-233-147.lightspeed.sntcca.sbcglobal.net. [172.10.233.147]) by smtp.gmail.com with ESMTPSA id u62-20020a818441000000b0057a5302e2fesm3768585ywf.5.2023.08.08.21.32.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Aug 2023 21:32:24 -0700 (PDT) Date: Tue, 8 Aug 2023 21:32:21 -0700 (PDT) From: Hugh Dickins X-X-Sender: hugh@ripple.attlocal.net To: Christian Brauner cc: Andrew Morton , Oleksandr Tymoshenko , Carlos Maiolino , Jeff Layton , Chuck Lever , Jan Kara , Miklos Szeredi , Daniel Xu , Chris Down , Tejun Heo , Greg Kroah-Hartman , Matthew Wilcox , Christoph Hellwig , Pete Zaitcev , Helge Deller , Topi Miettinen , Yu Kuai , linux-fsdevel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH vfs.tmpfs 2/5] tmpfs: track free_ispace instead of free_inodes In-Reply-To: Message-ID: <4fe1739-d9e7-8dfd-5bce-12e7339711da@google.com> References: MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Server: rspam12 X-Rspamd-Queue-Id: A3D9C4000D X-Stat-Signature: 93fihad9eimyjts6iq3mf4n3mm3ezjby X-HE-Tag: 1691555545-149925 X-HE-Meta: U2FsdGVkX1+69VehxA3z5Sv6R4WfoFGkB1MrEQdiWjvZHw9THceI5kyd1KgCxsN4ffqxaXnnVemE3uVQVeMEi+z3SPDiwOODbNSaHq7tUVNeaGanYsfOIAZQjO2wQpGQg8mkulZS6mQ8yx7M0vitXnEMrae/XRliYYgzDJIKfMx1AOPU5YvvbVIF7zhSXgH7rY67nzLVMas6XG8FlD2U/yJSsPR7hmPrNLr59UrY8jJfH/9NVt5Q644arZzUlMf8LM/81Z+mrh6geT06BMFlv+mco8nAoVzPd4fdhHxjDtAmjy+9+yLfDhzLhgeAn2WhBbnR7yEX8PHEWE7gJmKrIiy5M5Uwk0OayF/ewXUE1r5SVxZDhBxm/TJOy6hgdglyLZkVbrsgb+zAFYKFKoj/Glb3gsg6bug7ll5kJpnltTFlltqnyALIUBkVsD42RaiFZ+2ZlOtHaLG6J+v9SesSEB2XLZ/8A2isYuaE+Jszg2BvkZ7TqeXPBRUYtjatHpIMy43r/xjbPZDi4OXPL5phP+HlmaJEWeuWOtqvJU2Q8f8/0aMPs3pWHbwNaxb+nvbKBQs9uzexFP/VQd6Tc6tlS5p+3xTrGoZMc9SaO2kk0joAtS8Mtj1yIV998+KSNTLVDVbPXOMnVHWm3DN+omITtM+Up/WMn8tkOtTP+eCHyjWTwtQ/nN6yzFRZ3d5lP9voF4rxZab91XMR+K+8yBDt7dhOK3AXf4snRBkkOk/bPndxxU7gp5IC0W0YNlgA3HzZhe5E9Aw5H6z9SSjpnyrkUttfYZTLO90BEu+oIYk5gui1ouHTNP8Joi2ecfXuOiB5lMfNXNMR7GrBCxYwB3VNVYvhNAiJZ0qZJ1Ll6iWmR0ADCFxHboIAeHOBoJ1+mH0hds12PKJAK7BgJHJ/qGKperMmIrWsiv8YMsTPH/n4K67NSexZJi/wwItTo8Jsc3q4ZLg5HMyJj/vZCem0Ku4 8Oou1Bhp iAUDiKCGjNaLMH81gRWtL+mjFZZSImkE3TGO05nPqVm8431yxSf9uV7VOiEeN2HelJjb5SEWhRUt6JLdeqWpsC0WFS4e4ToKca9RZFshsB/YAdW05bgnsvsXl5drmROGmWi5NIe3Ogscmq2H5pQndStA8CWFJHTP7rUfc4XKkXXkqEJXMke1q1Lsl8+seZ+Tn6SIjEP8iOODLaXbWjNeoNRNJfnVd3yG4A1//azLPV50fViJqQMsk6f/BGISF/1IrT+omKcgez+hicxrcadWrr8qAC65LRR3t8xpAo+5vAutybPkV8ak/gPGHqoRz4U/LhKbrGjeOk4jYOzmcjzMAT7kPKh0G2IQJ+RF2uK7g6mIqVR9vTKFbigSlzeNiGIPNv5UWvgfXREwSflf4T2kuDitL1o2msbLKL1IDTOdAp/p6nPk8n605omHRtIeRtezCG2g7bbDidiBmU+DcwN9HaBBWyrbA81fmfFhmhD44WJMLTDHZUzL+e68PFw== 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: In preparation for assigning some inode space to extended attributes, keep track of free_ispace instead of number of free_inodes: as if one tmpfs inode (and accompanying dentry) occupies very approximately 1KiB. Unsigned long is large enough for free_ispace, on 64-bit and on 32-bit: but take care to enforce the maximum. And fix the nr_blocks maximum on 32-bit: S64_MAX would be too big for it there, so say LONG_MAX instead. Delete the incorrect limited<->unlimited blocks/inodes comment above shmem_reconfigure(): leave it to the error messages below to describe. Signed-off-by: Hugh Dickins Reviewed-by: Jan Kara Reviewed-by: Carlos Maiolino --- include/linux/shmem_fs.h | 2 +- mm/shmem.c | 33 +++++++++++++++++---------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index 9b2d2faff1d0..6b0c626620f5 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -54,7 +54,7 @@ struct shmem_sb_info { unsigned long max_blocks; /* How many blocks are allowed */ struct percpu_counter used_blocks; /* How many are allocated */ unsigned long max_inodes; /* How many inodes are allowed */ - unsigned long free_inodes; /* How many are left for allocation */ + unsigned long free_ispace; /* How much ispace left for allocation */ raw_spinlock_t stat_lock; /* Serialize shmem_sb_info changes */ umode_t mode; /* Mount mode for root directory */ unsigned char huge; /* Whether to try for hugepages */ diff --git a/mm/shmem.c b/mm/shmem.c index df3cabf54206..c39471384168 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -90,6 +90,9 @@ static struct vfsmount *shm_mnt; /* Pretend that each entry is of this size in directory's i_size */ #define BOGO_DIRENT_SIZE 20 +/* Pretend that one inode + its dentry occupy this much memory */ +#define BOGO_INODE_SIZE 1024 + /* Symlink up to this size is kmalloc'ed instead of using a swappable page */ #define SHORT_SYMLINK_LEN 128 @@ -137,7 +140,8 @@ static unsigned long shmem_default_max_inodes(void) { unsigned long nr_pages = totalram_pages(); - return min(nr_pages - totalhigh_pages(), nr_pages / 2); + return min3(nr_pages - totalhigh_pages(), nr_pages / 2, + ULONG_MAX / BOGO_INODE_SIZE); } #endif @@ -331,11 +335,11 @@ static int shmem_reserve_inode(struct super_block *sb, ino_t *inop) if (!(sb->s_flags & SB_KERNMOUNT)) { raw_spin_lock(&sbinfo->stat_lock); if (sbinfo->max_inodes) { - if (!sbinfo->free_inodes) { + if (sbinfo->free_ispace < BOGO_INODE_SIZE) { raw_spin_unlock(&sbinfo->stat_lock); return -ENOSPC; } - sbinfo->free_inodes--; + sbinfo->free_ispace -= BOGO_INODE_SIZE; } if (inop) { ino = sbinfo->next_ino++; @@ -394,7 +398,7 @@ static void shmem_free_inode(struct super_block *sb) struct shmem_sb_info *sbinfo = SHMEM_SB(sb); if (sbinfo->max_inodes) { raw_spin_lock(&sbinfo->stat_lock); - sbinfo->free_inodes++; + sbinfo->free_ispace += BOGO_INODE_SIZE; raw_spin_unlock(&sbinfo->stat_lock); } } @@ -3155,7 +3159,7 @@ static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf) } if (sbinfo->max_inodes) { buf->f_files = sbinfo->max_inodes; - buf->f_ffree = sbinfo->free_inodes; + buf->f_ffree = sbinfo->free_ispace / BOGO_INODE_SIZE; } /* else leave those fields 0 like simple_statfs */ @@ -3815,13 +3819,13 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param) break; case Opt_nr_blocks: ctx->blocks = memparse(param->string, &rest); - if (*rest || ctx->blocks > S64_MAX) + if (*rest || ctx->blocks > LONG_MAX) goto bad_value; ctx->seen |= SHMEM_SEEN_BLOCKS; break; case Opt_nr_inodes: ctx->inodes = memparse(param->string, &rest); - if (*rest) + if (*rest || ctx->inodes > ULONG_MAX / BOGO_INODE_SIZE) goto bad_value; ctx->seen |= SHMEM_SEEN_INODES; break; @@ -4002,21 +4006,17 @@ static int shmem_parse_options(struct fs_context *fc, void *data) /* * Reconfigure a shmem filesystem. - * - * Note that we disallow change from limited->unlimited blocks/inodes while any - * are in use; but we must separately disallow unlimited->limited, because in - * that case we have no record of how much is already in use. */ static int shmem_reconfigure(struct fs_context *fc) { struct shmem_options *ctx = fc->fs_private; struct shmem_sb_info *sbinfo = SHMEM_SB(fc->root->d_sb); - unsigned long inodes; + unsigned long used_isp; struct mempolicy *mpol = NULL; const char *err; raw_spin_lock(&sbinfo->stat_lock); - inodes = sbinfo->max_inodes - sbinfo->free_inodes; + used_isp = sbinfo->max_inodes * BOGO_INODE_SIZE - sbinfo->free_ispace; if ((ctx->seen & SHMEM_SEEN_BLOCKS) && ctx->blocks) { if (!sbinfo->max_blocks) { @@ -4034,7 +4034,7 @@ static int shmem_reconfigure(struct fs_context *fc) err = "Cannot retroactively limit inodes"; goto out; } - if (ctx->inodes < inodes) { + if (ctx->inodes * BOGO_INODE_SIZE < used_isp) { err = "Too few inodes for current use"; goto out; } @@ -4080,7 +4080,7 @@ static int shmem_reconfigure(struct fs_context *fc) sbinfo->max_blocks = ctx->blocks; if (ctx->seen & SHMEM_SEEN_INODES) { sbinfo->max_inodes = ctx->inodes; - sbinfo->free_inodes = ctx->inodes - inodes; + sbinfo->free_ispace = ctx->inodes * BOGO_INODE_SIZE - used_isp; } /* @@ -4211,7 +4211,8 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc) sb->s_flags |= SB_NOUSER; #endif sbinfo->max_blocks = ctx->blocks; - sbinfo->free_inodes = sbinfo->max_inodes = ctx->inodes; + sbinfo->max_inodes = ctx->inodes; + sbinfo->free_ispace = sbinfo->max_inodes * BOGO_INODE_SIZE; if (sb->s_flags & SB_KERNMOUNT) { sbinfo->ino_batch = alloc_percpu(ino_t); if (!sbinfo->ino_batch) From patchwork Wed Aug 9 04:33:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hugh Dickins X-Patchwork-Id: 13347421 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id A2D54C04E69 for ; Wed, 9 Aug 2023 04:34:03 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 46D5E8D0001; Wed, 9 Aug 2023 00:34:03 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 41BD28D0002; Wed, 9 Aug 2023 00:34:03 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 2E4808D0001; Wed, 9 Aug 2023 00:34:03 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id 1D7796B0071 for ; Wed, 9 Aug 2023 00:34:03 -0400 (EDT) Received: from smtpin16.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id ED45D80499 for ; Wed, 9 Aug 2023 04:34:02 +0000 (UTC) X-FDA: 81103298724.16.08CD466 Received: from mail-yb1-f182.google.com (mail-yb1-f182.google.com [209.85.219.182]) by imf20.hostedemail.com (Postfix) with ESMTP id 092621C0017 for ; Wed, 9 Aug 2023 04:33:59 +0000 (UTC) Authentication-Results: imf20.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=tisuCV0B; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf20.hostedemail.com: domain of hughd@google.com designates 209.85.219.182 as permitted sender) smtp.mailfrom=hughd@google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1691555640; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=LKmWNaTQHWbW/f06pFcnEOfwhbTzT9a9ji8bFsf1bck=; b=Xy8V9s42FyfLWepLE4vKzggdjrAuUTBS7KbZTsPhu//Y3UIuS5DAmm4Vyny7Zbnei3YTDQ 3gWt/0jM2XV8jSgIRfDTrsSn0nnaCG54/evCDy5T2QSPA+osiYu5mPdhu3300FAXcWjO1T 0SY6yIzl1ess4a2P0DlZeRwMjKkyFKU= ARC-Authentication-Results: i=1; imf20.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=tisuCV0B; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf20.hostedemail.com: domain of hughd@google.com designates 209.85.219.182 as permitted sender) smtp.mailfrom=hughd@google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1691555640; a=rsa-sha256; cv=none; b=K8Afos7FIVFy36gNpJ3CbrbG6Qx38ENINvh/wTkMNnZQLVCN0h6e0EXLj5eg3DaSRbPper kDCBDX4VVyf3xWjrGJc/ukhgwI9kjRuXyy6KywVYQezZUqy929d7IFQB89SqGbcrjsseBi X9lWUN1SRG7D2sltwu8GI+yLcItTQbs= Received: by mail-yb1-f182.google.com with SMTP id 3f1490d57ef6-bc379e4c1cbso6834558276.2 for ; Tue, 08 Aug 2023 21:33:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1691555639; x=1692160439; h=mime-version:references:message-id:in-reply-to:subject:cc:to:from :date:from:to:cc:subject:date:message-id:reply-to; bh=LKmWNaTQHWbW/f06pFcnEOfwhbTzT9a9ji8bFsf1bck=; b=tisuCV0B7ipG83St9qBA5XGO5RJ5cDSm15eriMOM13gYSGm+trwDTq6Et7srBx5Qac W9gkD1UY2kBQrTJHTbPQoS8Oz1veJFvqonVrcltvyBatz2qmfN6jjSZmkBG8sdEZN2D8 hj0c1iSVkxaWskybtQEQipRS8+Tu3cgS5PX8gBTHNyTnmUkfnE15RzvSxwVkGYYupjJQ YHopNDtlvGjLLk4UFZJ34DfM1rbLyMGwrZN1vIld2YeF4m+eq3xTz6PhTZB6XxqQZvQO EIrZBGQYP0oTCkxcI4TeilpLP9YGlBTEhJcxWzm0Oj1FM3iXxVHDHp9Jq2GzcVVzeOGl 2nSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1691555639; x=1692160439; h=mime-version:references:message-id:in-reply-to:subject:cc:to:from :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=LKmWNaTQHWbW/f06pFcnEOfwhbTzT9a9ji8bFsf1bck=; b=J1l9bZV+MWSG8ntYZJ5sn64ddQOO7SA3QkYBCGY/v/wwgDcJdAYxjbALWFyIT+jn/8 Iz2fq5BhXoBkZNsqY3OVTIy2kQ62YlcckB0K/Pxkf3IU21OTNdbR6OjSy9oeSqsJwx7R Ov/zG2YKKEfkrrY6yw73cogC6Aqa7OV/G8dNurw6ZjX2bE4LQNRlxa+3rG0TvMq69JlC sT7zEAbZDuwPm3YlINLEu7MHfgamTT3ap+4eYxbOA3ZrsUuPj6dd4XTSk3Oo56XDHf37 V21IR7OI/5LFDcqMzEZ9jdo4AD+t8iOLZeajyDQuEIy+En+36PK1F1fxahVZSWkRNY9+ /TuA== X-Gm-Message-State: AOJu0YwC+0BsVWN7qnhdhigeobFxDYHkBglOgf0HbvBQsPXeVQO5m/bf R3pZVGs22p7pQiR/7oq1zJgnqA== X-Google-Smtp-Source: AGHT+IHfObTLHvN18MX9PxQb0aEQKcQX/w+V4oLEKKEHeUObobIaXthO2HgX/Yf7Qiyo4bn7+JcVQw== X-Received: by 2002:a05:6902:20a:b0:d07:1bdb:7780 with SMTP id j10-20020a056902020a00b00d071bdb7780mr1815999ybs.60.1691555638942; Tue, 08 Aug 2023 21:33:58 -0700 (PDT) Received: from ripple.attlocal.net (172-10-233-147.lightspeed.sntcca.sbcglobal.net. [172.10.233.147]) by smtp.gmail.com with ESMTPSA id c2-20020a258802000000b00d0c698ed6b6sm3079740ybl.41.2023.08.08.21.33.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Aug 2023 21:33:58 -0700 (PDT) Date: Tue, 8 Aug 2023 21:33:56 -0700 (PDT) From: Hugh Dickins X-X-Sender: hugh@ripple.attlocal.net To: Christian Brauner cc: Andrew Morton , Oleksandr Tymoshenko , Carlos Maiolino , Jeff Layton , Chuck Lever , Jan Kara , Miklos Szeredi , Daniel Xu , Chris Down , Tejun Heo , Greg Kroah-Hartman , Matthew Wilcox , Christoph Hellwig , Pete Zaitcev , Helge Deller , Topi Miettinen , Yu Kuai , linux-fsdevel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH vfs.tmpfs 3/5] tmpfs,xattr: enable limited user extended attributes In-Reply-To: Message-ID: <2e63b26e-df46-5baa-c7d6-f9a8dd3282c5@google.com> References: MIME-Version: 1.0 X-Rspamd-Server: rspam09 X-Rspamd-Queue-Id: 092621C0017 X-Stat-Signature: mj6gijnwecjzctqmbret51oz1wok3n95 X-Rspam-User: X-HE-Tag: 1691555639-257205 X-HE-Meta: U2FsdGVkX1+1ZpIQ/7OwbmI7D07k15uK5N6+IJoVfmEhCjelb8CiHfEKb5PYlFpOHs3vRHC6NY/KWqPRMS6zJLarvBcoRI9gfc4ym0iDvgmd8qE1Po3YYeqX62H3TmzF5GQtb5zTogut5n+PvLcD8QbNA7MfGFH6A24qI8IrY0dDp7wF/w1kojvrVNhKk5aSVdI9PPTkY8YzClHKEupC1mTXh0VOtpJTy3vgajVlGQOPiEX5fK13aZVL6S5AfwtphITWOtA8UIcGsaXNsGPZCzTGHWTCl8UsX3TxwDzqlT+mvTbfo40XIeyLuLPnRb7Vsq9pV8WL1tKSGH8FBrgYJpOFZrSCKsLIyQ3fa5S78Ctc9uw4IIbHo3JcG6WZU1TDH12qol2Vrweoyb5QlhiioBFPpOc0MxZvpf24zToAcFTJNMDhK2dIRy/27qcADtdyqrQD/K6s1hFOqSivNqwZLvSlAWETFQatR0EQxqLLXQubU//azlsR4e06hc5tQDnnyuPOlG0tgVpnWhur2GWSbX2MeT6GkIjz3fROCaNHddKH077YzZZdRcc/d5GFZsWyQotVChOMtUae9JAJZhQ8Ch2GnFxWr9y8s8mj1IIILHrc2xhFwYOyanuBvp+wHNgdVBFtlsOBDkLa91Z801/LeYbw/6FGcHzr+kPORYksFKquXUhrxDWTzU4Z/lcNo9DSal9lKAW9Rfkl5y73Z0ktJtbBCD/VP1OnK5sd+WoJxoW1tIGvFDJcUOKL5cpFLwLkXYakSe73fNSgt+a+R10DC7avcLNZXEyublZDaoSWZjmxYNBYNmkBmmQLoqkA04hBPWgVkJ+1vtEpFGlVT1PR6xOHT/SmctjsmbtS/IENQhvUXaD8fxUQx1phhShUT5GvwBBVkejupuQakonGckBVPjfCr0kGzaWh1gLIf9FR1sYAWktxk4k2LPNawElHbwo22zatMn3879Zr3ltlXON U5Mp9VZI SN0a0fNXIGKz52FKFzyl+LvYGq4lgEe24nrWluJapEJx3XyrdrkCqChXYXLv/KHrcBLFM1Og3kkaJdIFIwteOm1qkKtX5CNxAxrlWdjksQV+L1OZ3B0o6xD0Fv3TXUH36YC7TglmqPjaVORjpKimEixANlcNhpXKYCE+2UbbLRh8ZZMw2FW0Hz+Eyj2KxIj8njGQUMMolex+vf6uO4qWEQgyxFTnAjt7RHjSr/CrSRsIkT9s+nO82ngRxkCZZD3ASLqCV0jfuttPOGyGhhcGm2rwrOZE0jyRx0AiV2biOBkAll3SSQDFRkRjmUrUrwsz3TuHiWtSgav8Z//zXYk72hb0/yYQGkXNaCpaE3VCVx2WKlT6USdcD9tAwWY/4xHTC0CUfm12k6c48vJlSiNCEgfUEDYNX4JQeA6MM 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: Enable "user." extended attributes on tmpfs, limiting them by tracking the space they occupy, and deducting that space from the limited ispace (unless tmpfs mounted with nr_inodes=0 to leave that ispace unlimited). tmpfs inodes and simple xattrs are both unswappable, and have to be in lowmem on a 32-bit highmem kernel: so the ispace limit is appropriate for xattrs, without any need for a further mount option. Add simple_xattr_space() to give approximate but deterministic estimate of the space taken up by each xattr: with simple_xattrs_free() outputting the space freed if required (but kernfs and even some tmpfs usages do not require that, so don't waste time on strlen'ing if not needed). Security and trusted xattrs were already supported: for consistency and simplicity, account them from the same pool; though there's a small risk that a tmpfs with enough space before would now be considered too small. When extended attributes are used, "df -i" does show more IUsed and less IFree than can be explained by the inodes: document that (manpage later). xfstests tests/generic which were not run on tmpfs before but now pass: 020 037 062 070 077 097 103 117 337 377 454 486 523 533 611 618 728 with no new failures. Signed-off-by: Hugh Dickins Reviewed-by: Jan Kara Reviewed-by: Carlos Maiolino --- Documentation/filesystems/tmpfs.rst | 7 ++- fs/Kconfig | 4 +- fs/kernfs/dir.c | 2 +- fs/xattr.c | 28 ++++++++++- include/linux/xattr.h | 3 +- mm/shmem.c | 78 +++++++++++++++++++++++++++---- 6 files changed, 106 insertions(+), 16 deletions(-) diff --git a/Documentation/filesystems/tmpfs.rst b/Documentation/filesystems/tmpfs.rst index 67422ee10e03..56a26c843dbe 100644 --- a/Documentation/filesystems/tmpfs.rst +++ b/Documentation/filesystems/tmpfs.rst @@ -21,8 +21,8 @@ explained further below, some of which can be reconfigured dynamically on the fly using a remount ('mount -o remount ...') of the filesystem. A tmpfs filesystem can be resized but it cannot be resized to a size below its current usage. tmpfs also supports POSIX ACLs, and extended attributes for the -trusted.* and security.* namespaces. ramfs does not use swap and you cannot -modify any parameter for a ramfs filesystem. The size limit of a ramfs +trusted.*, security.* and user.* namespaces. ramfs does not use swap and you +cannot modify any parameter for a ramfs filesystem. The size limit of a ramfs filesystem is how much memory you have available, and so care must be taken if used so to not run out of memory. @@ -97,6 +97,9 @@ mount with such options, since it allows any user with write access to use up all the memory on the machine; but enhances the scalability of that instance in a system with many CPUs making intensive use of it. +If nr_inodes is not 0, that limited space for inodes is also used up by +extended attributes: "df -i"'s IUsed and IUse% increase, IFree decreases. + tmpfs blocks may be swapped out, when there is a shortage of memory. tmpfs has a mount option to disable its use of swap: diff --git a/fs/Kconfig b/fs/Kconfig index 8218a71933f9..7da21f563192 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -205,8 +205,8 @@ config TMPFS_XATTR Extended attributes are name:value pairs associated with inodes by the kernel or by users (see the attr(5) manual page for details). - Currently this enables support for the trusted.* and - security.* namespaces. + This enables support for the trusted.*, security.* and user.* + namespaces. You need this for POSIX ACL support on tmpfs. diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 5a1a4af9d3d2..660995856a04 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -556,7 +556,7 @@ void kernfs_put(struct kernfs_node *kn) kfree_const(kn->name); if (kn->iattr) { - simple_xattrs_free(&kn->iattr->xattrs); + simple_xattrs_free(&kn->iattr->xattrs, NULL); kmem_cache_free(kernfs_iattrs_cache, kn->iattr); } spin_lock(&kernfs_idr_lock); diff --git a/fs/xattr.c b/fs/xattr.c index ba37a8f5cfd1..2d607542281b 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -1039,6 +1039,26 @@ const char *xattr_full_name(const struct xattr_handler *handler, } EXPORT_SYMBOL(xattr_full_name); +/** + * simple_xattr_space - estimate the memory used by a simple xattr + * @name: the full name of the xattr + * @size: the size of its value + * + * This takes no account of how much larger the two slab objects actually are: + * that would depend on the slab implementation, when what is required is a + * deterministic number, which grows with name length and size and quantity. + * + * Return: The approximate number of bytes of memory used by such an xattr. + */ +size_t simple_xattr_space(const char *name, size_t size) +{ + /* + * Use "40" instead of sizeof(struct simple_xattr), to return the + * same result on 32-bit and 64-bit, and even if simple_xattr grows. + */ + return 40 + size + strlen(name); +} + /** * simple_xattr_free - free an xattr object * @xattr: the xattr object @@ -1363,14 +1383,17 @@ void simple_xattrs_init(struct simple_xattrs *xattrs) /** * simple_xattrs_free - free xattrs * @xattrs: xattr header whose xattrs to destroy + * @freed_space: approximate number of bytes of memory freed from @xattrs * * Destroy all xattrs in @xattr. When this is called no one can hold a * reference to any of the xattrs anymore. */ -void simple_xattrs_free(struct simple_xattrs *xattrs) +void simple_xattrs_free(struct simple_xattrs *xattrs, size_t *freed_space) { struct rb_node *rbp; + if (freed_space) + *freed_space = 0; rbp = rb_first(&xattrs->rb_root); while (rbp) { struct simple_xattr *xattr; @@ -1379,6 +1402,9 @@ void simple_xattrs_free(struct simple_xattrs *xattrs) rbp_next = rb_next(rbp); xattr = rb_entry(rbp, struct simple_xattr, rb_node); rb_erase(&xattr->rb_node, &xattrs->rb_root); + if (freed_space) + *freed_space += simple_xattr_space(xattr->name, + xattr->size); simple_xattr_free(xattr); rbp = rbp_next; } diff --git a/include/linux/xattr.h b/include/linux/xattr.h index e37fe667ae04..d20051865800 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h @@ -114,7 +114,8 @@ struct simple_xattr { }; void simple_xattrs_init(struct simple_xattrs *xattrs); -void simple_xattrs_free(struct simple_xattrs *xattrs); +void simple_xattrs_free(struct simple_xattrs *xattrs, size_t *freed_space); +size_t simple_xattr_space(const char *name, size_t size); struct simple_xattr *simple_xattr_alloc(const void *value, size_t size); void simple_xattr_free(struct simple_xattr *xattr); int simple_xattr_get(struct simple_xattrs *xattrs, const char *name, diff --git a/mm/shmem.c b/mm/shmem.c index c39471384168..7420b510a9f3 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -393,12 +393,12 @@ static int shmem_reserve_inode(struct super_block *sb, ino_t *inop) return 0; } -static void shmem_free_inode(struct super_block *sb) +static void shmem_free_inode(struct super_block *sb, size_t freed_ispace) { struct shmem_sb_info *sbinfo = SHMEM_SB(sb); if (sbinfo->max_inodes) { raw_spin_lock(&sbinfo->stat_lock); - sbinfo->free_ispace += BOGO_INODE_SIZE; + sbinfo->free_ispace += BOGO_INODE_SIZE + freed_ispace; raw_spin_unlock(&sbinfo->stat_lock); } } @@ -1232,6 +1232,7 @@ static void shmem_evict_inode(struct inode *inode) { struct shmem_inode_info *info = SHMEM_I(inode); struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); + size_t freed; if (shmem_mapping(inode->i_mapping)) { shmem_unacct_size(info->flags, inode->i_size); @@ -1258,9 +1259,9 @@ static void shmem_evict_inode(struct inode *inode) } } - simple_xattrs_free(&info->xattrs); + simple_xattrs_free(&info->xattrs, sbinfo->max_inodes ? &freed : NULL); + shmem_free_inode(inode->i_sb, freed); WARN_ON(inode->i_blocks); - shmem_free_inode(inode->i_sb); clear_inode(inode); #ifdef CONFIG_TMPFS_QUOTA dquot_free_inode(inode); @@ -2440,7 +2441,7 @@ static struct inode *__shmem_get_inode(struct mnt_idmap *idmap, inode = new_inode(sb); if (!inode) { - shmem_free_inode(sb); + shmem_free_inode(sb, 0); return ERR_PTR(-ENOSPC); } @@ -3281,7 +3282,7 @@ static int shmem_link(struct dentry *old_dentry, struct inode *dir, struct dentr ret = simple_offset_add(shmem_get_offset_ctx(dir), dentry); if (ret) { if (inode->i_nlink) - shmem_free_inode(inode->i_sb); + shmem_free_inode(inode->i_sb, 0); goto out; } @@ -3301,7 +3302,7 @@ static int shmem_unlink(struct inode *dir, struct dentry *dentry) struct inode *inode = d_inode(dentry); if (inode->i_nlink > 1 && !S_ISDIR(inode->i_mode)) - shmem_free_inode(inode->i_sb); + shmem_free_inode(inode->i_sb, 0); simple_offset_remove(shmem_get_offset_ctx(dir), dentry); @@ -3554,21 +3555,40 @@ static int shmem_initxattrs(struct inode *inode, void *fs_info) { struct shmem_inode_info *info = SHMEM_I(inode); + struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); const struct xattr *xattr; struct simple_xattr *new_xattr; + size_t ispace = 0; size_t len; + if (sbinfo->max_inodes) { + for (xattr = xattr_array; xattr->name != NULL; xattr++) { + ispace += simple_xattr_space(xattr->name, + xattr->value_len + XATTR_SECURITY_PREFIX_LEN); + } + if (ispace) { + raw_spin_lock(&sbinfo->stat_lock); + if (sbinfo->free_ispace < ispace) + ispace = 0; + else + sbinfo->free_ispace -= ispace; + raw_spin_unlock(&sbinfo->stat_lock); + if (!ispace) + return -ENOSPC; + } + } + for (xattr = xattr_array; xattr->name != NULL; xattr++) { new_xattr = simple_xattr_alloc(xattr->value, xattr->value_len); if (!new_xattr) - return -ENOMEM; + break; len = strlen(xattr->name) + 1; new_xattr->name = kmalloc(XATTR_SECURITY_PREFIX_LEN + len, GFP_KERNEL); if (!new_xattr->name) { kvfree(new_xattr); - return -ENOMEM; + break; } memcpy(new_xattr->name, XATTR_SECURITY_PREFIX, @@ -3579,6 +3599,16 @@ static int shmem_initxattrs(struct inode *inode, simple_xattr_add(&info->xattrs, new_xattr); } + if (xattr->name != NULL) { + if (ispace) { + raw_spin_lock(&sbinfo->stat_lock); + sbinfo->free_ispace += ispace; + raw_spin_unlock(&sbinfo->stat_lock); + } + simple_xattrs_free(&info->xattrs, NULL); + return -ENOMEM; + } + return 0; } @@ -3599,16 +3629,39 @@ static int shmem_xattr_handler_set(const struct xattr_handler *handler, size_t size, int flags) { struct shmem_inode_info *info = SHMEM_I(inode); + struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); struct simple_xattr *old_xattr; + size_t ispace = 0; name = xattr_full_name(handler, name); + if (value && sbinfo->max_inodes) { + ispace = simple_xattr_space(name, size); + raw_spin_lock(&sbinfo->stat_lock); + if (sbinfo->free_ispace < ispace) + ispace = 0; + else + sbinfo->free_ispace -= ispace; + raw_spin_unlock(&sbinfo->stat_lock); + if (!ispace) + return -ENOSPC; + } + old_xattr = simple_xattr_set(&info->xattrs, name, value, size, flags); if (!IS_ERR(old_xattr)) { + ispace = 0; + if (old_xattr && sbinfo->max_inodes) + ispace = simple_xattr_space(old_xattr->name, + old_xattr->size); simple_xattr_free(old_xattr); old_xattr = NULL; inode->i_ctime = current_time(inode); inode_inc_iversion(inode); } + if (ispace) { + raw_spin_lock(&sbinfo->stat_lock); + sbinfo->free_ispace += ispace; + raw_spin_unlock(&sbinfo->stat_lock); + } return PTR_ERR(old_xattr); } @@ -3624,9 +3677,16 @@ static const struct xattr_handler shmem_trusted_xattr_handler = { .set = shmem_xattr_handler_set, }; +static const struct xattr_handler shmem_user_xattr_handler = { + .prefix = XATTR_USER_PREFIX, + .get = shmem_xattr_handler_get, + .set = shmem_xattr_handler_set, +}; + static const struct xattr_handler *shmem_xattr_handlers[] = { &shmem_security_xattr_handler, &shmem_trusted_xattr_handler, + &shmem_user_xattr_handler, NULL }; From patchwork Wed Aug 9 04:34:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hugh Dickins X-Patchwork-Id: 13347422 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0A0CFC04A94 for ; Wed, 9 Aug 2023 04:35:00 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 8DA746B0071; Wed, 9 Aug 2023 00:35:00 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 889FB6B0074; Wed, 9 Aug 2023 00:35:00 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 752388D0002; Wed, 9 Aug 2023 00:35:00 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 661E96B0071 for ; Wed, 9 Aug 2023 00:35:00 -0400 (EDT) Received: from smtpin28.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id 3E5281A049D for ; Wed, 9 Aug 2023 04:35:00 +0000 (UTC) X-FDA: 81103301160.28.5220F2C Received: from mail-yb1-f178.google.com (mail-yb1-f178.google.com [209.85.219.178]) by imf14.hostedemail.com (Postfix) with ESMTP id 5A757100019 for ; Wed, 9 Aug 2023 04:34:58 +0000 (UTC) Authentication-Results: imf14.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=vAzcYUsb; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf14.hostedemail.com: domain of hughd@google.com designates 209.85.219.178 as permitted sender) smtp.mailfrom=hughd@google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1691555698; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=fTcwtqovj/n/LD3Icai5ShB8o9Zi6NmsgjgaBMH67ps=; b=wHueWa4sXcDazgCMjm72/ptoyjS3h9rFzRBhpj/t+zOT8i5ceOB8m50eP+90LTxY/VRaX0 KedYuwYjzrFlqC4Lcnnusev8QkTlUk1zbJScSpWzlx562a3AgxZBa53BoyVsozBzPPl/ki CrvOdCN1vFGjyI9UJAmgbklPhezyzwc= ARC-Authentication-Results: i=1; imf14.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=vAzcYUsb; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf14.hostedemail.com: domain of hughd@google.com designates 209.85.219.178 as permitted sender) smtp.mailfrom=hughd@google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1691555698; a=rsa-sha256; cv=none; b=qNoMjXGYNcMt3XR2bL2LplWOHIXj/eQEAWaQsC1uwb9hc8Os1gwyv4/yrftzMztvPsV9Wy JO9+eJDee2yElRShS54DaQu29LfzGT46JJsio3xVdkyDR/6mR7i67w0WRLGpIX7t4P+OJK BOkivvIg2TfJq6q+JpHS5+Rngwa0N2I= Received: by mail-yb1-f178.google.com with SMTP id 3f1490d57ef6-d593a63e249so1891090276.3 for ; Tue, 08 Aug 2023 21:34:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1691555697; x=1692160497; h=mime-version:references:message-id:in-reply-to:subject:cc:to:from :date:from:to:cc:subject:date:message-id:reply-to; bh=fTcwtqovj/n/LD3Icai5ShB8o9Zi6NmsgjgaBMH67ps=; b=vAzcYUsbMguHrchC9hn1CB5osMk/5YiGsgK2RYGkiVTG6y4+Y3oMgkq6hSzJnCK0io 3Ip0koO49LOYhVedkmqMZB+RDZkLYAOLd2zPtQ4qwtftMWaGwkQQudBVKheQz+SLQaal ZsXqL1XPhXf09s7c2NmiwIIKjqFMqYoaOqVBJXWEdX/pg2dDzHCG+bKLqIJA6U7Q3MVN 36liji+AHJWyLgr5x93GFh/6fl9PwkPArG8a5guP4Pz0Xkfg5yptXlr6sZyAaDLJECM7 l0E2bsZWY4rLln97xOdUzijmTFxcPPrakoc/PcuKyj0ZZysgXgTO+H1G4WoQDiTqJQCF SG4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1691555697; x=1692160497; h=mime-version:references:message-id:in-reply-to:subject:cc:to:from :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=fTcwtqovj/n/LD3Icai5ShB8o9Zi6NmsgjgaBMH67ps=; b=O8uon5m3Sye2Wf+Fx0MNkIIHVewcO5fiGgGjxcVHsS+Ay/GwPcrWONyzoxwHYZrwJV xI2gSI2oepG61ld8ywlaCCeKueoixgG1Zfr23U8ETM+td3U8svdNQHgOy0Amjo08isxG 0i9K8NMCUo9bV1xkO6qlgNqdglO3zwHS/E0r6/UUR8aqDyrobntniTnIeWqDRzFrts+s Ie9jgSf8zzCchfe/LduMvZ98v5cVTcwlDCBhf8lpp0lBcuSfcITl37PfR96RhD1UEN+2 3v3Hcv5ngkQyRetGaK0l274OgvKvfegubskNfLHIhna6z6HZqNeEbBlTBIH5smCgpZUJ Gm+A== X-Gm-Message-State: AOJu0Yz7GDr7v0jj4x+nnLuSV/D9xOGKIwNX0RMneCVrsNJdz25H/d+r wurtyJ8i+LKvbP7VNRhYPJNqJQ== X-Google-Smtp-Source: AGHT+IHKKV4hQ5vytluAdPVMcaWjO0NzAaMwo9dYu1hyneZrdnCvcm251k5acja++/q3pN0aSKgfDA== X-Received: by 2002:a0d:e811:0:b0:576:d65d:2802 with SMTP id r17-20020a0de811000000b00576d65d2802mr1729866ywe.3.1691555697390; Tue, 08 Aug 2023 21:34:57 -0700 (PDT) Received: from ripple.attlocal.net (172-10-233-147.lightspeed.sntcca.sbcglobal.net. [172.10.233.147]) by smtp.gmail.com with ESMTPSA id y139-20020a0dd691000000b00570589c5aedsm3785800ywd.7.2023.08.08.21.34.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Aug 2023 21:34:57 -0700 (PDT) Date: Tue, 8 Aug 2023 21:34:54 -0700 (PDT) From: Hugh Dickins X-X-Sender: hugh@ripple.attlocal.net To: Christian Brauner cc: Andrew Morton , Oleksandr Tymoshenko , Carlos Maiolino , Jeff Layton , Chuck Lever , Jan Kara , Miklos Szeredi , Daniel Xu , Chris Down , Tejun Heo , Greg Kroah-Hartman , Matthew Wilcox , Christoph Hellwig , Pete Zaitcev , Helge Deller , Topi Miettinen , Yu Kuai , linux-fsdevel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH vfs.tmpfs 4/5] tmpfs: trivial support for direct IO In-Reply-To: Message-ID: <7c12819-9b94-d56-ff88-35623aa34180@google.com> References: MIME-Version: 1.0 X-Rspamd-Server: rspam09 X-Rspamd-Queue-Id: 5A757100019 X-Stat-Signature: e3j49wd4o5rjutigr7npyx7czx5gpnj4 X-Rspam-User: X-HE-Tag: 1691555698-87616 X-HE-Meta: U2FsdGVkX1/GOpAYZP/C0G+g4mnnp1SlRr+ADxkvMhwTEZesDLJCuQFQJBP21DQIpuAmM7rDEcH+H7yaNgpdCWsJpBJvAONoNJTslmWSMxlFp80kUCnrtEFSjwLxrLwyTHOKf5jZyR2g3g60+yCtOfsScICFZVBYKhFIiycuKb3Y4LO4uNO1WS4BIuq/MWZqKqZm0H5eX0G9nF10oNlP2FZG1RVSGZAyG4WGCG182BtzOtWRJ5Ashf5ssHGYeksheEfJULUm0mBsRFNPa2kOuKg1tgZIVyjHfo5q3fuzVHJHMMgrLfDao+c9fVykvCpXPh4St2ZDeD34XNydrlIozrPCmivffwi+BiNFxVbHPQvxwVs6aOOVUsuObKGqHx58tdvH8/KldUCI60wltwgblStanAgEybvlmgCflYNZEB09I513Hx9xpWUaVf0OkgDppvXrlAfKp/a0qign+llHJ6xE/AHrs9ti7cRjHoe9X+zQUEmmIh+RmEhwF9Bopg4CMIaEe+Qw8n/W6cl95RdAPikMSQpAMMWdSPAKUBW6ZvZqNjU0bSmVWlp2sfrxjQR2xYcJL7aHRvkNovk4IHL8F5T1q4fAbZRS6m3GZCmQJHZmcmk0KvEg1fgdWvt42XvzpAVzkdPQ3E3KeoOwTm9yxvSn6ZStR/FLH7j0zhadjJyztIxfgguYDL/0BMwlXcYlNkrNT5ph02mNWDCF5G3l0G4XAhAKvfLYlm2nO+57Rm41J0cc1DY9GHMo06vo0Dtrd0pGkPNl8YewG2NzhOScXC5iX1Wjh/lWO8aO6p7lWjQVXJ1zU4kX+LQzxShDJTgImWJW5mcLqCQW5YlBOlViNtkmrTofamrqNqc5HUnCkuN0Q+S0OhztqMqbvUvxoKzLt8ET0V8UUpine7Zrs3POMQ4zNKZWMyNcZa8otSf7VJVrRk09ycGSlPrCSkGUALR1sr92RhdWVE/+AHvdEND AUE8yGb/ TMX7iDHru9xaR6UBxSD8bXvd8dXhcGodEPGU+Sz9YKqigtXEonBaTj+PVmkNcIRRUq8jPberjXbCl+Vyd1brEEOInmoNbLEXf1RnrcuyIqpW9W51HzdcS1kZ0s+a8lpVrFIsjgwQl1wY30CsS2oqL6KgQjuKnWyU31e0KbelYM5pUD7Wa2teDyh6oykNCtvW3aBwdRFCMgGybe3gmenpmR7xzkGEsRSAvb158V+CzLqllW2FkctqdHTyVS8rqeJalrzSxGtwM0lg8Hd5QMWECrG20zvOYFTPiNFRRGvbEARafCyDgBNA+8ORgghVBYWzmr0/AEUfpgb+jB6s7xH/8uELMTSg11p4vdwGAa0DZAjm5MTgxHMCt8EnhdY4YVsuSFO1Dx3VR0QPVDjN8F8RBPHdEKg== 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: Depending upon your philosophical viewpoint, either tmpfs always does direct IO, or it cannot ever do direct IO; but whichever, if tmpfs is to stand in for a more sophisticated filesystem, it can be helpful for tmpfs to support O_DIRECT. So, give tmpfs a shmem_direct_IO() method, of the simplest kind: by just returning 0 done, it leaves all the work to the buffered fallback (and everything else just happens to work out okay - in particular, its dirty pages don't get lost to invalidation). xfstests auto generic which were not run on tmpfs before but now pass: 036 091 113 125 130 133 135 198 207 208 209 210 211 212 214 226 239 263 323 355 391 406 412 422 427 446 451 465 551 586 591 609 615 647 708 729 with no new failures. LTP dio tests which were not run on tmpfs before but now pass: dio01 through dio30, except for dio04 and dio10, which fail because tmpfs dio read and write allow odd count: tmpfs could be made stricter, but would that be an improvement? Signed-off-by: Hugh Dickins Reviewed-by: Jan Kara --- mm/shmem.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mm/shmem.c b/mm/shmem.c index 7420b510a9f3..4d5599e566df 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2720,6 +2720,16 @@ shmem_write_end(struct file *file, struct address_space *mapping, return copied; } +static ssize_t shmem_direct_IO(struct kiocb *iocb, struct iov_iter *iter) +{ + /* + * Just leave all the work to the buffered fallback. + * Some LTP tests may expect us to enforce alignment restrictions, + * but the fallback works just fine with any alignment, so allow it. + */ + return 0; +} + static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to) { struct file *file = iocb->ki_filp; @@ -4421,6 +4431,7 @@ const struct address_space_operations shmem_aops = { #ifdef CONFIG_TMPFS .write_begin = shmem_write_begin, .write_end = shmem_write_end, + .direct_IO = shmem_direct_IO, #endif #ifdef CONFIG_MIGRATION .migrate_folio = migrate_folio, From patchwork Wed Aug 9 04:36:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hugh Dickins X-Patchwork-Id: 13347423 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2BC58C001B0 for ; Wed, 9 Aug 2023 04:36:20 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id B72886B0074; Wed, 9 Aug 2023 00:36:19 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id B22FD6B0075; Wed, 9 Aug 2023 00:36:19 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id A13288D0002; Wed, 9 Aug 2023 00:36:19 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id 919FF6B0074 for ; Wed, 9 Aug 2023 00:36:19 -0400 (EDT) Received: from smtpin11.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 310D3120DEA for ; Wed, 9 Aug 2023 04:36:19 +0000 (UTC) X-FDA: 81103304478.11.2412070 Received: from mail-yw1-f173.google.com (mail-yw1-f173.google.com [209.85.128.173]) by imf09.hostedemail.com (Postfix) with ESMTP id 6B07314000D for ; Wed, 9 Aug 2023 04:36:17 +0000 (UTC) Authentication-Results: imf09.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b="jfYt/KAw"; spf=pass (imf09.hostedemail.com: domain of hughd@google.com designates 209.85.128.173 as permitted sender) smtp.mailfrom=hughd@google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1691555777; a=rsa-sha256; cv=none; b=4Z/oIBPLPpSLr8xHIn9bbNZsPx7i4LWJsS0iIH/4D5kW1Yn/6U5pg7pEIoxoUC+fXjLIYw v4llpQTRnKxWdRwfOP830uGu18n5L33k6F8gpZhpfjsFHIklALuZxgmy2PRV7MH1+wN/5F K2e63NjYI79AJAZ4VPeDfxc+OLuAZmE= ARC-Authentication-Results: i=1; imf09.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b="jfYt/KAw"; spf=pass (imf09.hostedemail.com: domain of hughd@google.com designates 209.85.128.173 as permitted sender) smtp.mailfrom=hughd@google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1691555777; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=dHla0CWZ0WHqYi4zECfU9k4rSR5m4RPnWM7U84PXzs4=; b=hTV2HbscN4b5aHL8X8PIyn+0xht4Ifjq5n3qV/vC61ZaEWjYeZaTLl1ziHwFnRk2pqXK6s 9XKjF+TjZiQC0Vazvu1czCYjvWhNatII5xHFMlgrL5SnXJmgxjxQFhd7vIhdSbB4xX2gSP AFwIjx7E+PIDOjfmZK2UHtxQk0pN1XY= Received: by mail-yw1-f173.google.com with SMTP id 00721157ae682-58411e24eefso69127707b3.1 for ; Tue, 08 Aug 2023 21:36:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1691555776; x=1692160576; h=mime-version:references:message-id:in-reply-to:subject:cc:to:from :date:from:to:cc:subject:date:message-id:reply-to; bh=dHla0CWZ0WHqYi4zECfU9k4rSR5m4RPnWM7U84PXzs4=; b=jfYt/KAwov5gjcGl3FcNqvOk5TKV42theXc90cj7+enViQ6fF9qu+PQj5ASY8WE7W3 v+iyUH0Txp5OMV/jluSYyP1REsaSFfUc3faZnlHJsEaHZ1LpsFH4+b/KfbKvn+MrdBoq kQMtsan3i4QOMU14zUeISfohUjToi6NDWoUpq3tXnu5co9QbSNtkHBPD3ON2J3UHbcBS bfpt+qB9NthEFbsYKt5nPgUflp+NCiswQhhQSLWM0EjAHFkf0HEZphqYfnT4rpIcffWK LDOe8CrxbjPWtBmEx1RJW6yZPSAVfVu+TU5K0iBt3PkGu3mAS21fnhljpCNCtAifpm+j umcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1691555776; x=1692160576; h=mime-version:references:message-id:in-reply-to:subject:cc:to:from :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=dHla0CWZ0WHqYi4zECfU9k4rSR5m4RPnWM7U84PXzs4=; b=VQP4zYMzpimFJVfOZs7eW781Sx4aXgzsCcSHsD91vA9NalKqSfMZ94iMdJQHueq5J1 UJJteFwEZsXy0w2Ja5wpf4x5x++i7aFRD1A48vcRc2wigAxtJJVlpfbzWh3DIf/AVbvm rXs1RA+V5ikQFsDDjYxNOXkVfo+kZFMCyRx2zbVh+EStHT5oe/eeiWTE3cGqqviD/f2G lGEIzWC5QQoqATNN4jVRARQ7prg49bxuz9WrteKbdTLYMfYJknZJeE9RJzV9fVHskpAK x+W+GzON1XnQeL493M8GCxg6nmLqgWDmtBcYtn81K5UdEmreI1dLnG2aPlKFSGQekBhC aifQ== X-Gm-Message-State: AOJu0YyvsGBxcIbt/3cBuoc/WXlUNh6N5yzL6yKLCPPH2OIKcMpvwbjf o/JSiD/g3MImm8PlhSf62mSqsQ== X-Google-Smtp-Source: AGHT+IETKivu9DrTnaNoT4T/s8DpkVlW+OXa1kLEZyP5WGJw/nJ4J6ztHKF9wuaAq6Z7ieKEERVmcg== X-Received: by 2002:a81:81c5:0:b0:583:42d3:8a18 with SMTP id r188-20020a8181c5000000b0058342d38a18mr1283732ywf.52.1691555776457; Tue, 08 Aug 2023 21:36:16 -0700 (PDT) Received: from ripple.attlocal.net (172-10-233-147.lightspeed.sntcca.sbcglobal.net. [172.10.233.147]) by smtp.gmail.com with ESMTPSA id z186-20020a8189c3000000b0058390181d16sm3788417ywf.30.2023.08.08.21.36.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Aug 2023 21:36:16 -0700 (PDT) Date: Tue, 8 Aug 2023 21:36:12 -0700 (PDT) From: Hugh Dickins X-X-Sender: hugh@ripple.attlocal.net To: Christian Brauner cc: Andrew Morton , Oleksandr Tymoshenko , Carlos Maiolino , Jeff Layton , Chuck Lever , Jan Kara , Miklos Szeredi , Daniel Xu , Chris Down , Tejun Heo , Greg Kroah-Hartman , Matthew Wilcox , Christoph Hellwig , Pete Zaitcev , Helge Deller , Topi Miettinen , Yu Kuai , linux-fsdevel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH vfs.tmpfs 5/5] mm: invalidation check mapping before folio_contains In-Reply-To: Message-ID: References: MIME-Version: 1.0 X-Rspamd-Server: rspam08 X-Rspamd-Queue-Id: 6B07314000D X-Stat-Signature: 7swr5yfqq5tspfxny8nxrcdftrz37nw4 X-Rspam-User: X-HE-Tag: 1691555777-169694 X-HE-Meta: U2FsdGVkX19Avfv/TAwnX9UKmzOgnxRw5DWJFCWl9b0fyJBg5/ZmJv7O2GA8+HKEzB9S7NEKB7iHdZ3aQOQLwLsSDXqKGRCA5Tsp/+GfKcuo5FexMjsFnz2JpiA0K/TgjiKwNu/8Y48SodZweiv21DsIG9TzMDUNQ+lDr+riZpgIMcvyweF+m+IMuNk10W1ynp9qnQknbRP6URB907ufRqrMUVmIy6RDwMmV+zzGF+BAVZF0A9vWG45ATUd0T6ARElpZZTaYwu5YpOdb2AAaQ2zAKuI6+P4kbCCVg8O/FvCv9b0m7zZESRcFSLUhjxoULpnBtIXsRGATBPSP/8rp42sQ9fRwAj1aeky2ZjUAMcnluVmOWbuJKPUuyBkNC9RuL1PFKOh+o0tUrUWtRscIMLdZwLmi4PRMbB6bQ/jjwhnghjrEfsZoZo2FvTYczsWIqIl/yW2jLjq2mhhMcYUMMxfz4wjkB0+pvckaRvUiToiL0UjS7f85/w2Tkloip7edvdI0rIut3Q/FwPrcynx0rKuA6190+4FVdyxcY5NpbQ03aMm6wD4w+aCphmnuA4dP6kceiNVn1m9QTBF91J5rlFzfcvHp0a9LY/V2V9IwinTMtCDa2tV0fip0EH+sCTkbwivvNqF8Tpl6gCtRTXx7DWvw3KVyW+r4ClGDCkpOmgWR1hRvZzGn8lo82cXoTFtdNlGU8SVCitPiBear8E2cMtbaP31RhK+WGZ0jRcwpDxHVS/Pl1YQijVI6cGx1gJQDZsGMEdhXswNecwCil8aLwUTqoGls6TMcylDC2rL+9FN6og1TQPWvegAE+jw2x54PWqW0PyoG0WnTLfKrFLf+FFvCjlUN+EJ0vl3lpK0vOnT43oZ0eBoewM2mbXEMh5oQb2GwMmEJ+8gmMRPJOlPfu457r/CyZXakzRzHv7+7wANg3Jy9gqSswD2qkU01C5ojEYOc/Y1qBd8et2qWqCC gvqYOGQh dFPS0S2sogmegywJRL2yH7nYX86Jo1kjEm38jxLqRlW5TgclXyowtH4eH5lHwfM5R35O4k1Kh2YSTAEiAN7GuOiMmarWxXKfHTutSVKq/1rk4fTSfxDvTTcyu5rCjcIKxA0fTxWfJ7jomsKOH0WNzvdcGakU/+V+TGSzptsWS1diVwL41NEb93iAeGPA5PGjklrBJNym1n0VDwd/WHdIxm025IOwqBNG1V5NKRby09GGAYKYIq+iZ5s5D8nKWp6uF6Ss9uu0Mc449LHX6QrA2nLmNEaZyGFKIVZHKBVxqu91nrqmWYdxLCcNT84TULVE4cxAPZmAw/GeiNFT9+DgiLTjiOoujM+V48zt04on1VLW6nH1Xp9GWdV8A+sQ53WImkc/KlKZj9fpvZe8Pc1Vtpc7plYmQPcZKXEYc+f1jqITRFcyoFQ06ay9YmftGsMxAUNhm2+CLyx+0844RtNYOalsEzA== 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: Enabling tmpfs "direct IO" exposes it to invalidate_inode_pages2_range(), which when swapping can hit the VM_BUG_ON_FOLIO(!folio_contains()): the folio has been moved from page cache to swap cache (with folio->mapping reset to NULL), but the folio_index() embedded in folio_contains() sees swapcache, and so returns the swapcache_index() - whereas folio->index would be the right one to check against the index from mapping's xarray. There are different ways to fix this, but my preference is just to order the checks in invalidate_inode_pages2_range() the same way that they are in __filemap_get_folio() and find_lock_entries() and filemap_fault(): check folio->mapping before folio_contains(). Signed-off-by: Hugh Dickins Reviewed-by: Jan Kara --- mm/truncate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/truncate.c b/mm/truncate.c index 95d1291d269b..c3320e66d6ea 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -657,11 +657,11 @@ int invalidate_inode_pages2_range(struct address_space *mapping, } folio_lock(folio); - VM_BUG_ON_FOLIO(!folio_contains(folio, indices[i]), folio); - if (folio->mapping != mapping) { + if (unlikely(folio->mapping != mapping)) { folio_unlock(folio); continue; } + VM_BUG_ON_FOLIO(!folio_contains(folio, indices[i]), folio); folio_wait_writeback(folio); if (folio_mapped(folio))