0001
0002 #ifndef _BCACHE_SYSFS_H_
0003 #define _BCACHE_SYSFS_H_
0004
0005 #define KTYPE(type) \
0006 struct kobj_type type ## _ktype = { \
0007 .release = type ## _release, \
0008 .sysfs_ops = &((const struct sysfs_ops) { \
0009 .show = type ## _show, \
0010 .store = type ## _store \
0011 }), \
0012 .default_groups = type ## _groups \
0013 }
0014
0015 #define SHOW(fn) \
0016 static ssize_t fn ## _show(struct kobject *kobj, struct attribute *attr,\
0017 char *buf) \
0018
0019 #define STORE(fn) \
0020 static ssize_t fn ## _store(struct kobject *kobj, struct attribute *attr,\
0021 const char *buf, size_t size) \
0022
0023 #define SHOW_LOCKED(fn) \
0024 SHOW(fn) \
0025 { \
0026 ssize_t ret; \
0027 mutex_lock(&bch_register_lock); \
0028 ret = __ ## fn ## _show(kobj, attr, buf); \
0029 mutex_unlock(&bch_register_lock); \
0030 return ret; \
0031 }
0032
0033 #define STORE_LOCKED(fn) \
0034 STORE(fn) \
0035 { \
0036 ssize_t ret; \
0037 mutex_lock(&bch_register_lock); \
0038 ret = __ ## fn ## _store(kobj, attr, buf, size); \
0039 mutex_unlock(&bch_register_lock); \
0040 return ret; \
0041 }
0042
0043 #define __sysfs_attribute(_name, _mode) \
0044 static struct attribute sysfs_##_name = \
0045 { .name = #_name, .mode = _mode }
0046
0047 #define write_attribute(n) __sysfs_attribute(n, 0200)
0048 #define read_attribute(n) __sysfs_attribute(n, 0444)
0049 #define rw_attribute(n) __sysfs_attribute(n, 0644)
0050
0051 #define sysfs_printf(file, fmt, ...) \
0052 do { \
0053 if (attr == &sysfs_ ## file) \
0054 return sysfs_emit(buf, fmt "\n", __VA_ARGS__); \
0055 } while (0)
0056
0057 #define sysfs_print(file, var) \
0058 do { \
0059 if (attr == &sysfs_ ## file) \
0060 return sysfs_emit(buf, \
0061 __builtin_types_compatible_p(typeof(var), int) \
0062 ? "%i\n" : \
0063 __builtin_types_compatible_p(typeof(var), unsigned int) \
0064 ? "%u\n" : \
0065 __builtin_types_compatible_p(typeof(var), long) \
0066 ? "%li\n" : \
0067 __builtin_types_compatible_p(typeof(var), unsigned long)\
0068 ? "%lu\n" : \
0069 __builtin_types_compatible_p(typeof(var), int64_t) \
0070 ? "%lli\n" : \
0071 __builtin_types_compatible_p(typeof(var), uint64_t) \
0072 ? "%llu\n" : \
0073 __builtin_types_compatible_p(typeof(var), const char *) \
0074 ? "%s\n" : "%i\n", var); \
0075 } while (0)
0076
0077 #define sysfs_hprint(file, val) \
0078 do { \
0079 if (attr == &sysfs_ ## file) { \
0080 ssize_t ret = bch_hprint(buf, val); \
0081 strcat(buf, "\n"); \
0082 return ret + 1; \
0083 } \
0084 } while (0)
0085
0086 #define var_printf(_var, fmt) sysfs_printf(_var, fmt, var(_var))
0087 #define var_print(_var) sysfs_print(_var, var(_var))
0088 #define var_hprint(_var) sysfs_hprint(_var, var(_var))
0089
0090 #define sysfs_strtoul(file, var) \
0091 do { \
0092 if (attr == &sysfs_ ## file) \
0093 return strtoul_safe(buf, var) ?: (ssize_t) size; \
0094 } while (0)
0095
0096 #define sysfs_strtoul_bool(file, var) \
0097 do { \
0098 if (attr == &sysfs_ ## file) { \
0099 unsigned long v = strtoul_or_return(buf); \
0100 \
0101 var = v ? 1 : 0; \
0102 return size; \
0103 } \
0104 } while (0)
0105
0106 #define sysfs_strtoul_clamp(file, var, min, max) \
0107 do { \
0108 if (attr == &sysfs_ ## file) { \
0109 unsigned long v = 0; \
0110 ssize_t ret; \
0111 ret = strtoul_safe_clamp(buf, v, min, max); \
0112 if (!ret) { \
0113 var = v; \
0114 return size; \
0115 } \
0116 return ret; \
0117 } \
0118 } while (0)
0119
0120 #define strtoul_or_return(cp) \
0121 ({ \
0122 unsigned long _v; \
0123 int _r = kstrtoul(cp, 10, &_v); \
0124 if (_r) \
0125 return _r; \
0126 _v; \
0127 })
0128
0129 #define strtoi_h_or_return(cp, v) \
0130 do { \
0131 int _r = strtoi_h(cp, &v); \
0132 if (_r) \
0133 return _r; \
0134 } while (0)
0135
0136 #define sysfs_hatoi(file, var) \
0137 do { \
0138 if (attr == &sysfs_ ## file) \
0139 return strtoi_h(buf, &var) ?: (ssize_t) size; \
0140 } while (0)
0141
0142 #endif