1
2 #ifndef _BCACHE_SYSFS_H_
3 #define _BCACHE_SYSFS_H_
4
5 #define KTYPE(type) \
6 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_attrs = type ## _files \
13 }
14
15 #define SHOW(fn) \
16 static ssize_t fn ## _show(struct kobject *kobj, struct attribute *attr,\
17 char *buf) \
18
19 #define STORE(fn) \
20 static ssize_t fn ## _store(struct kobject *kobj, struct attribute *attr,\
21 const char *buf, size_t size) \
22
23 #define SHOW_LOCKED(fn) \
24 SHOW(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) \
34 STORE(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, ...) \
52 do { \
53 if (attr == &sysfs_ ## file) \
54 return snprintf(buf, PAGE_SIZE, fmt "\n", __VA_ARGS__); \
55 } while (0)
56
57 #define sysfs_print(file, var) \
58 do { \
59 if (attr == &sysfs_ ## file) \
60 return snprint(buf, PAGE_SIZE, var); \
61 } while (0)
62
63 #define sysfs_hprint(file, val) \
64 do { \
65 if (attr == &sysfs_ ## file) { \
66 ssize_t ret = bch_hprint(buf, val); \
67 strcat(buf, "\n"); \
68 return ret + 1; \
69 } \
70 } while (0)
71
72 #define var_printf(_var, fmt) sysfs_printf(_var, fmt, var(_var))
73 #define var_print(_var) sysfs_print(_var, var(_var))
74 #define var_hprint(_var) sysfs_hprint(_var, var(_var))
75
76 #define sysfs_strtoul(file, var) \
77 do { \
78 if (attr == &sysfs_ ## file) \
79 return strtoul_safe(buf, var) ?: (ssize_t) size; \
80 } while (0)
81
82 #define sysfs_strtoul_bool(file, var) \
83 do { \
84 if (attr == &sysfs_ ## file) { \
85 unsigned long v = strtoul_or_return(buf); \
86 \
87 var = v ? 1 : 0; \
88 return size; \
89 } \
90 } while (0)
91
92 #define sysfs_strtoul_clamp(file, var, min, max) \
93 do { \
94 if (attr == &sysfs_ ## file) { \
95 unsigned long v = 0; \
96 ssize_t ret; \
97 ret = strtoul_safe_clamp(buf, v, min, max); \
98 if (!ret) { \
99 var = v; \
100 return size; \
101 } \
102 return ret; \
103 } \
104 } while (0)
105
106 #define strtoul_or_return(cp) \
107 ({ \
108 unsigned long _v; \
109 int _r = kstrtoul(cp, 10, &_v); \
110 if (_r) \
111 return _r; \
112 _v; \
113 })
114
115 #define strtoi_h_or_return(cp, v) \
116 do { \
117 int _r = strtoi_h(cp, &v); \
118 if (_r) \
119 return _r; \
120 } while (0)
121
122 #define sysfs_hatoi(file, var) \
123 do { \
124 if (attr == &sysfs_ ## file) \
125 return strtoi_h(buf, &var) ?: (ssize_t) size; \
126 } while (0)
127
128 #endif