Skip to content

Commit 1f84344

Browse files
committed
Merge patch series "ns: rework reference counting"
Christian Brauner <brauner@kernel.org> says: Stop open accesses to the reference counts and cargo-culting the same code in all namespace. Use a set of dedicated helpers and make the actual count private. * patches from https://lore.kernel.org/20250918-work-namespace-ns_ref-v1-0-1b0a98ee041e@kernel.org: ns: rename to __ns_ref nsfs: port to ns_ref_*() helpers net: port to ns_ref_*() helpers uts: port to ns_ref_*() helpers ipv4: use check_net() net: use check_net() net-sysfs: use check_net() user: port to ns_ref_*() helpers time: port to ns_ref_*() helpers pid: port to ns_ref_*() helpers ipc: port to ns_ref_*() helpers cgroup: port to ns_ref_*() helpers mnt: port to ns_ref_*() helpers ns: add reference count helpers Signed-off-by: Christian Brauner <brauner@kernel.org>
2 parents bb57289 + 024596a commit 1f84344

25 files changed

Lines changed: 74 additions & 49 deletions

fs/mount.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ static inline void detach_mounts(struct dentry *dentry)
143143

144144
static inline void get_mnt_ns(struct mnt_namespace *ns)
145145
{
146-
refcount_inc(&ns->ns.count);
146+
ns_ref_inc(ns);
147147
}
148148

149149
extern seqlock_t mount_lock;

fs/namespace.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,7 +2110,7 @@ struct mnt_namespace *get_sequential_mnt_ns(struct mnt_namespace *mntns, bool pr
21102110
* the mount namespace and it might already be on its
21112111
* deathbed.
21122112
*/
2113-
if (!refcount_inc_not_zero(&mntns->ns.count))
2113+
if (!ns_ref_get(mntns))
21142114
continue;
21152115

21162116
return mntns;
@@ -6015,7 +6015,7 @@ struct mnt_namespace init_mnt_ns = {
60156015
.ns.inum = PROC_MNT_INIT_INO,
60166016
.ns.ops = &mntns_operations,
60176017
.user_ns = &init_user_ns,
6018-
.ns.count = REFCOUNT_INIT(1),
6018+
.ns.__ns_ref = REFCOUNT_INIT(1),
60196019
.passive = REFCOUNT_INIT(1),
60206020
.mounts = RB_ROOT,
60216021
.poll = __WAIT_QUEUE_HEAD_INITIALIZER(init_mnt_ns.poll),
@@ -6084,7 +6084,7 @@ void __init mnt_init(void)
60846084

60856085
void put_mnt_ns(struct mnt_namespace *ns)
60866086
{
6087-
if (!refcount_dec_and_test(&ns->ns.count))
6087+
if (!ns_ref_put(ns))
60886088
return;
60896089
namespace_lock();
60906090
emptied_ns = ns;

fs/nsfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ static struct dentry *nsfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
492492
VFS_WARN_ON_ONCE(ns->ops->type != fid->ns_type);
493493
VFS_WARN_ON_ONCE(ns->inum != fid->ns_inum);
494494

495-
if (!refcount_inc_not_zero(&ns->count))
495+
if (!__ns_ref_get(ns))
496496
return NULL;
497497
}
498498

include/linux/cgroup_namespace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ int cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen,
2929

3030
static inline void get_cgroup_ns(struct cgroup_namespace *ns)
3131
{
32-
refcount_inc(&ns->ns.count);
32+
ns_ref_inc(ns);
3333
}
3434

3535
static inline void put_cgroup_ns(struct cgroup_namespace *ns)
3636
{
37-
if (refcount_dec_and_test(&ns->ns.count))
37+
if (ns_ref_put(ns))
3838
free_cgroup_ns(ns);
3939
}
4040

include/linux/ipc_namespace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,14 @@ extern struct ipc_namespace *copy_ipcs(unsigned long flags,
140140
static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
141141
{
142142
if (ns)
143-
refcount_inc(&ns->ns.count);
143+
ns_ref_inc(ns);
144144
return ns;
145145
}
146146

147147
static inline struct ipc_namespace *get_ipc_ns_not_zero(struct ipc_namespace *ns)
148148
{
149149
if (ns) {
150-
if (refcount_inc_not_zero(&ns->ns.count))
150+
if (ns_ref_get(ns))
151151
return ns;
152152
}
153153

include/linux/ns_common.h

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ struct ns_common {
2929
struct dentry *stashed;
3030
const struct proc_ns_operations *ops;
3131
unsigned int inum;
32-
refcount_t count;
32+
refcount_t __ns_ref; /* do not use directly */
3333
union {
3434
struct {
3535
u64 ns_id;
@@ -43,16 +43,24 @@ struct ns_common {
4343
int __ns_common_init(struct ns_common *ns, const struct proc_ns_operations *ops, int inum);
4444
void __ns_common_free(struct ns_common *ns);
4545

46-
#define to_ns_common(__ns) \
47-
_Generic((__ns), \
48-
struct cgroup_namespace *: &(__ns)->ns, \
49-
struct ipc_namespace *: &(__ns)->ns, \
50-
struct mnt_namespace *: &(__ns)->ns, \
51-
struct net *: &(__ns)->ns, \
52-
struct pid_namespace *: &(__ns)->ns, \
53-
struct time_namespace *: &(__ns)->ns, \
54-
struct user_namespace *: &(__ns)->ns, \
55-
struct uts_namespace *: &(__ns)->ns)
46+
#define to_ns_common(__ns) \
47+
_Generic((__ns), \
48+
struct cgroup_namespace *: &(__ns)->ns, \
49+
const struct cgroup_namespace *: &(__ns)->ns, \
50+
struct ipc_namespace *: &(__ns)->ns, \
51+
const struct ipc_namespace *: &(__ns)->ns, \
52+
struct mnt_namespace *: &(__ns)->ns, \
53+
const struct mnt_namespace *: &(__ns)->ns, \
54+
struct net *: &(__ns)->ns, \
55+
const struct net *: &(__ns)->ns, \
56+
struct pid_namespace *: &(__ns)->ns, \
57+
const struct pid_namespace *: &(__ns)->ns, \
58+
struct time_namespace *: &(__ns)->ns, \
59+
const struct time_namespace *: &(__ns)->ns, \
60+
struct user_namespace *: &(__ns)->ns, \
61+
const struct user_namespace *: &(__ns)->ns, \
62+
struct uts_namespace *: &(__ns)->ns, \
63+
const struct uts_namespace *: &(__ns)->ns)
5664

5765
#define ns_init_inum(__ns) \
5866
_Generic((__ns), \
@@ -83,4 +91,21 @@ void __ns_common_free(struct ns_common *ns);
8391

8492
#define ns_common_free(__ns) __ns_common_free(to_ns_common((__ns)))
8593

94+
static __always_inline __must_check bool __ns_ref_put(struct ns_common *ns)
95+
{
96+
return refcount_dec_and_test(&ns->__ns_ref);
97+
}
98+
99+
static __always_inline __must_check bool __ns_ref_get(struct ns_common *ns)
100+
{
101+
return refcount_inc_not_zero(&ns->__ns_ref);
102+
}
103+
104+
#define ns_ref_read(__ns) refcount_read(&to_ns_common((__ns))->__ns_ref)
105+
#define ns_ref_inc(__ns) refcount_inc(&to_ns_common((__ns))->__ns_ref)
106+
#define ns_ref_get(__ns) __ns_ref_get(to_ns_common((__ns)))
107+
#define ns_ref_put(__ns) __ns_ref_put(to_ns_common((__ns)))
108+
#define ns_ref_put_and_lock(__ns, __lock) \
109+
refcount_dec_and_lock(&to_ns_common((__ns))->__ns_ref, (__lock))
110+
86111
#endif

include/linux/pid_namespace.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static inline struct pid_namespace *to_pid_ns(struct ns_common *ns)
6262
static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns)
6363
{
6464
if (ns != &init_pid_ns)
65-
refcount_inc(&ns->ns.count);
65+
ns_ref_inc(ns);
6666
return ns;
6767
}
6868

include/linux/time_namespace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ extern void timens_commit(struct task_struct *tsk, struct time_namespace *ns);
4444

4545
static inline struct time_namespace *get_time_ns(struct time_namespace *ns)
4646
{
47-
refcount_inc(&ns->ns.count);
47+
ns_ref_inc(ns);
4848
return ns;
4949
}
5050

@@ -57,7 +57,7 @@ struct page *find_timens_vvar_page(struct vm_area_struct *vma);
5757

5858
static inline void put_time_ns(struct time_namespace *ns)
5959
{
60-
if (refcount_dec_and_test(&ns->ns.count))
60+
if (ns_ref_put(ns))
6161
free_time_ns(ns);
6262
}
6363

include/linux/user_namespace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ static inline struct user_namespace *to_user_ns(struct ns_common *ns)
176176
static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
177177
{
178178
if (ns)
179-
refcount_inc(&ns->ns.count);
179+
ns_ref_inc(ns);
180180
return ns;
181181
}
182182

@@ -186,7 +186,7 @@ extern void __put_user_ns(struct user_namespace *ns);
186186

187187
static inline void put_user_ns(struct user_namespace *ns)
188188
{
189-
if (ns && refcount_dec_and_test(&ns->ns.count))
189+
if (ns && ns_ref_put(ns))
190190
__put_user_ns(ns);
191191
}
192192

include/linux/uts_namespace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ static inline struct uts_namespace *to_uts_ns(struct ns_common *ns)
2525

2626
static inline void get_uts_ns(struct uts_namespace *ns)
2727
{
28-
refcount_inc(&ns->ns.count);
28+
ns_ref_inc(ns);
2929
}
3030

3131
extern struct uts_namespace *copy_utsname(unsigned long flags,
@@ -34,7 +34,7 @@ extern void free_uts_ns(struct uts_namespace *ns);
3434

3535
static inline void put_uts_ns(struct uts_namespace *ns)
3636
{
37-
if (refcount_dec_and_test(&ns->ns.count))
37+
if (ns_ref_put(ns))
3838
free_uts_ns(ns);
3939
}
4040

0 commit comments

Comments
 (0)