xattr.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /* Extended attribute handling for AFS. We use xattrs to get and set metadata
  2. * instead of providing pioctl().
  3. *
  4. * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
  5. * Written by David Howells (dhowells@redhat.com)
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public Licence
  9. * as published by the Free Software Foundation; either version
  10. * 2 of the Licence, or (at your option) any later version.
  11. */
  12. #include <linux/slab.h>
  13. #include <linux/fs.h>
  14. #include <linux/xattr.h>
  15. #include "internal.h"
  16. static const char afs_xattr_list[] =
  17. "afs.cell\0"
  18. "afs.fid\0"
  19. "afs.volume";
  20. /*
  21. * Retrieve a list of the supported xattrs.
  22. */
  23. ssize_t afs_listxattr(struct dentry *dentry, char *buffer, size_t size)
  24. {
  25. if (size == 0)
  26. return sizeof(afs_xattr_list);
  27. if (size < sizeof(afs_xattr_list))
  28. return -ERANGE;
  29. memcpy(buffer, afs_xattr_list, sizeof(afs_xattr_list));
  30. return sizeof(afs_xattr_list);
  31. }
  32. /*
  33. * Get the name of the cell on which a file resides.
  34. */
  35. static int afs_xattr_get_cell(const struct xattr_handler *handler,
  36. struct dentry *dentry,
  37. struct inode *inode, const char *name,
  38. void *buffer, size_t size)
  39. {
  40. struct afs_vnode *vnode = AFS_FS_I(inode);
  41. struct afs_cell *cell = vnode->volume->cell;
  42. size_t namelen;
  43. namelen = cell->name_len;
  44. if (size == 0)
  45. return namelen;
  46. if (namelen > size)
  47. return -ERANGE;
  48. memcpy(buffer, cell->name, namelen);
  49. return namelen;
  50. }
  51. static const struct xattr_handler afs_xattr_afs_cell_handler = {
  52. .name = "afs.cell",
  53. .get = afs_xattr_get_cell,
  54. };
  55. /*
  56. * Get the volume ID, vnode ID and vnode uniquifier of a file as a sequence of
  57. * hex numbers separated by colons.
  58. */
  59. static int afs_xattr_get_fid(const struct xattr_handler *handler,
  60. struct dentry *dentry,
  61. struct inode *inode, const char *name,
  62. void *buffer, size_t size)
  63. {
  64. struct afs_vnode *vnode = AFS_FS_I(inode);
  65. char text[8 + 1 + 8 + 1 + 8 + 1];
  66. size_t len;
  67. len = sprintf(text, "%x:%x:%x",
  68. vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique);
  69. if (size == 0)
  70. return len;
  71. if (len > size)
  72. return -ERANGE;
  73. memcpy(buffer, text, len);
  74. return len;
  75. }
  76. static const struct xattr_handler afs_xattr_afs_fid_handler = {
  77. .name = "afs.fid",
  78. .get = afs_xattr_get_fid,
  79. };
  80. /*
  81. * Get the name of the volume on which a file resides.
  82. */
  83. static int afs_xattr_get_volume(const struct xattr_handler *handler,
  84. struct dentry *dentry,
  85. struct inode *inode, const char *name,
  86. void *buffer, size_t size)
  87. {
  88. struct afs_vnode *vnode = AFS_FS_I(inode);
  89. const char *volname = vnode->volume->name;
  90. size_t namelen;
  91. namelen = strlen(volname);
  92. if (size == 0)
  93. return namelen;
  94. if (namelen > size)
  95. return -ERANGE;
  96. memcpy(buffer, volname, namelen);
  97. return namelen;
  98. }
  99. static const struct xattr_handler afs_xattr_afs_volume_handler = {
  100. .name = "afs.volume",
  101. .get = afs_xattr_get_volume,
  102. };
  103. const struct xattr_handler *afs_xattr_handlers[] = {
  104. &afs_xattr_afs_cell_handler,
  105. &afs_xattr_afs_fid_handler,
  106. &afs_xattr_afs_volume_handler,
  107. NULL
  108. };