weedfs_file_read.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. package mount
  2. import (
  3. "github.com/chrislusf/seaweedfs/weed/glog"
  4. "github.com/hanwen/go-fuse/v2/fuse"
  5. "io"
  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. offset := int64(in.Offset)
  38. fh.lockForRead(offset, len(buff))
  39. defer fh.unlockForRead(offset, len(buff))
  40. totalRead, err := fh.readFromChunks(buff, offset)
  41. if err == nil || err == io.EOF {
  42. maxStop := fh.readFromDirtyPages(buff, offset)
  43. totalRead = max(maxStop-offset, totalRead)
  44. }
  45. if err == io.EOF {
  46. err = nil
  47. }
  48. if err != nil {
  49. glog.Warningf("file handle read %s %d: %v", fh.FullPath(), totalRead, err)
  50. return nil, fuse.EIO
  51. }
  52. return fuse.ReadResultData(buff[:totalRead]), fuse.OK
  53. }