All of lore.kernel.org
 help / color / mirror / Atom feed
From: Al Viro <viro@zeniv.linux.org.uk>
To: linux-fsdevel@vger.kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Christian Brauner <brauner@kernel.org>,
	linux-kernel@vger.kernel.org
Subject: [PATCH v3 01/21] switch nfsd_client_rmdir() to use of simple_recursive_removal()
Date: Fri, 24 Nov 2023 06:04:02 +0000	[thread overview]
Message-ID: <20231124060422.576198-1-viro@zeniv.linux.org.uk> (raw)
In-Reply-To: <20231124060200.GR38156@ZenIV>

nfsd_client_rmdir() open-codes a subset of simple_recursive_removal().
Conversion to calling simple_recursive_removal() allows to clean things
up quite a bit.

While we are at it, nfsdfs_create_files() doesn't need to mess with "pick
the reference to struct nfsdfs_client from the already created parent" -
the caller already knows it (that's where the parent got it from,
after all), so we might as well just pass it as an explicit argument.
So __get_nfsdfs_client() is only needed in get_nfsdfs_client() and
can be folded in there.

Incidentally, the locking in get_nfsdfs_client() is too heavy - we don't
need ->i_rwsem for that, ->i_lock serves just fine.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Tested-by: Jeff Layton <jlayton@kernel.org>
Acked-by: Chuck Lever <chuck.lever@oracle.com>
Acked-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/nfsd/nfsctl.c | 70 ++++++++++--------------------------------------
 1 file changed, 14 insertions(+), 56 deletions(-)

diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 3e15b72f421d..50df5e9d0069 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -1236,63 +1236,34 @@ static inline void _nfsd_symlink(struct dentry *parent, const char *name,
 
 #endif
 
-static void clear_ncl(struct inode *inode)
+static void clear_ncl(struct dentry *dentry)
 {
+	struct inode *inode = d_inode(dentry);
 	struct nfsdfs_client *ncl = inode->i_private;
 
+	spin_lock(&inode->i_lock);
 	inode->i_private = NULL;
+	spin_unlock(&inode->i_lock);
 	kref_put(&ncl->cl_ref, ncl->cl_release);
 }
 
-static struct nfsdfs_client *__get_nfsdfs_client(struct inode *inode)
-{
-	struct nfsdfs_client *nc = inode->i_private;
-
-	if (nc)
-		kref_get(&nc->cl_ref);
-	return nc;
-}
-
 struct nfsdfs_client *get_nfsdfs_client(struct inode *inode)
 {
 	struct nfsdfs_client *nc;
 
-	inode_lock_shared(inode);
-	nc = __get_nfsdfs_client(inode);
-	inode_unlock_shared(inode);
+	spin_lock(&inode->i_lock);
+	nc = inode->i_private;
+	if (nc)
+		kref_get(&nc->cl_ref);
+	spin_unlock(&inode->i_lock);
 	return nc;
 }
-/* from __rpc_unlink */
-static void nfsdfs_remove_file(struct inode *dir, struct dentry *dentry)
-{
-	int ret;
-
-	clear_ncl(d_inode(dentry));
-	dget(dentry);
-	ret = simple_unlink(dir, dentry);
-	d_drop(dentry);
-	fsnotify_unlink(dir, dentry);
-	dput(dentry);
-	WARN_ON_ONCE(ret);
-}
-
-static void nfsdfs_remove_files(struct dentry *root)
-{
-	struct dentry *dentry, *tmp;
-
-	list_for_each_entry_safe(dentry, tmp, &root->d_subdirs, d_child) {
-		if (!simple_positive(dentry)) {
-			WARN_ON_ONCE(1); /* I think this can't happen? */
-			continue;
-		}
-		nfsdfs_remove_file(d_inode(root), dentry);
-	}
-}
 
 /* XXX: cut'n'paste from simple_fill_super; figure out if we could share
  * code instead. */
 static  int nfsdfs_create_files(struct dentry *root,
 				const struct tree_descr *files,
+				struct nfsdfs_client *ncl,
 				struct dentry **fdentries)
 {
 	struct inode *dir = d_inode(root);
@@ -1311,8 +1282,9 @@ static  int nfsdfs_create_files(struct dentry *root,
 			dput(dentry);
 			goto out;
 		}
+		kref_get(&ncl->cl_ref);
 		inode->i_fop = files->ops;
-		inode->i_private = __get_nfsdfs_client(dir);
+		inode->i_private = ncl;
 		d_add(dentry, inode);
 		fsnotify_create(dir, dentry);
 		if (fdentries)
@@ -1321,7 +1293,6 @@ static  int nfsdfs_create_files(struct dentry *root,
 	inode_unlock(dir);
 	return 0;
 out:
-	nfsdfs_remove_files(root);
 	inode_unlock(dir);
 	return -ENOMEM;
 }
@@ -1341,7 +1312,7 @@ struct dentry *nfsd_client_mkdir(struct nfsd_net *nn,
 	dentry = nfsd_mkdir(nn->nfsd_client_dir, ncl, name);
 	if (IS_ERR(dentry)) /* XXX: tossing errors? */
 		return NULL;
-	ret = nfsdfs_create_files(dentry, files, fdentries);
+	ret = nfsdfs_create_files(dentry, files, ncl, fdentries);
 	if (ret) {
 		nfsd_client_rmdir(dentry);
 		return NULL;
@@ -1352,20 +1323,7 @@ struct dentry *nfsd_client_mkdir(struct nfsd_net *nn,
 /* Taken from __rpc_rmdir: */
 void nfsd_client_rmdir(struct dentry *dentry)
 {
-	struct inode *dir = d_inode(dentry->d_parent);
-	struct inode *inode = d_inode(dentry);
-	int ret;
-
-	inode_lock(dir);
-	nfsdfs_remove_files(dentry);
-	clear_ncl(inode);
-	dget(dentry);
-	ret = simple_rmdir(dir, dentry);
-	WARN_ON_ONCE(ret);
-	d_drop(dentry);
-	fsnotify_rmdir(dir, dentry);
-	dput(dentry);
-	inode_unlock(dir);
+	simple_recursive_removal(dentry, clear_ncl);
 }
 
 static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc)
-- 
2.39.2


  reply	other threads:[~2023-11-24  6:04 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-24  6:02 [RFC][PATCHSET v3] simplifying fast_dput(), dentry_kill() et.al Al Viro
2023-11-24  6:04 ` Al Viro [this message]
2023-11-24  6:04   ` [PATCH v3 02/21] coda_flag_children(): cope with dentries turning negative Al Viro
2023-11-24 21:22     ` Linus Torvalds
2023-11-24 22:58       ` Paul E. McKenney
2023-11-24  6:04   ` [PATCH v3 03/21] dentry: switch the lists of children to hlist Al Viro
2023-11-24  7:44     ` Amir Goldstein
2023-11-24  7:55       ` Al Viro
2023-11-24  8:02         ` Amir Goldstein
2023-11-24  6:04   ` [PATCH v3 04/21] centralize killing dentry from shrink list Al Viro
2023-11-24  6:04   ` [PATCH v3 05/21] shrink_dentry_list(): no need to check that dentry refcount is marked dead Al Viro
2023-11-24  6:04   ` [PATCH v3 06/21] fast_dput(): having ->d_delete() is not reason to delay refcount decrement Al Viro
2023-11-24  6:04   ` [PATCH v3 07/21] fast_dput(): handle underflows gracefully Al Viro
2023-11-24  6:04   ` [PATCH v3 08/21] fast_dput(): new rules for refcount Al Viro
2023-11-24  6:04   ` [PATCH v3 09/21] __dput_to_list(): do decrement of refcount in the callers Al Viro
2023-11-24  6:04   ` [PATCH v3 10/21] make retain_dentry() neutral with respect to refcounting Al Viro
2023-11-24  6:04   ` [PATCH v3 11/21] __dentry_kill(): get consistent rules for victim's refcount Al Viro
2023-11-24  6:04   ` [PATCH v3 12/21] dentry_kill(): don't bother with retain_dentry() on slow path Al Viro
2023-11-24  6:04   ` [PATCH v3 13/21] Call retain_dentry() with refcount 0 Al Viro
2023-11-24  6:04   ` [PATCH v3 14/21] fold the call of retain_dentry() into fast_dput() Al Viro
2023-11-24  6:04   ` [PATCH v3 15/21] don't try to cut corners in shrink_lock_dentry() Al Viro
2023-11-24  6:04   ` [PATCH v3 16/21] fold dentry_kill() into dput() Al Viro
2023-11-24  6:04   ` [PATCH v3 17/21] to_shrink_list(): call only if refcount is 0 Al Viro
2023-11-24  6:04   ` [PATCH v3 18/21] switch select_collect{,2}() to use of to_shrink_list() Al Viro
2023-11-24  6:04   ` [PATCH v3 19/21] d_prune_aliases(): use a shrink list Al Viro
2023-11-24  6:04   ` [PATCH v3 20/21] __dentry_kill(): new locking scheme Al Viro
2023-11-24  6:04   ` [PATCH v3 21/21] retain_dentry(): introduce a trimmed-down lockless variant Al Viro
2023-11-24 21:28 ` [RFC][PATCHSET v3] simplifying fast_dput(), dentry_kill() et.al Linus Torvalds

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=20231124060422.576198-1-viro@zeniv.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=brauner@kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /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.