virtio-9p-xattr.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * Virtio 9p xattr callback
  3. *
  4. * Copyright IBM, Corp. 2010
  5. *
  6. * Authors:
  7. * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
  8. *
  9. * This work is licensed under the terms of the GNU GPL, version 2. See
  10. * the COPYING file in the top-level directory.
  11. *
  12. */
  13. #include "hw/virtio.h"
  14. #include "virtio-9p.h"
  15. #include "fsdev/file-op-9p.h"
  16. #include "virtio-9p-xattr.h"
  17. static XattrOperations *get_xattr_operations(XattrOperations **h,
  18. const char *name)
  19. {
  20. XattrOperations *xops;
  21. for (xops = *(h)++; xops != NULL; xops = *(h)++) {
  22. if (!strncmp(name, xops->name, strlen(xops->name))) {
  23. return xops;
  24. }
  25. }
  26. return NULL;
  27. }
  28. ssize_t v9fs_get_xattr(FsContext *ctx, const char *path,
  29. const char *name, void *value, size_t size)
  30. {
  31. XattrOperations *xops = get_xattr_operations(ctx->xops, name);
  32. if (xops) {
  33. return xops->getxattr(ctx, path, name, value, size);
  34. }
  35. errno = -EOPNOTSUPP;
  36. return -1;
  37. }
  38. ssize_t pt_listxattr(FsContext *ctx, const char *path,
  39. char *name, void *value, size_t size)
  40. {
  41. int name_size = strlen(name) + 1;
  42. if (!value) {
  43. return name_size;
  44. }
  45. if (size < name_size) {
  46. errno = ERANGE;
  47. return -1;
  48. }
  49. strncpy(value, name, name_size);
  50. return name_size;
  51. }
  52. /*
  53. * Get the list and pass to each layer to find out whether
  54. * to send the data or not
  55. */
  56. ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,
  57. void *value, size_t vsize)
  58. {
  59. ssize_t size = 0;
  60. char buffer[PATH_MAX];
  61. void *ovalue = value;
  62. XattrOperations *xops;
  63. char *orig_value, *orig_value_start;
  64. ssize_t xattr_len, parsed_len = 0, attr_len;
  65. /* Get the actual len */
  66. xattr_len = llistxattr(rpath(ctx, path, buffer), value, 0);
  67. if (xattr_len <= 0) {
  68. return xattr_len;
  69. }
  70. /* Now fetch the xattr and find the actual size */
  71. orig_value = g_malloc(xattr_len);
  72. xattr_len = llistxattr(rpath(ctx, path, buffer), orig_value, xattr_len);
  73. /* store the orig pointer */
  74. orig_value_start = orig_value;
  75. while (xattr_len > parsed_len) {
  76. xops = get_xattr_operations(ctx->xops, orig_value);
  77. if (!xops) {
  78. goto next_entry;
  79. }
  80. if (!value) {
  81. size += xops->listxattr(ctx, path, orig_value, value, vsize);
  82. } else {
  83. size = xops->listxattr(ctx, path, orig_value, value, vsize);
  84. if (size < 0) {
  85. goto err_out;
  86. }
  87. value += size;
  88. vsize -= size;
  89. }
  90. next_entry:
  91. /* Got the next entry */
  92. attr_len = strlen(orig_value) + 1;
  93. parsed_len += attr_len;
  94. orig_value += attr_len;
  95. }
  96. if (value) {
  97. size = value - ovalue;
  98. }
  99. err_out:
  100. g_free(orig_value_start);
  101. return size;
  102. }
  103. int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name,
  104. void *value, size_t size, int flags)
  105. {
  106. XattrOperations *xops = get_xattr_operations(ctx->xops, name);
  107. if (xops) {
  108. return xops->setxattr(ctx, path, name, value, size, flags);
  109. }
  110. errno = -EOPNOTSUPP;
  111. return -1;
  112. }
  113. int v9fs_remove_xattr(FsContext *ctx,
  114. const char *path, const char *name)
  115. {
  116. XattrOperations *xops = get_xattr_operations(ctx->xops, name);
  117. if (xops) {
  118. return xops->removexattr(ctx, path, name);
  119. }
  120. errno = -EOPNOTSUPP;
  121. return -1;
  122. }
  123. XattrOperations *mapped_xattr_ops[] = {
  124. &mapped_user_xattr,
  125. &mapped_pacl_xattr,
  126. &mapped_dacl_xattr,
  127. NULL,
  128. };
  129. XattrOperations *passthrough_xattr_ops[] = {
  130. &passthrough_user_xattr,
  131. &passthrough_acl_xattr,
  132. NULL,
  133. };
  134. /* for .user none model should be same as passthrough */
  135. XattrOperations *none_xattr_ops[] = {
  136. &passthrough_user_xattr,
  137. &none_acl_xattr,
  138. NULL,
  139. };