FuseGetAttr.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /** @file
  2. FUSE_GETATTR wrapper for the Virtio Filesystem device.
  3. Copyright (C) 2020, Red Hat, Inc.
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "VirtioFsDxe.h"
  7. /**
  8. Send a FUSE_GETATTR request to the Virtio Filesystem device, for fetching the
  9. attributes of an inode.
  10. The function may only be called after VirtioFsFuseInitSession() returns
  11. successfully and before VirtioFsUninit() is called.
  12. @param[in,out] VirtioFs The Virtio Filesystem device to send the
  13. FUSE_GETATTR request to. On output, the FUSE request
  14. counter "VirtioFs->RequestId" will have been
  15. incremented.
  16. @param[in] NodeId The inode number for which the attributes should be
  17. retrieved.
  18. @param[out] FuseAttr The VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE object
  19. describing the properties of the inode.
  20. @retval EFI_SUCCESS FuseAttr has been filled in.
  21. @return The "errno" value mapped to an EFI_STATUS code, if the
  22. Virtio Filesystem device explicitly reported an error.
  23. @return Error codes propagated from VirtioFsSgListsValidate(),
  24. VirtioFsFuseNewRequest(), VirtioFsSgListsSubmit(),
  25. VirtioFsFuseCheckResponse().
  26. **/
  27. EFI_STATUS
  28. VirtioFsFuseGetAttr (
  29. IN OUT VIRTIO_FS *VirtioFs,
  30. IN UINT64 NodeId,
  31. OUT VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr
  32. )
  33. {
  34. VIRTIO_FS_FUSE_REQUEST CommonReq;
  35. VIRTIO_FS_FUSE_GETATTR_REQUEST GetAttrReq;
  36. VIRTIO_FS_IO_VECTOR ReqIoVec[2];
  37. VIRTIO_FS_SCATTER_GATHER_LIST ReqSgList;
  38. VIRTIO_FS_FUSE_RESPONSE CommonResp;
  39. VIRTIO_FS_FUSE_GETATTR_RESPONSE GetAttrResp;
  40. VIRTIO_FS_IO_VECTOR RespIoVec[3];
  41. VIRTIO_FS_SCATTER_GATHER_LIST RespSgList;
  42. EFI_STATUS Status;
  43. //
  44. // Set up the scatter-gather lists.
  45. //
  46. ReqIoVec[0].Buffer = &CommonReq;
  47. ReqIoVec[0].Size = sizeof CommonReq;
  48. ReqIoVec[1].Buffer = &GetAttrReq;
  49. ReqIoVec[1].Size = sizeof GetAttrReq;
  50. ReqSgList.IoVec = ReqIoVec;
  51. ReqSgList.NumVec = ARRAY_SIZE (ReqIoVec);
  52. RespIoVec[0].Buffer = &CommonResp;
  53. RespIoVec[0].Size = sizeof CommonResp;
  54. RespIoVec[1].Buffer = &GetAttrResp;
  55. RespIoVec[1].Size = sizeof GetAttrResp;
  56. RespIoVec[2].Buffer = FuseAttr;
  57. RespIoVec[2].Size = sizeof *FuseAttr;
  58. RespSgList.IoVec = RespIoVec;
  59. RespSgList.NumVec = ARRAY_SIZE (RespIoVec);
  60. //
  61. // Validate the scatter-gather lists; calculate the total transfer sizes.
  62. //
  63. Status = VirtioFsSgListsValidate (VirtioFs, &ReqSgList, &RespSgList);
  64. if (EFI_ERROR (Status)) {
  65. return Status;
  66. }
  67. //
  68. // Populate the common request header.
  69. //
  70. Status = VirtioFsFuseNewRequest (
  71. VirtioFs,
  72. &CommonReq,
  73. ReqSgList.TotalSize,
  74. VirtioFsFuseOpGetAttr,
  75. NodeId
  76. );
  77. if (EFI_ERROR (Status)) {
  78. return Status;
  79. }
  80. //
  81. // Populate the FUSE_GETATTR-specific fields.
  82. //
  83. GetAttrReq.GetAttrFlags = 0;
  84. GetAttrReq.Dummy = 0;
  85. GetAttrReq.FileHandle = 0;
  86. //
  87. // Submit the request.
  88. //
  89. Status = VirtioFsSgListsSubmit (VirtioFs, &ReqSgList, &RespSgList);
  90. if (EFI_ERROR (Status)) {
  91. return Status;
  92. }
  93. //
  94. // Verify the response (all response buffers are fixed size).
  95. //
  96. Status = VirtioFsFuseCheckResponse (&RespSgList, CommonReq.Unique, NULL);
  97. if (Status == EFI_DEVICE_ERROR) {
  98. DEBUG ((
  99. DEBUG_ERROR,
  100. "%a: Label=\"%s\" NodeId=%Lu Errno=%d\n",
  101. __FUNCTION__,
  102. VirtioFs->Label,
  103. NodeId,
  104. CommonResp.Error
  105. ));
  106. Status = VirtioFsErrnoToEfiStatus (CommonResp.Error);
  107. }
  108. return Status;
  109. }