weedfs_file_io.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package mount
  2. import (
  3. "github.com/hanwen/go-fuse/v2/fuse"
  4. "github.com/seaweedfs/seaweedfs/weed/glog"
  5. )
  6. /**
  7. * Open a file
  8. *
  9. * Open flags are available in fi->flags. The following rules
  10. * apply.
  11. *
  12. * - Creation (O_CREAT, O_EXCL, O_NOCTTY) flags will be
  13. * filtered out / handled by the kernel.
  14. *
  15. * - Access modes (O_RDONLY, O_WRONLY, O_RDWR) should be used
  16. * by the filesystem to check if the operation is
  17. * permitted. If the ``-o default_permissions`` mount
  18. * option is given, this check is already done by the
  19. * kernel before calling open() and may thus be omitted by
  20. * the filesystem.
  21. *
  22. * - When writeback caching is enabled, the kernel may send
  23. * read requests even for files opened with O_WRONLY. The
  24. * filesystem should be prepared to handle this.
  25. *
  26. * - When writeback caching is disabled, the filesystem is
  27. * expected to properly handle the O_APPEND flag and ensure
  28. * that each write is appending to the end of the file.
  29. *
  30. * - When writeback caching is enabled, the kernel will
  31. * handle O_APPEND. However, unless all changes to the file
  32. * come through the kernel this will not work reliably. The
  33. * filesystem should thus either ignore the O_APPEND flag
  34. * (and let the kernel handle it), or return an error
  35. * (indicating that reliably O_APPEND is not available).
  36. *
  37. * Filesystem may store an arbitrary file handle (pointer,
  38. * index, etc) in fi->fh, and use this in other all other file
  39. * operations (read, write, flush, release, fsync).
  40. *
  41. * Filesystem may also implement stateless file I/O and not store
  42. * anything in fi->fh.
  43. *
  44. * There are also some flags (direct_io, keep_cache) which the
  45. * filesystem may set in fi, to change the way the file is opened.
  46. * See fuse_file_info structure in <fuse_common.h> for more details.
  47. *
  48. * If this request is answered with an error code of ENOSYS
  49. * and FUSE_CAP_NO_OPEN_SUPPORT is set in
  50. * `fuse_conn_info.capable`, this is treated as success and
  51. * future calls to open and release will also succeed without being
  52. * sent to the filesystem process.
  53. *
  54. * Valid replies:
  55. * fuse_reply_open
  56. * fuse_reply_err
  57. *
  58. * @param req request handle
  59. * @param ino the inode number
  60. * @param fi file information
  61. */
  62. func (wfs *WFS) Open(cancel <-chan struct{}, in *fuse.OpenIn, out *fuse.OpenOut) (status fuse.Status) {
  63. var fileHandle *FileHandle
  64. fileHandle, status = wfs.AcquireHandle(in.NodeId, in.Flags, in.Uid, in.Gid)
  65. if status == fuse.OK {
  66. out.Fh = uint64(fileHandle.fh)
  67. out.OpenFlags = in.Flags
  68. if wfs.option.IsMacOs {
  69. // remove the direct_io flag, as it is not well-supported on macOS
  70. // https://code.google.com/archive/p/macfuse/wikis/OPTIONS.wiki recommended to avoid the direct_io flag
  71. if in.Flags&fuse.FOPEN_DIRECT_IO != 0 {
  72. glog.V(4).Infof("macfuse direct_io mode %v => false\n", in.Flags&fuse.FOPEN_DIRECT_IO != 0)
  73. out.OpenFlags &^= fuse.FOPEN_DIRECT_IO
  74. }
  75. }
  76. // TODO https://github.com/libfuse/libfuse/blob/master/include/fuse_common.h#L64
  77. }
  78. return status
  79. }
  80. /**
  81. * Release an open file
  82. *
  83. * Release is called when there are no more references to an open
  84. * file: all file descriptors are closed and all memory mappings
  85. * are unmapped.
  86. *
  87. * For every open call there will be exactly one release call (unless
  88. * the filesystem is force-unmounted).
  89. *
  90. * The filesystem may reply with an error, but error values are
  91. * not returned to close() or munmap() which triggered the
  92. * release.
  93. *
  94. * fi->fh will contain the value set by the open method, or will
  95. * be undefined if the open method didn't set any value.
  96. * fi->flags will contain the same flags as for open.
  97. *
  98. * Valid replies:
  99. * fuse_reply_err
  100. *
  101. * @param req request handle
  102. * @param ino the inode number
  103. * @param fi file information
  104. */
  105. func (wfs *WFS) Release(cancel <-chan struct{}, in *fuse.ReleaseIn) {
  106. wfs.ReleaseHandle(FileHandleId(in.Fh))
  107. }