summaryrefslogtreecommitdiff
path: root/fs/bcachefs/enumerated_ref.h
blob: ec01cf59ef8069871e96d31767979727ac8c2bd9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _BCACHEFS_ENUMERATED_REF_H
#define _BCACHEFS_ENUMERATED_REF_H

#include "enumerated_ref_types.h"

/*
 * A refcount where the users are enumerated: in debug mode, we create sepate
 * refcounts for each user, to make leaks and refcount errors easy to track
 * down:
 */

#ifdef ENUMERATED_REF_DEBUG
void enumerated_ref_get(struct enumerated_ref *, unsigned);
bool __enumerated_ref_tryget(struct enumerated_ref *, unsigned);
bool enumerated_ref_tryget(struct enumerated_ref *, unsigned);
void enumerated_ref_put(struct enumerated_ref *, unsigned);
#else

static inline void enumerated_ref_get(struct enumerated_ref *ref, unsigned idx)
{
	percpu_ref_get(&ref->ref);
}

static inline bool __enumerated_ref_tryget(struct enumerated_ref *ref, unsigned idx)
{
	return percpu_ref_tryget(&ref->ref);
}

static inline bool enumerated_ref_tryget(struct enumerated_ref *ref, unsigned idx)
{
	return percpu_ref_tryget_live(&ref->ref);
}

static inline void enumerated_ref_put(struct enumerated_ref *ref, unsigned idx)
{
	percpu_ref_put(&ref->ref);
}
#endif

static inline bool enumerated_ref_is_zero(struct enumerated_ref *ref)
{
#ifndef ENUMERATED_REF_DEBUG
	return percpu_ref_is_zero(&ref->ref);
#else
	for (unsigned i = 0; i < ref->nr; i++)
		if (atomic_long_read(&ref->refs[i]))
			return false;
	return true;
#endif
}

void enumerated_ref_stop_async(struct enumerated_ref *);
void enumerated_ref_stop(struct enumerated_ref *, const char * const[]);
void enumerated_ref_start(struct enumerated_ref *);

void enumerated_ref_exit(struct enumerated_ref *);
int enumerated_ref_init(struct enumerated_ref *, unsigned,
			void (*stop_fn)(struct enumerated_ref *));

struct printbuf;
void enumerated_ref_to_text(struct printbuf *,
			    struct enumerated_ref *,
			    const char * const[]);

#endif /* _BCACHEFS_ENUMERATED_REF_H */