attr.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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. int hfs_setxattr(struct dentry *dentry, const char *name,
  13. const void *value, size_t size, int flags)
  14. {
  15. struct inode *inode = d_inode(dentry);
  16. struct hfs_find_data fd;
  17. hfs_cat_rec rec;
  18. struct hfs_cat_file *file;
  19. int res;
  20. if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode))
  21. return -EOPNOTSUPP;
  22. res = hfs_find_init(HFS_SB(inode->i_sb)->cat_tree, &fd);
  23. if (res)
  24. return res;
  25. fd.search_key->cat = HFS_I(inode)->cat_key;
  26. res = hfs_brec_find(&fd);
  27. if (res)
  28. goto out;
  29. hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
  30. sizeof(struct hfs_cat_file));
  31. file = &rec.file;
  32. if (!strcmp(name, "hfs.type")) {
  33. if (size == 4)
  34. memcpy(&file->UsrWds.fdType, value, 4);
  35. else
  36. res = -ERANGE;
  37. } else if (!strcmp(name, "hfs.creator")) {
  38. if (size == 4)
  39. memcpy(&file->UsrWds.fdCreator, value, 4);
  40. else
  41. res = -ERANGE;
  42. } else
  43. res = -EOPNOTSUPP;
  44. if (!res)
  45. hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
  46. sizeof(struct hfs_cat_file));
  47. out:
  48. hfs_find_exit(&fd);
  49. return res;
  50. }
  51. ssize_t hfs_getxattr(struct dentry *dentry, const char *name,
  52. void *value, size_t size)
  53. {
  54. struct inode *inode = d_inode(dentry);
  55. struct hfs_find_data fd;
  56. hfs_cat_rec rec;
  57. struct hfs_cat_file *file;
  58. ssize_t res = 0;
  59. if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode))
  60. return -EOPNOTSUPP;
  61. if (size) {
  62. res = hfs_find_init(HFS_SB(inode->i_sb)->cat_tree, &fd);
  63. if (res)
  64. return res;
  65. fd.search_key->cat = HFS_I(inode)->cat_key;
  66. res = hfs_brec_find(&fd);
  67. if (res)
  68. goto out;
  69. hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
  70. sizeof(struct hfs_cat_file));
  71. }
  72. file = &rec.file;
  73. if (!strcmp(name, "hfs.type")) {
  74. if (size >= 4) {
  75. memcpy(value, &file->UsrWds.fdType, 4);
  76. res = 4;
  77. } else
  78. res = size ? -ERANGE : 4;
  79. } else if (!strcmp(name, "hfs.creator")) {
  80. if (size >= 4) {
  81. memcpy(value, &file->UsrWds.fdCreator, 4);
  82. res = 4;
  83. } else
  84. res = size ? -ERANGE : 4;
  85. } else
  86. res = -ENODATA;
  87. out:
  88. if (size)
  89. hfs_find_exit(&fd);
  90. return res;
  91. }
  92. #define HFS_ATTRLIST_SIZE (sizeof("hfs.creator")+sizeof("hfs.type"))
  93. ssize_t hfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
  94. {
  95. struct inode *inode = d_inode(dentry);
  96. if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode))
  97. return -EOPNOTSUPP;
  98. if (!buffer || !size)
  99. return HFS_ATTRLIST_SIZE;
  100. if (size < HFS_ATTRLIST_SIZE)
  101. return -ERANGE;
  102. strcpy(buffer, "hfs.type");
  103. strcpy(buffer + sizeof("hfs.type"), "hfs.creator");
  104. return HFS_ATTRLIST_SIZE;
  105. }