sysfs.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  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. int btrfs_sysfs_add_super(struct btrfs_fs_info *fs)
  159. {
  160. int error;
  161. char *name;
  162. char c;
  163. int len = strlen(fs->sb->s_id) + 1;
  164. int i;
  165. name = kmalloc(len, GFP_NOFS);
  166. if (!name) {
  167. error = -ENOMEM;
  168. goto fail;
  169. }
  170. for (i = 0; i < len; i++) {
  171. c = fs->sb->s_id[i];
  172. if (c == '/' || c == '\\')
  173. c = '!';
  174. name[i] = c;
  175. }
  176. name[len] = '\0';
  177. fs->super_kobj.kset = &btrfs_kset;
  178. fs->super_kobj.ktype = &btrfs_super_ktype;
  179. error = kobject_set_name(&fs->super_kobj, "%s", name);
  180. if (error)
  181. goto fail;
  182. error = kobject_register(&fs->super_kobj);
  183. if (error)
  184. goto fail;
  185. kfree(name);
  186. return 0;
  187. fail:
  188. kfree(name);
  189. printk(KERN_ERR "btrfs: sysfs creation for super failed\n");
  190. return error;
  191. }
  192. int btrfs_sysfs_add_root(struct btrfs_root *root)
  193. {
  194. int error;
  195. root->root_kobj.ktype = &btrfs_root_ktype;
  196. root->root_kobj.parent = &root->fs_info->super_kobj;
  197. error = kobject_set_name(&root->root_kobj, "%s", root->name);
  198. if (error) {
  199. goto fail;
  200. }
  201. error = kobject_register(&root->root_kobj);
  202. if (error)
  203. goto fail;
  204. return 0;
  205. fail:
  206. printk(KERN_ERR "btrfs: sysfs creation for root failed\n");
  207. return error;
  208. }
  209. void btrfs_sysfs_del_root(struct btrfs_root *root)
  210. {
  211. kobject_unregister(&root->root_kobj);
  212. wait_for_completion(&root->kobj_unregister);
  213. }
  214. void btrfs_sysfs_del_super(struct btrfs_fs_info *fs)
  215. {
  216. kobject_unregister(&fs->super_kobj);
  217. wait_for_completion(&fs->kobj_unregister);
  218. }
  219. int btrfs_init_sysfs()
  220. {
  221. kobj_set_kset_s(&btrfs_kset, fs_subsys);
  222. kobject_set_name(&btrfs_kset.kobj, "btrfs");
  223. return kset_register(&btrfs_kset);
  224. }
  225. void btrfs_exit_sysfs()
  226. {
  227. kset_unregister(&btrfs_kset);
  228. }