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_ */
111