group.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * fs/sysfs/group.c - Operations for adding/removing multiple files at once.
  3. *
  4. * Copyright (c) 2003 Patrick Mochel
  5. * Copyright (c) 2003 Open Source Development Lab
  6. *
  7. * This file is released undert the GPL v2.
  8. *
  9. */
  10. #include <linux/kobject.h>
  11. #include <linux/module.h>
  12. #include <linux/dcache.h>
  13. #include <linux/namei.h>
  14. #include <linux/err.h>
  15. #include "sysfs.h"
  16. static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
  17. const struct attribute_group *grp)
  18. {
  19. struct attribute *const* attr;
  20. int i;
  21. for (i = 0, attr = grp->attrs; *attr; i++, attr++)
  22. if (!grp->is_visible ||
  23. grp->is_visible(kobj, *attr, i))
  24. sysfs_hash_and_remove(dir_sd, (*attr)->name);
  25. }
  26. static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
  27. const struct attribute_group *grp)
  28. {
  29. struct attribute *const* attr;
  30. int error = 0, i;
  31. for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++)
  32. if (!grp->is_visible ||
  33. grp->is_visible(kobj, *attr, i))
  34. error |=
  35. sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR);
  36. if (error)
  37. remove_files(dir_sd, kobj, grp);
  38. return error;
  39. }
  40. int sysfs_create_group(struct kobject * kobj,
  41. const struct attribute_group * grp)
  42. {
  43. struct sysfs_dirent *sd;
  44. int error;
  45. BUG_ON(!kobj || !kobj->sd);
  46. if (grp->name) {
  47. error = sysfs_create_subdir(kobj, grp->name, &sd);
  48. if (error)
  49. return error;
  50. } else
  51. sd = kobj->sd;
  52. sysfs_get(sd);
  53. error = create_files(sd, kobj, grp);
  54. if (error) {
  55. if (grp->name)
  56. sysfs_remove_subdir(sd);
  57. }
  58. sysfs_put(sd);
  59. return error;
  60. }
  61. void sysfs_remove_group(struct kobject * kobj,
  62. const struct attribute_group * grp)
  63. {
  64. struct sysfs_dirent *dir_sd = kobj->sd;
  65. struct sysfs_dirent *sd;
  66. if (grp->name) {
  67. sd = sysfs_get_dirent(dir_sd, grp->name);
  68. BUG_ON(!sd);
  69. } else
  70. sd = sysfs_get(dir_sd);
  71. remove_files(sd, kobj, grp);
  72. if (grp->name)
  73. sysfs_remove_subdir(sd);
  74. sysfs_put(sd);
  75. }
  76. EXPORT_SYMBOL_GPL(sysfs_create_group);
  77. EXPORT_SYMBOL_GPL(sysfs_remove_group);