sysfs.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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_attrs = type ## _files \
  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 snprintf(buf, PAGE_SIZE, fmt "\n", __VA_ARGS__); \
  47. } while (0)
  48. #define sysfs_print(file, var) \
  49. do { \
  50. if (attr == &sysfs_ ## file) \
  51. return snprint(buf, PAGE_SIZE, var); \
  52. } while (0)
  53. #define sysfs_hprint(file, val) \
  54. do { \
  55. if (attr == &sysfs_ ## file) { \
  56. ssize_t ret = bch_hprint(buf, val); \
  57. strcat(buf, "\n"); \
  58. return ret + 1; \
  59. } \
  60. } while (0)
  61. #define var_printf(_var, fmt) sysfs_printf(_var, fmt, var(_var))
  62. #define var_print(_var) sysfs_print(_var, var(_var))
  63. #define var_hprint(_var) sysfs_hprint(_var, var(_var))
  64. #define sysfs_strtoul(file, var) \
  65. do { \
  66. if (attr == &sysfs_ ## file) \
  67. return strtoul_safe(buf, var) ?: (ssize_t) size; \
  68. } while (0)
  69. #define sysfs_strtoul_bool(file, var) \
  70. do { \
  71. if (attr == &sysfs_ ## file) { \
  72. unsigned long v = strtoul_or_return(buf); \
  73. \
  74. var = v ? 1 : 0; \
  75. return size; \
  76. } \
  77. } while (0)
  78. #define sysfs_strtoul_clamp(file, var, min, max) \
  79. do { \
  80. if (attr == &sysfs_ ## file) { \
  81. unsigned long v = 0; \
  82. ssize_t ret; \
  83. ret = strtoul_safe_clamp(buf, v, min, max); \
  84. if (!ret) { \
  85. var = v; \
  86. return size; \
  87. } \
  88. return ret; \
  89. } \
  90. } while (0)
  91. #define strtoul_or_return(cp) \
  92. ({ \
  93. unsigned long _v; \
  94. int _r = kstrtoul(cp, 10, &_v); \
  95. if (_r) \
  96. return _r; \
  97. _v; \
  98. })
  99. #define strtoi_h_or_return(cp, v) \
  100. do { \
  101. int _r = strtoi_h(cp, &v); \
  102. if (_r) \
  103. return _r; \
  104. } while (0)
  105. #define sysfs_hatoi(file, var) \
  106. do { \
  107. if (attr == &sysfs_ ## file) \
  108. return strtoi_h(buf, &var) ?: (ssize_t) size; \
  109. } while (0)
  110. #endif /* _BCACHE_SYSFS_H_ */