sysfs.h 3.8 KB

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