1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun #ifndef _BCACHE_SYSFS_H_ 3*4882a593Smuzhiyun #define _BCACHE_SYSFS_H_ 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun #define KTYPE(type) \ 6*4882a593Smuzhiyun struct kobj_type type ## _ktype = { \ 7*4882a593Smuzhiyun .release = type ## _release, \ 8*4882a593Smuzhiyun .sysfs_ops = &((const struct sysfs_ops) { \ 9*4882a593Smuzhiyun .show = type ## _show, \ 10*4882a593Smuzhiyun .store = type ## _store \ 11*4882a593Smuzhiyun }), \ 12*4882a593Smuzhiyun .default_attrs = type ## _files \ 13*4882a593Smuzhiyun } 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun #define SHOW(fn) \ 16*4882a593Smuzhiyun static ssize_t fn ## _show(struct kobject *kobj, struct attribute *attr,\ 17*4882a593Smuzhiyun char *buf) \ 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun #define STORE(fn) \ 20*4882a593Smuzhiyun static ssize_t fn ## _store(struct kobject *kobj, struct attribute *attr,\ 21*4882a593Smuzhiyun const char *buf, size_t size) \ 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun #define SHOW_LOCKED(fn) \ 24*4882a593Smuzhiyun SHOW(fn) \ 25*4882a593Smuzhiyun { \ 26*4882a593Smuzhiyun ssize_t ret; \ 27*4882a593Smuzhiyun mutex_lock(&bch_register_lock); \ 28*4882a593Smuzhiyun ret = __ ## fn ## _show(kobj, attr, buf); \ 29*4882a593Smuzhiyun mutex_unlock(&bch_register_lock); \ 30*4882a593Smuzhiyun return ret; \ 31*4882a593Smuzhiyun } 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun #define STORE_LOCKED(fn) \ 34*4882a593Smuzhiyun STORE(fn) \ 35*4882a593Smuzhiyun { \ 36*4882a593Smuzhiyun ssize_t ret; \ 37*4882a593Smuzhiyun mutex_lock(&bch_register_lock); \ 38*4882a593Smuzhiyun ret = __ ## fn ## _store(kobj, attr, buf, size); \ 39*4882a593Smuzhiyun mutex_unlock(&bch_register_lock); \ 40*4882a593Smuzhiyun return ret; \ 41*4882a593Smuzhiyun } 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun #define __sysfs_attribute(_name, _mode) \ 44*4882a593Smuzhiyun static struct attribute sysfs_##_name = \ 45*4882a593Smuzhiyun { .name = #_name, .mode = _mode } 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun #define write_attribute(n) __sysfs_attribute(n, 0200) 48*4882a593Smuzhiyun #define read_attribute(n) __sysfs_attribute(n, 0444) 49*4882a593Smuzhiyun #define rw_attribute(n) __sysfs_attribute(n, 0644) 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun #define sysfs_printf(file, fmt, ...) \ 52*4882a593Smuzhiyun do { \ 53*4882a593Smuzhiyun if (attr == &sysfs_ ## file) \ 54*4882a593Smuzhiyun return snprintf(buf, PAGE_SIZE, fmt "\n", __VA_ARGS__); \ 55*4882a593Smuzhiyun } while (0) 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun #define sysfs_print(file, var) \ 58*4882a593Smuzhiyun do { \ 59*4882a593Smuzhiyun if (attr == &sysfs_ ## file) \ 60*4882a593Smuzhiyun return snprint(buf, PAGE_SIZE, var); \ 61*4882a593Smuzhiyun } while (0) 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun #define sysfs_hprint(file, val) \ 64*4882a593Smuzhiyun do { \ 65*4882a593Smuzhiyun if (attr == &sysfs_ ## file) { \ 66*4882a593Smuzhiyun ssize_t ret = bch_hprint(buf, val); \ 67*4882a593Smuzhiyun strcat(buf, "\n"); \ 68*4882a593Smuzhiyun return ret + 1; \ 69*4882a593Smuzhiyun } \ 70*4882a593Smuzhiyun } while (0) 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun #define var_printf(_var, fmt) sysfs_printf(_var, fmt, var(_var)) 73*4882a593Smuzhiyun #define var_print(_var) sysfs_print(_var, var(_var)) 74*4882a593Smuzhiyun #define var_hprint(_var) sysfs_hprint(_var, var(_var)) 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun #define sysfs_strtoul(file, var) \ 77*4882a593Smuzhiyun do { \ 78*4882a593Smuzhiyun if (attr == &sysfs_ ## file) \ 79*4882a593Smuzhiyun return strtoul_safe(buf, var) ?: (ssize_t) size; \ 80*4882a593Smuzhiyun } while (0) 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun #define sysfs_strtoul_bool(file, var) \ 83*4882a593Smuzhiyun do { \ 84*4882a593Smuzhiyun if (attr == &sysfs_ ## file) { \ 85*4882a593Smuzhiyun unsigned long v = strtoul_or_return(buf); \ 86*4882a593Smuzhiyun \ 87*4882a593Smuzhiyun var = v ? 1 : 0; \ 88*4882a593Smuzhiyun return size; \ 89*4882a593Smuzhiyun } \ 90*4882a593Smuzhiyun } while (0) 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun #define sysfs_strtoul_clamp(file, var, min, max) \ 93*4882a593Smuzhiyun do { \ 94*4882a593Smuzhiyun if (attr == &sysfs_ ## file) { \ 95*4882a593Smuzhiyun unsigned long v = 0; \ 96*4882a593Smuzhiyun ssize_t ret; \ 97*4882a593Smuzhiyun ret = strtoul_safe_clamp(buf, v, min, max); \ 98*4882a593Smuzhiyun if (!ret) { \ 99*4882a593Smuzhiyun var = v; \ 100*4882a593Smuzhiyun return size; \ 101*4882a593Smuzhiyun } \ 102*4882a593Smuzhiyun return ret; \ 103*4882a593Smuzhiyun } \ 104*4882a593Smuzhiyun } while (0) 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun #define strtoul_or_return(cp) \ 107*4882a593Smuzhiyun ({ \ 108*4882a593Smuzhiyun unsigned long _v; \ 109*4882a593Smuzhiyun int _r = kstrtoul(cp, 10, &_v); \ 110*4882a593Smuzhiyun if (_r) \ 111*4882a593Smuzhiyun return _r; \ 112*4882a593Smuzhiyun _v; \ 113*4882a593Smuzhiyun }) 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun #define strtoi_h_or_return(cp, v) \ 116*4882a593Smuzhiyun do { \ 117*4882a593Smuzhiyun int _r = strtoi_h(cp, &v); \ 118*4882a593Smuzhiyun if (_r) \ 119*4882a593Smuzhiyun return _r; \ 120*4882a593Smuzhiyun } while (0) 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun #define sysfs_hatoi(file, var) \ 123*4882a593Smuzhiyun do { \ 124*4882a593Smuzhiyun if (attr == &sysfs_ ## file) \ 125*4882a593Smuzhiyun return strtoi_h(buf, &var) ?: (ssize_t) size; \ 126*4882a593Smuzhiyun } while (0) 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun #endif /* _BCACHE_SYSFS_H_ */ 129