All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org
Cc: Qingfang Deng <dqfext@gmail.com>, Sasha Levin <sashal@kernel.org>
Subject: Re: [PATCH 5.10 3/5] kernfs: switch kernfs to use an rwsem
Date: Wed, 21 May 2025 22:03:47 -0400	[thread overview]
Message-ID: <20250521154443-367c6fc07dc3045a@stable.kernel.org> (raw)
In-Reply-To: <20250521015336.3450911-4-dqfext@gmail.com>

[ Sasha's backport helper bot ]

Hi,

✅ All tests passed successfully. No issues detected.
No action required from the submitter.

The upstream commit SHA1 provided is correct: 7ba0273b2f34a55efe967d3c7381fb1da2ca195f

WARNING: Author mismatch between patch and upstream commit:
Backport author: Qingfang Deng<dqfext@gmail.com>
Commit author: Ian Kent<raven@themaw.net>

Status in newer kernel trees:
6.14.y | Present (exact SHA1)
6.12.y | Present (exact SHA1)
6.6.y | Present (exact SHA1)
6.1.y | Present (exact SHA1)
5.15.y | Present (exact SHA1)

Note: The patch differs from the upstream commit:
---
1:  7ba0273b2f34a ! 1:  a0418b6d194c8 kernfs: switch kernfs to use an rwsem
    @@ Metadata
      ## Commit message ##
         kernfs: switch kernfs to use an rwsem
     
    +    Commit 7ba0273b2f34a55efe967d3c7381fb1da2ca195f upstream.
    +
         The kernfs global lock restricts the ability to perform kernfs node
         lookup operations in parallel during path walks.
     
    @@ fs/kernfs/dir.c
     -DEFINE_MUTEX(kernfs_mutex);
     +DECLARE_RWSEM(kernfs_rwsem);
      static DEFINE_SPINLOCK(kernfs_rename_lock);	/* kn->parent and ->name */
    - static char kernfs_pr_cont_buf[PATH_MAX];	/* protected by rename_lock */
    - static DEFINE_SPINLOCK(kernfs_idr_lock);	/* root->ino_idr */
    + /*
    +  * Don't use rename_lock to piggy back on pr_cont_buf. We don't want to
     @@ fs/kernfs/dir.c: static DEFINE_SPINLOCK(kernfs_idr_lock);	/* root->ino_idr */
      
      static bool kernfs_active(struct kernfs_node *kn)
    @@ fs/kernfs/dir.c: static void kernfs_drain(struct kernfs_node *kn)
      }
      
      /**
    +@@ fs/kernfs/dir.c: static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
    + 		/* If the kernfs parent node has changed discard and
    + 		 * proceed to ->lookup.
    + 		 */
    +-		mutex_lock(&kernfs_mutex);
    ++		down_read(&kernfs_rwsem);
    + 		spin_lock(&dentry->d_lock);
    + 		parent = kernfs_dentry_node(dentry->d_parent);
    + 		if (parent) {
    + 			if (kernfs_dir_changed(parent, dentry)) {
    + 				spin_unlock(&dentry->d_lock);
    +-				mutex_unlock(&kernfs_mutex);
    ++				up_read(&kernfs_rwsem);
    + 				return 0;
    + 			}
    + 		}
    + 		spin_unlock(&dentry->d_lock);
    +-		mutex_unlock(&kernfs_mutex);
    ++		up_read(&kernfs_rwsem);
    + 
    + 		/* The kernfs parent node hasn't changed, leave the
    + 		 * dentry negative and return success.
    +@@ fs/kernfs/dir.c: static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
    + 	}
    + 
    + 	kn = kernfs_dentry_node(dentry);
    +-	mutex_lock(&kernfs_mutex);
    ++	down_read(&kernfs_rwsem);
    + 
    + 	/* The kernfs node has been deactivated */
    + 	if (!kernfs_active(kn))
    +@@ fs/kernfs/dir.c: static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
    + 	    kernfs_info(dentry->d_sb)->ns != kn->ns)
    + 		goto out_bad;
    + 
    +-	mutex_unlock(&kernfs_mutex);
    ++	up_read(&kernfs_rwsem);
    + 	return 1;
    + out_bad:
    +-	mutex_unlock(&kernfs_mutex);
    ++	up_read(&kernfs_rwsem);
    + 	return 0;
    + }
    + 
     @@ fs/kernfs/dir.c: int kernfs_add_one(struct kernfs_node *kn)
      	bool has_ns;
      	int ret;
    @@ fs/kernfs/dir.c: static struct kernfs_node *kernfs_walk_ns(struct kernfs_node *p
     -	lockdep_assert_held(&kernfs_mutex);
     +	lockdep_assert_held_read(&kernfs_rwsem);
      
    - 	/* grab kernfs_rename_lock to piggy back on kernfs_pr_cont_buf */
    - 	spin_lock_irq(&kernfs_rename_lock);
    + 	spin_lock_irq(&kernfs_pr_cont_lock);
    + 
     @@ fs/kernfs/dir.c: struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent,
      {
      	struct kernfs_node *kn;
    @@ fs/kernfs/dir.c: struct kernfs_node *kernfs_walk_and_get_ns(struct kernfs_node *
      
      	return kn;
      }
    -@@ fs/kernfs/dir.c: static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
    - 		/* If the kernfs parent node has changed discard and
    - 		 * proceed to ->lookup.
    - 		 */
    --		mutex_lock(&kernfs_mutex);
    -+		down_read(&kernfs_rwsem);
    - 		spin_lock(&dentry->d_lock);
    - 		parent = kernfs_dentry_node(dentry->d_parent);
    - 		if (parent) {
    - 			if (kernfs_dir_changed(parent, dentry)) {
    - 				spin_unlock(&dentry->d_lock);
    --				mutex_unlock(&kernfs_mutex);
    -+				up_read(&kernfs_rwsem);
    - 				return 0;
    - 			}
    - 		}
    - 		spin_unlock(&dentry->d_lock);
    --		mutex_unlock(&kernfs_mutex);
    -+		up_read(&kernfs_rwsem);
    - 
    - 		/* The kernfs parent node hasn't changed, leave the
    - 		 * dentry negative and return success.
    -@@ fs/kernfs/dir.c: static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
    - 	}
    - 
    - 	kn = kernfs_dentry_node(dentry);
    --	mutex_lock(&kernfs_mutex);
    -+	down_read(&kernfs_rwsem);
    - 
    - 	/* The kernfs node has been deactivated */
    - 	if (!kernfs_active(kn))
    -@@ fs/kernfs/dir.c: static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
    - 	    kernfs_info(dentry->d_sb)->ns != kn->ns)
    - 		goto out_bad;
    - 
    --	mutex_unlock(&kernfs_mutex);
    -+	up_read(&kernfs_rwsem);
    - 	return 1;
    - out_bad:
    --	mutex_unlock(&kernfs_mutex);
    -+	up_read(&kernfs_rwsem);
    - 	return 0;
    - }
    - 
     @@ fs/kernfs/dir.c: static struct dentry *kernfs_iop_lookup(struct inode *dir,
      	struct inode *inode = NULL;
      	const void *ns = NULL;
    @@ fs/kernfs/dir.c: int kernfs_remove_by_name_ns(struct kernfs_node *parent, const
     +	down_write(&kernfs_rwsem);
      
      	kn = kernfs_find_ns(parent, name, ns);
    - 	if (kn)
    - 		__kernfs_remove(kn);
    + 	if (kn) {
    +@@ fs/kernfs/dir.c: int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name,
    + 		kernfs_put(kn);
    + 	}
      
     -	mutex_unlock(&kernfs_mutex);
     +	up_write(&kernfs_rwsem);
    @@ fs/kernfs/inode.c: int kernfs_setattr(struct kernfs_node *kn, const struct iattr
      	return ret;
      }
      
    -@@ fs/kernfs/inode.c: int kernfs_iop_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
    +@@ fs/kernfs/inode.c: int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr)
      	if (!kn)
      		return -EINVAL;
      
     -	mutex_lock(&kernfs_mutex);
     +	down_write(&kernfs_rwsem);
    - 	error = setattr_prepare(&init_user_ns, dentry, iattr);
    + 	error = setattr_prepare(dentry, iattr);
      	if (error)
      		goto out;
    -@@ fs/kernfs/inode.c: int kernfs_iop_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
    - 	setattr_copy(&init_user_ns, inode, iattr);
    +@@ fs/kernfs/inode.c: int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr)
    + 	setattr_copy(inode, iattr);
      
      out:
     -	mutex_unlock(&kernfs_mutex);
    @@ fs/kernfs/inode.c: int kernfs_iop_setattr(struct user_namespace *mnt_userns, str
      	return error;
      }
      
    -@@ fs/kernfs/inode.c: int kernfs_iop_getattr(struct user_namespace *mnt_userns,
    +@@ fs/kernfs/inode.c: int kernfs_iop_getattr(const struct path *path, struct kstat *stat,
      	struct inode *inode = d_inode(path->dentry);
      	struct kernfs_node *kn = inode->i_private;
      
    @@ fs/kernfs/inode.c: int kernfs_iop_getattr(struct user_namespace *mnt_userns,
     -	mutex_unlock(&kernfs_mutex);
     +	up_write(&kernfs_rwsem);
      
    - 	generic_fillattr(&init_user_ns, inode, stat);
    + 	generic_fillattr(inode, stat);
      	return 0;
    -@@ fs/kernfs/inode.c: int kernfs_iop_permission(struct user_namespace *mnt_userns,
    +@@ fs/kernfs/inode.c: int kernfs_iop_permission(struct inode *inode, int mask)
      
      	kn = inode->i_private;
      
    @@ fs/kernfs/inode.c: int kernfs_iop_permission(struct user_namespace *mnt_userns,
     -	mutex_unlock(&kernfs_mutex);
     +	up_write(&kernfs_rwsem);
      
    - 	return generic_permission(&init_user_ns, inode, mask);
    + 	return generic_permission(inode, mask);
      }
     
      ## fs/kernfs/kernfs-internal.h ##
---

Results of testing on various branches:

| Branch                    | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-5.15.y       |  Success    |  Success   |

  reply	other threads:[~2025-05-22  2:03 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-21  1:53 [PATCH 5.10 0/5] kernfs: backport locking and concurrency improvement Qingfang Deng
2025-05-21  1:53 ` [PATCH 5.10 1/5] kernfs: add a revision to identify directory node changes Qingfang Deng
2025-05-21  4:16   ` Greg Kroah-Hartman
2025-05-22  2:07   ` Sasha Levin
2025-05-21  1:53 ` [PATCH 5.10 2/5] kernfs: use VFS negative dentry caching Qingfang Deng
2025-05-22  2:05   ` Sasha Levin
2025-05-21  1:53 ` [PATCH 5.10 3/5] kernfs: switch kernfs to use an rwsem Qingfang Deng
2025-05-22  2:03   ` Sasha Levin [this message]
2025-05-21  1:53 ` [PATCH 5.10 4/5] kernfs: use i_lock to protect concurrent inode updates Qingfang Deng
2025-05-22  2:07   ` Sasha Levin
2025-05-21  1:53 ` [PATCH 5.10 5/5] kernfs: dont call d_splice_alias() under kernfs node lock Qingfang Deng
2025-05-22  2:08   ` Sasha Levin
2025-05-21  4:15 ` [PATCH 5.10 0/5] kernfs: backport locking and concurrency improvement Greg Kroah-Hartman
2025-05-21  5:35 ` Ian Kent
2025-05-21  6:09   ` Ian Kent

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=20250521154443-367c6fc07dc3045a@stable.kernel.org \
    --to=sashal@kernel.org \
    --cc=dqfext@gmail.com \
    --cc=stable@vger.kernel.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.