Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp5149746pxj; Wed, 9 Jun 2021 10:14:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzAny/zKXS77ToC77pTaosn4RnH6oovG9EjIcjZDQ6//eJSe/oveBGvrQCuV9xK4Bsq+3F5 X-Received: by 2002:a17:906:5d14:: with SMTP id g20mr832876ejt.243.1623258862212; Wed, 09 Jun 2021 10:14:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623258862; cv=none; d=google.com; s=arc-20160816; b=G3x9jrY5fk85mX1H3o939DR0583ip4DEw7F1DNSWlhC9WGwrW4zV8V9fiWCWlpVIOQ 1iq1xHZ78F0y8mw3j8n+2440S9NuG5CN3/6Aoigaf0kJHcBG8abuC8tm+NmJ7aWALy67 YsK0Rsxr9iOosfrybCcXpWOmGZDaMOVV4tIiCsTbqXDHV0iCvZzO54Zb9WZ6kgasPYu8 6wnVnncK0FQNt11tPt21KfpfsxOp2bLnIbyGXD49XWysfadl6rb4jYKShTjqOb3Ufwk5 ileQbAEaw7o68FNmQnHbuE1KfHDGZoHMZyGl5Bp83Qgndwy8mNq8prU3zqjyFhueEIjO VEjA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:cc:to:from :subject; bh=fT7NjgjSMHmPg2R2aMK8K5w4EUWzG2w3PI9Q3p5+Quw=; b=GV4487RaKNWP6At3oSAg9t5KE+qh1+v+oKlyvVNKvXZj3yzB5afAW4+PpWzunzTzOT ilAbWoTOZGxN/Bue2M9Egkw6f3v2kC3Nq3vdV+m/zFZK0p8kcEi4zVpAgR8/UwYc1aCp Bhr/GEM6Ap5MSlDF4Z2Vuy1emPyCzzIsRz4DcNaBjuC4IFejGKzUtKjSUGtvFvE7OaT+ md742DdAi2GV+WSBgq5fXefPU2jgqWt2HIXPwZhPvRy3+t8q8gLMLX3iqRhH1BcsDGYs c8opWZUeilqpEx/O/L2fjjI4O9RxQIO6/NrneXq11/wsaoAelPEUilWa7bnh0o8hJC3t eBAQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id a27si237192edm.396.2021.06.09.10.13.57; Wed, 09 Jun 2021 10:14:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237743AbhFIIwZ convert rfc822-to-8bit (ORCPT + 99 others); Wed, 9 Jun 2021 04:52:25 -0400 Received: from us-smtp-delivery-44.mimecast.com ([205.139.111.44]:58377 "EHLO us-smtp-delivery-44.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237740AbhFIIwY (ORCPT ); Wed, 9 Jun 2021 04:52:24 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-312-qhieEAuNNmGzp1Y2k73bTw-1; Wed, 09 Jun 2021 04:50:23 -0400 X-MC-Unique: qhieEAuNNmGzp1Y2k73bTw-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D1757801B15; Wed, 9 Jun 2021 08:50:21 +0000 (UTC) Received: from web.messagingengine.com (ovpn-116-20.sin2.redhat.com [10.67.116.20]) by smtp.corp.redhat.com (Postfix) with ESMTP id CAD1D60918; Wed, 9 Jun 2021 08:50:02 +0000 (UTC) Subject: [PATCH v6 2/7] kernfs: add a revision to identify directory node changes From: Ian Kent To: Greg Kroah-Hartman , Tejun Heo Cc: Eric Sandeen , Fox Chen , Brice Goglin , Al Viro , Rick Lindsley , David Howells , Miklos Szeredi , Marcelo Tosatti , "Eric W. Biederman" , Carlos Maiolino , linux-fsdevel , Kernel Mailing List Date: Wed, 09 Jun 2021 16:49:59 +0800 Message-ID: <162322859985.361452.14110524195807923374.stgit@web.messagingengine.com> In-Reply-To: <162322846765.361452.17051755721944717990.stgit@web.messagingengine.com> References: <162322846765.361452.17051755721944717990.stgit@web.messagingengine.com> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=raven@themaw.net X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: themaw.net Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8BIT Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add a revision counter to kernfs directory nodes so it can be used to detect if a directory node has changed during negative dentry revalidation. There's an assumption that sizeof(unsigned long) <= sizeof(pointer) on all architectures and as far as I know that assumption holds. So adding a revision counter to the struct kernfs_elem_dir variant of the kernfs_node type union won't increase the size of the kernfs_node struct. This is because struct kernfs_elem_dir is at least sizeof(pointer) smaller than the largest union variant. It's tempting to make the revision counter a u64 but that would increase the size of kernfs_node on archs where sizeof(pointer) is smaller than the revision counter. Signed-off-by: Ian Kent --- fs/kernfs/dir.c | 2 ++ fs/kernfs/kernfs-internal.h | 23 +++++++++++++++++++++++ include/linux/kernfs.h | 5 +++++ 3 files changed, 30 insertions(+) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 33166ec90a112..b3d1bc0f317d0 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -372,6 +372,7 @@ static int kernfs_link_sibling(struct kernfs_node *kn) /* successfully added, account subdir number */ if (kernfs_type(kn) == KERNFS_DIR) kn->parent->dir.subdirs++; + kernfs_inc_rev(kn->parent); return 0; } @@ -394,6 +395,7 @@ static bool kernfs_unlink_sibling(struct kernfs_node *kn) if (kernfs_type(kn) == KERNFS_DIR) kn->parent->dir.subdirs--; + kernfs_inc_rev(kn->parent); rb_erase(&kn->rb, &kn->parent->dir.children); RB_CLEAR_NODE(&kn->rb); diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index ccc3b44f6306f..b4e7579e04799 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -81,6 +81,29 @@ static inline struct kernfs_node *kernfs_dentry_node(struct dentry *dentry) return d_inode(dentry)->i_private; } +static inline void kernfs_set_rev(struct kernfs_node *kn, + struct dentry *dentry) +{ + if (kernfs_type(kn) == KERNFS_DIR) + dentry->d_time = kn->dir.rev; +} + +static inline void kernfs_inc_rev(struct kernfs_node *kn) +{ + if (kernfs_type(kn) == KERNFS_DIR) + kn->dir.rev++; +} + +static inline bool kernfs_dir_changed(struct kernfs_node *kn, + struct dentry *dentry) +{ + if (kernfs_type(kn) == KERNFS_DIR) { + if (kn->dir.rev != dentry->d_time) + return true; + } + return false; +} + extern const struct super_operations kernfs_sops; extern struct kmem_cache *kernfs_node_cache, *kernfs_iattrs_cache; diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 9e8ca8743c268..d7e0160fce6df 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -98,6 +98,11 @@ struct kernfs_elem_dir { * better directly in kernfs_node but is here to save space. */ struct kernfs_root *root; + /* + * Monotonic revision counter, used to identify if a directory + * node has changed during negative dentry revalidation. + */ + unsigned long rev; }; struct kernfs_elem_symlink {