143 lines · c
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_ */143