You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

70 lines
1.8 KiB

3 years ago
3 years ago
3 years ago
  1. package mount
  2. import (
  3. "io"
  4. "github.com/hanwen/go-fuse/v2/fuse"
  5. "github.com/seaweedfs/seaweedfs/weed/glog"
  6. )
  7. /**
  8. * Read data
  9. *
  10. * Read should send exactly the number of bytes requested except
  11. * on EOF or error, otherwise the rest of the data will be
  12. * substituted with zeroes. An exception to this is when the file
  13. * has been opened in 'direct_io' mode, in which case the return
  14. * value of the read system call will reflect the return value of
  15. * this operation.
  16. *
  17. * fi->fh will contain the value set by the open method, or will
  18. * be undefined if the open method didn't set any value.
  19. *
  20. * Valid replies:
  21. * fuse_reply_buf
  22. * fuse_reply_iov
  23. * fuse_reply_data
  24. * fuse_reply_err
  25. *
  26. * @param req request handle
  27. * @param ino the inode number
  28. * @param size number of bytes to read
  29. * @param off offset to read from
  30. * @param fi file information
  31. */
  32. func (wfs *WFS) Read(cancel <-chan struct{}, in *fuse.ReadIn, buff []byte) (fuse.ReadResult, fuse.Status) {
  33. fh := wfs.GetHandle(FileHandleId(in.Fh))
  34. if fh == nil {
  35. return nil, fuse.ENOENT
  36. }
  37. fh.entryLock.Lock()
  38. defer fh.entryLock.Unlock()
  39. offset := int64(in.Offset)
  40. totalRead, err := readDataByFileHandle(buff, fh, offset)
  41. if err != nil {
  42. glog.Warningf("file handle read %s %d: %v", fh.FullPath(), totalRead, err)
  43. return nil, fuse.EIO
  44. }
  45. return fuse.ReadResultData(buff[:totalRead]), fuse.OK
  46. }
  47. func readDataByFileHandle(buff []byte, fhIn *FileHandle, offset int64) (int64, error) {
  48. // read data from source file
  49. size := len(buff)
  50. fhIn.lockForRead(offset, size)
  51. defer fhIn.unlockForRead(offset, size)
  52. n, err := fhIn.readFromChunks(buff, offset)
  53. if err == nil || err == io.EOF {
  54. maxStop := fhIn.readFromDirtyPages(buff, offset)
  55. n = max(maxStop-offset, n)
  56. }
  57. if err == io.EOF {
  58. err = nil
  59. }
  60. return n, err
  61. }