FuseOpen.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /** @file
  2. FUSE_OPEN 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_OPEN request to the Virtio Filesystem device, for opening a
  9. regular file.
  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 FUSE_OPEN
  13. request to. On output, the FUSE request counter
  14. "VirtioFs->RequestId" will have been incremented.
  15. @param[in] NodeId The inode number of the regular file to open.
  16. @param[in] ReadWrite If TRUE, open the regular file in read-write mode.
  17. If FALSE, open the regular file in read-only mode.
  18. @param[out] FuseHandle The open handle to the regular file, returned by the
  19. Virtio Filesystem device.
  20. @retval EFI_SUCCESS The regular file has been opened.
  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. VirtioFsFuseOpen (
  29. IN OUT VIRTIO_FS *VirtioFs,
  30. IN UINT64 NodeId,
  31. IN BOOLEAN ReadWrite,
  32. OUT UINT64 *FuseHandle
  33. )
  34. {
  35. VIRTIO_FS_FUSE_REQUEST CommonReq;
  36. VIRTIO_FS_FUSE_OPEN_REQUEST OpenReq;
  37. VIRTIO_FS_IO_VECTOR ReqIoVec[2];
  38. VIRTIO_FS_SCATTER_GATHER_LIST ReqSgList;
  39. VIRTIO_FS_FUSE_RESPONSE CommonResp;
  40. VIRTIO_FS_FUSE_OPEN_RESPONSE OpenResp;
  41. VIRTIO_FS_IO_VECTOR RespIoVec[2];
  42. VIRTIO_FS_SCATTER_GATHER_LIST RespSgList;
  43. EFI_STATUS Status;
  44. //
  45. // Set up the scatter-gather lists.
  46. //
  47. ReqIoVec[0].Buffer = &CommonReq;
  48. ReqIoVec[0].Size = sizeof CommonReq;
  49. ReqIoVec[1].Buffer = &OpenReq;
  50. ReqIoVec[1].Size = sizeof OpenReq;
  51. ReqSgList.IoVec = ReqIoVec;
  52. ReqSgList.NumVec = ARRAY_SIZE (ReqIoVec);
  53. RespIoVec[0].Buffer = &CommonResp;
  54. RespIoVec[0].Size = sizeof CommonResp;
  55. RespIoVec[1].Buffer = &OpenResp;
  56. RespIoVec[1].Size = sizeof OpenResp;
  57. RespSgList.IoVec = RespIoVec;
  58. RespSgList.NumVec = ARRAY_SIZE (RespIoVec);
  59. //
  60. // Validate the scatter-gather lists; calculate the total transfer sizes.
  61. //
  62. Status = VirtioFsSgListsValidate (VirtioFs, &ReqSgList, &RespSgList);
  63. if (EFI_ERROR (Status)) {
  64. return Status;
  65. }
  66. //
  67. // Populate the common request header.
  68. //
  69. Status = VirtioFsFuseNewRequest (
  70. VirtioFs,
  71. &CommonReq,
  72. ReqSgList.TotalSize,
  73. VirtioFsFuseOpOpen,
  74. NodeId
  75. );
  76. if (EFI_ERROR (Status)) {
  77. return Status;
  78. }
  79. //
  80. // Populate the FUSE_OPEN-specific fields.
  81. //
  82. OpenReq.Flags = (ReadWrite ?
  83. VIRTIO_FS_FUSE_OPEN_REQ_F_RDWR :
  84. VIRTIO_FS_FUSE_OPEN_REQ_F_RDONLY);
  85. OpenReq.Unused = 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 (EFI_ERROR (Status)) {
  98. if (Status == EFI_DEVICE_ERROR) {
  99. DEBUG ((
  100. DEBUG_ERROR,
  101. "%a: Label=\"%s\" NodeId=%Lu ReadWrite=%d "
  102. "Errno=%d\n",
  103. __FUNCTION__,
  104. VirtioFs->Label,
  105. NodeId,
  106. ReadWrite,
  107. CommonResp.Error
  108. ));
  109. Status = VirtioFsErrnoToEfiStatus (CommonResp.Error);
  110. }
  111. return Status;
  112. }
  113. //
  114. // Output the open handle.
  115. //
  116. *FuseHandle = OpenResp.FileHandle;
  117. return EFI_SUCCESS;
  118. }