Loading...
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _BCACHE_SYSFS_H_
3#define _BCACHE_SYSFS_H_
4
5#define KTYPE(type) \
6const struct kobj_type type ## _ktype = { \
7 .release = type ## _release, \
8 .sysfs_ops = &((const struct sysfs_ops) { \
9 .show = type ## _show, \
10 .store = type ## _store \
11 }), \
12 .default_groups = type ## _groups \
13}
14
15#define SHOW(fn) \
16static ssize_t fn ## _show(struct kobject *kobj, struct attribute *attr,\
17 char *buf) \
18
19#define STORE(fn) \
20static ssize_t fn ## _store(struct kobject *kobj, struct attribute *attr,\
21 const char *buf, size_t size) \
22
23#define SHOW_LOCKED(fn) \
24SHOW(fn) \
25{ \
26 ssize_t ret; \
27 mutex_lock(&bch_register_lock); \
28 ret = __ ## fn ## _show(kobj, attr, buf); \
29 mutex_unlock(&bch_register_lock); \
30 return ret; \
31}
32
33#define STORE_LOCKED(fn) \
34STORE(fn) \
35{ \
36 ssize_t ret; \
37 mutex_lock(&bch_register_lock); \
38 ret = __ ## fn ## _store(kobj, attr, buf, size); \
39 mutex_unlock(&bch_register_lock); \
40 return ret; \
41}
42
43#define __sysfs_attribute(_name, _mode) \
44 static struct attribute sysfs_##_name = \
45 { .name = #_name, .mode = _mode }
46
47#define write_attribute(n) __sysfs_attribute(n, 0200)
48#define read_attribute(n) __sysfs_attribute(n, 0444)
49#define rw_attribute(n) __sysfs_attribute(n, 0644)
50
51#define sysfs_printf(file, fmt, ...) \
52do { \
53 if (attr == &sysfs_ ## file) \
54 return sysfs_emit(buf, fmt "\n", __VA_ARGS__); \
55} while (0)
56
57#define sysfs_print(file, var) \
58do { \
59 if (attr == &sysfs_ ## file) \
60 return sysfs_emit(buf, \
61 __builtin_types_compatible_p(typeof(var), int) \
62 ? "%i\n" : \
63 __builtin_types_compatible_p(typeof(var), unsigned int) \
64 ? "%u\n" : \
65 __builtin_types_compatible_p(typeof(var), long) \
66 ? "%li\n" : \
67 __builtin_types_compatible_p(typeof(var), unsigned long)\
68 ? "%lu\n" : \
69 __builtin_types_compatible_p(typeof(var), int64_t) \
70 ? "%lli\n" : \
71 __builtin_types_compatible_p(typeof(var), uint64_t) \
72 ? "%llu\n" : \
73 __builtin_types_compatible_p(typeof(var), const char *) \
74 ? "%s\n" : "%i\n", var); \
75} while (0)
76
77#define sysfs_hprint(file, val) \
78do { \
79 if (attr == &sysfs_ ## file) { \
80 ssize_t ret = bch_hprint(buf, val); \
81 strcat(buf, "\n"); \
82 return ret + 1; \
83 } \
84} while (0)
85
86#define var_printf(_var, fmt) sysfs_printf(_var, fmt, var(_var))
87#define var_print(_var) sysfs_print(_var, var(_var))
88#define var_hprint(_var) sysfs_hprint(_var, var(_var))
89
90#define sysfs_strtoul(file, var) \
91do { \
92 if (attr == &sysfs_ ## file) \
93 return strtoul_safe(buf, var) ?: (ssize_t) size; \
94} while (0)
95
96#define sysfs_strtoul_bool(file, var) \
97do { \
98 if (attr == &sysfs_ ## file) { \
99 unsigned long v = strtoul_or_return(buf); \
100 \
101 var = v ? 1 : 0; \
102 return size; \
103 } \
104} while (0)
105
106#define sysfs_strtoul_clamp(file, var, min, max) \
107do { \
108 if (attr == &sysfs_ ## file) { \
109 unsigned long v = 0; \
110 ssize_t ret; \
111 ret = strtoul_safe_clamp(buf, v, min, max); \
112 if (!ret) { \
113 var = v; \
114 return size; \
115 } \
116 return ret; \
117 } \
118} while (0)
119
120#define strtoul_or_return(cp) \
121({ \
122 unsigned long _v; \
123 int _r = kstrtoul(cp, 10, &_v); \
124 if (_r) \
125 return _r; \
126 _v; \
127})
128
129#define strtoi_h_or_return(cp, v) \
130do { \
131 int _r = strtoi_h(cp, &v); \
132 if (_r) \
133 return _r; \
134} while (0)
135
136#define sysfs_hatoi(file, var) \
137do { \
138 if (attr == &sysfs_ ## file) \
139 return strtoi_h(buf, &var) ?: (ssize_t) size; \
140} while (0)
141
142#endif /* _BCACHE_SYSFS_H_ */
1#ifndef _BCACHE_SYSFS_H_
2#define _BCACHE_SYSFS_H_
3
4#define KTYPE(type) \
5struct kobj_type type ## _ktype = { \
6 .release = type ## _release, \
7 .sysfs_ops = &((const struct sysfs_ops) { \
8 .show = type ## _show, \
9 .store = type ## _store \
10 }), \
11 .default_attrs = type ## _files \
12}
13
14#define SHOW(fn) \
15static ssize_t fn ## _show(struct kobject *kobj, struct attribute *attr,\
16 char *buf) \
17
18#define STORE(fn) \
19static ssize_t fn ## _store(struct kobject *kobj, struct attribute *attr,\
20 const char *buf, size_t size) \
21
22#define SHOW_LOCKED(fn) \
23SHOW(fn) \
24{ \
25 ssize_t ret; \
26 mutex_lock(&bch_register_lock); \
27 ret = __ ## fn ## _show(kobj, attr, buf); \
28 mutex_unlock(&bch_register_lock); \
29 return ret; \
30}
31
32#define STORE_LOCKED(fn) \
33STORE(fn) \
34{ \
35 ssize_t ret; \
36 mutex_lock(&bch_register_lock); \
37 ret = __ ## fn ## _store(kobj, attr, buf, size); \
38 mutex_unlock(&bch_register_lock); \
39 return ret; \
40}
41
42#define __sysfs_attribute(_name, _mode) \
43 static struct attribute sysfs_##_name = \
44 { .name = #_name, .mode = _mode }
45
46#define write_attribute(n) __sysfs_attribute(n, S_IWUSR)
47#define read_attribute(n) __sysfs_attribute(n, S_IRUGO)
48#define rw_attribute(n) __sysfs_attribute(n, S_IRUGO|S_IWUSR)
49
50#define sysfs_printf(file, fmt, ...) \
51do { \
52 if (attr == &sysfs_ ## file) \
53 return snprintf(buf, PAGE_SIZE, fmt "\n", __VA_ARGS__); \
54} while (0)
55
56#define sysfs_print(file, var) \
57do { \
58 if (attr == &sysfs_ ## file) \
59 return snprint(buf, PAGE_SIZE, var); \
60} while (0)
61
62#define sysfs_hprint(file, val) \
63do { \
64 if (attr == &sysfs_ ## file) { \
65 ssize_t ret = bch_hprint(buf, val); \
66 strcat(buf, "\n"); \
67 return ret + 1; \
68 } \
69} while (0)
70
71#define var_printf(_var, fmt) sysfs_printf(_var, fmt, var(_var))
72#define var_print(_var) sysfs_print(_var, var(_var))
73#define var_hprint(_var) sysfs_hprint(_var, var(_var))
74
75#define sysfs_strtoul(file, var) \
76do { \
77 if (attr == &sysfs_ ## file) \
78 return strtoul_safe(buf, var) ?: (ssize_t) size; \
79} while (0)
80
81#define sysfs_strtoul_clamp(file, var, min, max) \
82do { \
83 if (attr == &sysfs_ ## file) \
84 return strtoul_safe_clamp(buf, var, min, max) \
85 ?: (ssize_t) size; \
86} while (0)
87
88#define strtoul_or_return(cp) \
89({ \
90 unsigned long _v; \
91 int _r = kstrtoul(cp, 10, &_v); \
92 if (_r) \
93 return _r; \
94 _v; \
95})
96
97#define strtoi_h_or_return(cp, v) \
98do { \
99 int _r = strtoi_h(cp, &v); \
100 if (_r) \
101 return _r; \
102} while (0)
103
104#define sysfs_hatoi(file, var) \
105do { \
106 if (attr == &sysfs_ ## file) \
107 return strtoi_h(buf, &var) ?: (ssize_t) size; \
108} while (0)
109
110#endif /* _BCACHE_SYSFS_H_ */