[RFC PATCH v2 18/18] struct filename ->refcnt doesn't need to be atomic

Al Viro <[email protected]>
Newsgroups org.kernel.vger.audit,org.kernel.vger.io-uring,org.kernel.vger.linux-fsdevel
Message-ID <[email protected]>
... or visible outside of audit, really.  Note that references
held in delayed_filename always have refcount 1, and from the
moment of complete_getname() or equivalent point in getname...()
there won't be any references to struct filename instance left
in places visible to other threads.

Signed-off-by: Al Viro <[email protected]>
---
 fs/namei.c         | 10 +++++-----
 include/linux/fs.h |  8 +-------
 kernel/auditsc.c   |  6 ++++++
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 8530d75fb270..d6eac90084e1 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -146,7 +146,7 @@ static inline void free_filename(struct filename *p)
 static inline void initname(struct filename *name)
 {
 	name->aname = NULL;
-	atomic_set(&name->refcnt, 1);
+	name->refcnt = 1;
 }
 
 static int getname_long(struct filename *name, const char __user *filename)
@@ -284,13 +284,13 @@ void putname(struct filename *name)
 	if (IS_ERR_OR_NULL(name))
 		return;
 
-	refcnt = atomic_read(&name->refcnt);
+	refcnt = name->refcnt;
 	if (unlikely(refcnt != 1)) {
 		if (WARN_ON_ONCE(!refcnt))
 			return;
 
-		if (!atomic_dec_and_test(&name->refcnt))
-			return;
+		name->refcnt--;
+		return;
 	}
 
 	if (unlikely(name->name != name->iname))
@@ -323,7 +323,7 @@ int putname_to_delayed(struct delayed_filename *v, struct filename *__name)
 	struct filename *name __free(putname) = no_free_ptr(__name);
 	struct filename *copy;
 
-	if (likely(atomic_read(&name->refcnt) == 1)) {
+	if (likely(name->refcnt == 1)) {
 		v->__incomplete_filename = no_free_ptr(name);
 		return 0;
 	}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 52ee3bc1baa9..b21814b93dcd 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2837,7 +2837,7 @@ struct audit_names;
 #define EMBEDDED_NAME_MAX	128
 struct filename {
 	const char		*name;	/* pointer to actual string */
-	atomic_t		refcnt;
+	int			refcnt;
 	struct audit_names	*aname;
 	const char		iname[EMBEDDED_NAME_MAX];
 };
@@ -2947,12 +2947,6 @@ void dismiss_delayed_filename(struct delayed_filename *);
 int putname_to_delayed(struct delayed_filename *, struct filename *);
 struct filename *complete_getname(struct delayed_filename *);
 
-static inline struct filename *refname(struct filename *name)
-{
-	atomic_inc(&name->refcnt);
-	return name;
-}
-
 extern int finish_open(struct file *file, struct dentry *dentry,
 			int (*open)(struct inode *, struct file *));
 extern int finish_no_open(struct file *file, struct dentry *dentry);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index e59a094bb9f7..d71fc73455b2 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -2169,6 +2169,12 @@ static struct audit_names *audit_alloc_name(struct audit_context *context,
 	return aname;
 }
 
+static inline struct filename *refname(struct filename *name)
+{
+	name->refcnt++;
+	return name;
+}
+
 /**
  * __audit_getname - add a name to the list
  * @name: name to add
-- 
2.47.3
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.