attr.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * linux/fs/hfs/attr.c
  3. *
  4. * (C) 2003 Ardis Technologies <roman@ardistech.com>
  5. *
  6. * Export hfs data via xattr
  7. */
  8. #include <linux/fs.h>
  9. #include <linux/xattr.h>
  10. #include "hfs_fs.h"
  11. #include "btree.h"
  12. enum hfs_xattr_type {
  13. HFS_TYPE,
  14. HFS_CREATOR,
  15. };
  16. static int __hfs_setxattr(struct inode *inode, enum hfs_xattr_type type,
  17. const void *value, size_t size, int flags)
  18. {
  19. struct hfs_find_data fd;
  20. hfs_cat_rec rec;
  21. struct hfs_cat_file *file;
  22. int res;
  23. if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode))
  24. return -EOPNOTSUPP;
  25. res = hfs_find_init(HFS_SB(inode->i_sb)->cat_tree, &fd);
  26. if (res)
  27. return res;
  28. fd.search_key->cat = HFS_I(inode)->cat_key;
  29. res = hfs_brec_find(&fd);
  30. if (res)
  31. goto out;
  32. hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
  33. sizeof(struct hfs_cat_file));
  34. file = &rec.file;
  35. switch (type) {
  36. case HFS_TYPE:
  37. if (size == 4)
  38. memcpy(&file->UsrWds.fdType, value, 4);
  39. else
  40. res = -ERANGE;
  41. break;
  42. case HFS_CREATOR:
  43. if (size == 4)
  44. memcpy(&file->UsrWds.fdCreator, value, 4);
  45. else
  46. res = -ERANGE;
  47. break;
  48. }
  49. if (!res)
  50. hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
  51. sizeof(struct hfs_cat_file));
  52. out:
  53. hfs_find_exit(&fd);
  54. return res;
  55. }
  56. static ssize_t __hfs_getxattr(struct inode *inode, enum hfs_xattr_type type,
  57. void *value, size_t size)
  58. {
  59. struct hfs_find_data fd;
  60. hfs_cat_rec rec;
  61. struct hfs_cat_file *file;
  62. ssize_t res = 0;
  63. if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode))
  64. return -EOPNOTSUPP;
  65. if (size) {
  66. res = hfs_find_init(HFS_SB(inode->i_sb)->cat_tree, &fd);
  67. if (res)
  68. return res;
  69. fd.search_key->cat = HFS_I(inode)->cat_key;
  70. res = hfs_brec_find(&fd);
  71. if (res)
  72. goto out;
  73. hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
  74. sizeof(struct hfs_cat_file));
  75. }
  76. file = &rec.file;
  77. switch (type) {
  78. case HFS_TYPE:
  79. if (size >= 4) {
  80. memcpy(value, &file->UsrWds.fdType, 4);
  81. res = 4;
  82. } else
  83. res = size ? -ERANGE : 4;
  84. break;
  85. case HFS_CREATOR:
  86. if (size >= 4) {
  87. memcpy(value, &file->UsrWds.fdCreator, 4);
  88. res = 4;
  89. } else
  90. res = size ? -ERANGE : 4;
  91. break;
  92. }
  93. out:
  94. if (size)
  95. hfs_find_exit(&fd);
  96. return res;
  97. }
  98. static int hfs_xattr_get(const struct xattr_handler *handler,
  99. struct dentry *unused, struct inode *inode,
  100. const char *name, void *value, size_t size)
  101. {
  102. return __hfs_getxattr(inode, handler->flags, value, size);
  103. }
  104. static int hfs_xattr_set(const struct xattr_handler *handler,
  105. struct dentry *unused, struct inode *inode,
  106. const char *name, const void *value, size_t size,
  107. int flags)
  108. {
  109. if (!value)
  110. return -EOPNOTSUPP;
  111. return __hfs_setxattr(inode, handler->flags, value, size, flags);
  112. }
  113. static const struct xattr_handler hfs_creator_handler = {
  114. .name = "hfs.creator",
  115. .flags = HFS_CREATOR,
  116. .get = hfs_xattr_get,
  117. .set = hfs_xattr_set,
  118. };
  119. static const struct xattr_handler hfs_type_handler = {
  120. .name = "hfs.type",
  121. .flags = HFS_TYPE,
  122. .get = hfs_xattr_get,
  123. .set = hfs_xattr_set,
  124. };
  125. const struct xattr_handler *hfs_xattr_handlers[] = {
  126. &hfs_creator_handler,
  127. &hfs_type_handler,
  128. NULL
  129. };