xref: /linux/drivers/md/bcache/sysfs.h (revision 93d90ad708b8da6efc0e487b66111aa9db7f70c7)
1 #ifndef _BCACHE_SYSFS_H_
2 #define _BCACHE_SYSFS_H_
3 
4 #define KTYPE(type)							\
5 struct 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)							\
15 static ssize_t fn ## _show(struct kobject *kobj, struct attribute *attr,\
16 			   char *buf)					\
17 
18 #define STORE(fn)							\
19 static ssize_t fn ## _store(struct kobject *kobj, struct attribute *attr,\
20 			    const char *buf, size_t size)		\
21 
22 #define SHOW_LOCKED(fn)							\
23 SHOW(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)						\
33 STORE(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, ...)					\
51 do {									\
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)						\
57 do {									\
58 	if (attr == &sysfs_ ## file)					\
59 		return snprint(buf, PAGE_SIZE, var);			\
60 } while (0)
61 
62 #define sysfs_hprint(file, val)						\
63 do {									\
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)					\
76 do {									\
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)			\
82 do {									\
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)					\
98 do {									\
99 	int _r = strtoi_h(cp, &v);					\
100 	if (_r)								\
101 		return _r;						\
102 } while (0)
103 
104 #define sysfs_hatoi(file, var)						\
105 do {									\
106 	if (attr == &sysfs_ ## file)					\
107 		return strtoi_h(buf, &var) ?: (ssize_t) size;		\
108 } while (0)
109 
110 #endif  /* _BCACHE_SYSFS_H_ */
111