sysfs.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. * Copyright (C) 2007 Oracle. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public
  6. * License v2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public
  14. * License along with this program; if not, write to the
  15. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  16. * Boston, MA 021110-1307, USA.
  17. */
  18. #include <linux/sched.h>
  19. #include <linux/slab.h>
  20. #include <linux/spinlock.h>
  21. #include <linux/completion.h>
  22. #include <linux/buffer_head.h>
  23. #include <linux/module.h>
  24. #include <linux/kobject.h>
  25. #include "ctree.h"
  26. #include "disk-io.h"
  27. #include "transaction.h"
  28. static ssize_t root_blocks_used_show(struct btrfs_root *root, char *buf)
  29. {
  30. return snprintf(buf, PAGE_SIZE, "%llu\n",
  31. (unsigned long long)btrfs_root_used(&root->root_item));
  32. }
  33. static ssize_t root_block_limit_show(struct btrfs_root *root, char *buf)
  34. {
  35. return snprintf(buf, PAGE_SIZE, "%llu\n",
  36. (unsigned long long)btrfs_root_limit(&root->root_item));
  37. }
  38. static ssize_t super_blocks_used_show(struct btrfs_fs_info *fs, char *buf)
  39. {
  40. return snprintf(buf, PAGE_SIZE, "%llu\n",
  41. (unsigned long long)btrfs_super_bytes_used(&fs->super_copy));
  42. }
  43. static ssize_t super_total_blocks_show(struct btrfs_fs_info *fs, char *buf)
  44. {
  45. return snprintf(buf, PAGE_SIZE, "%llu\n",
  46. (unsigned long long)btrfs_super_total_bytes(&fs->super_copy));
  47. }
  48. static ssize_t super_blocksize_show(struct btrfs_fs_info *fs, char *buf)
  49. {
  50. return snprintf(buf, PAGE_SIZE, "%llu\n",
  51. (unsigned long long)btrfs_super_sectorsize(&fs->super_copy));
  52. }
  53. /* this is for root attrs (subvols/snapshots) */
  54. struct btrfs_root_attr {
  55. struct attribute attr;
  56. ssize_t (*show)(struct btrfs_root *, char *);
  57. ssize_t (*store)(struct btrfs_root *, const char *, size_t);
  58. };
  59. #define ROOT_ATTR(name, mode, show, store) \
  60. static struct btrfs_root_attr btrfs_root_attr_##name = __ATTR(name, mode, show, store)
  61. ROOT_ATTR(blocks_used, 0444, root_blocks_used_show, NULL);
  62. ROOT_ATTR(block_limit, 0644, root_block_limit_show, NULL);
  63. static struct attribute *btrfs_root_attrs[] = {
  64. &btrfs_root_attr_blocks_used.attr,
  65. &btrfs_root_attr_block_limit.attr,
  66. NULL,
  67. };
  68. /* this is for super attrs (actual full fs) */
  69. struct btrfs_super_attr {
  70. struct attribute attr;
  71. ssize_t (*show)(struct btrfs_fs_info *, char *);
  72. ssize_t (*store)(struct btrfs_fs_info *, const char *, size_t);
  73. };
  74. #define SUPER_ATTR(name, mode, show, store) \
  75. static struct btrfs_super_attr btrfs_super_attr_##name = __ATTR(name, mode, show, store)
  76. SUPER_ATTR(blocks_used, 0444, super_blocks_used_show, NULL);
  77. SUPER_ATTR(total_blocks, 0444, super_total_blocks_show, NULL);
  78. SUPER_ATTR(blocksize, 0444, super_blocksize_show, NULL);
  79. static struct attribute *btrfs_super_attrs[] = {
  80. &btrfs_super_attr_blocks_used.attr,
  81. &btrfs_super_attr_total_blocks.attr,
  82. &btrfs_super_attr_blocksize.attr,
  83. NULL,
  84. };
  85. static ssize_t btrfs_super_attr_show(struct kobject *kobj,
  86. struct attribute *attr, char *buf)
  87. {
  88. struct btrfs_fs_info *fs = container_of(kobj, struct btrfs_fs_info,
  89. super_kobj);
  90. struct btrfs_super_attr *a = container_of(attr,
  91. struct btrfs_super_attr,
  92. attr);
  93. return a->show ? a->show(fs, buf) : 0;
  94. }
  95. static ssize_t btrfs_super_attr_store(struct kobject *kobj,
  96. struct attribute *attr,
  97. const char *buf, size_t len)
  98. {
  99. struct btrfs_fs_info *fs = container_of(kobj, struct btrfs_fs_info,
  100. super_kobj);
  101. struct btrfs_super_attr *a = container_of(attr,
  102. struct btrfs_super_attr,
  103. attr);
  104. return a->store ? a->store(fs, buf, len) : 0;
  105. }
  106. static ssize_t btrfs_root_attr_show(struct kobject *kobj,
  107. struct attribute *attr, char *buf)
  108. {
  109. struct btrfs_root *root = container_of(kobj, struct btrfs_root,
  110. root_kobj);
  111. struct btrfs_root_attr *a = container_of(attr,
  112. struct btrfs_root_attr,
  113. attr);
  114. return a->show ? a->show(root, buf) : 0;
  115. }
  116. static ssize_t btrfs_root_attr_store(struct kobject *kobj,
  117. struct attribute *attr,
  118. const char *buf, size_t len)
  119. {
  120. struct btrfs_root *root = container_of(kobj, struct btrfs_root,
  121. root_kobj);
  122. struct btrfs_root_attr *a = container_of(attr,
  123. struct btrfs_root_attr,
  124. attr);
  125. return a->store ? a->store(root, buf, len) : 0;
  126. }
  127. static void btrfs_super_release(struct kobject *kobj)
  128. {
  129. struct btrfs_fs_info *fs = container_of(kobj, struct btrfs_fs_info,
  130. super_kobj);
  131. complete(&fs->kobj_unregister);
  132. }
  133. static void btrfs_root_release(struct kobject *kobj)
  134. {
  135. struct btrfs_root *root = container_of(kobj, struct btrfs_root,
  136. root_kobj);
  137. complete(&root->kobj_unregister);
  138. }
  139. static struct sysfs_ops btrfs_super_attr_ops = {
  140. .show = btrfs_super_attr_show,
  141. .store = btrfs_super_attr_store,
  142. };
  143. static struct sysfs_ops btrfs_root_attr_ops = {
  144. .show = btrfs_root_attr_show,
  145. .store = btrfs_root_attr_store,
  146. };
  147. static struct kobj_type btrfs_root_ktype = {
  148. .default_attrs = btrfs_root_attrs,
  149. .sysfs_ops = &btrfs_root_attr_ops,
  150. .release = btrfs_root_release,
  151. };
  152. static struct kobj_type btrfs_super_ktype = {
  153. .default_attrs = btrfs_super_attrs,
  154. .sysfs_ops = &btrfs_super_attr_ops,
  155. .release = btrfs_super_release,
  156. };
  157. static struct kset btrfs_kset = {
  158. .kobj = {.name = "btrfs"},
  159. };
  160. int btrfs_sysfs_add_super(struct btrfs_fs_info *fs)
  161. {
  162. int error;
  163. fs->super_kobj.kset = &btrfs_kset;
  164. fs->super_kobj.ktype = &btrfs_super_ktype;
  165. error = kobject_set_name(&fs->super_kobj, "%s",
  166. fs->sb->s_id);
  167. if (error)
  168. goto fail;
  169. error = kobject_register(&fs->super_kobj);
  170. if (error)
  171. goto fail;
  172. return 0;
  173. fail:
  174. printk(KERN_ERR "btrfs: sysfs creation for super failed\n");
  175. return error;
  176. }
  177. int btrfs_sysfs_add_root(struct btrfs_root *root)
  178. {
  179. int error;
  180. root->root_kobj.ktype = &btrfs_root_ktype;
  181. root->root_kobj.parent = &root->fs_info->super_kobj;
  182. error = kobject_set_name(&root->root_kobj, "%s", root->name);
  183. if (error) {
  184. goto fail;
  185. }
  186. error = kobject_register(&root->root_kobj);
  187. if (error)
  188. goto fail;
  189. return 0;
  190. fail:
  191. printk(KERN_ERR "btrfs: sysfs creation for root failed\n");
  192. return error;
  193. }
  194. void btrfs_sysfs_del_root(struct btrfs_root *root)
  195. {
  196. kobject_unregister(&root->root_kobj);
  197. wait_for_completion(&root->kobj_unregister);
  198. }
  199. void btrfs_sysfs_del_super(struct btrfs_fs_info *fs)
  200. {
  201. kobject_unregister(&fs->super_kobj);
  202. wait_for_completion(&fs->kobj_unregister);
  203. }
  204. int btrfs_init_sysfs()
  205. {
  206. kobj_set_kset_s(&btrfs_kset, fs_subsys);
  207. return kset_register(&btrfs_kset);
  208. }
  209. void btrfs_exit_sysfs()
  210. {
  211. kset_unregister(&btrfs_kset);
  212. }