weedfs_file_write.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package mount
  2. import (
  3. "github.com/hanwen/go-fuse/v2/fuse"
  4. "net/http"
  5. "syscall"
  6. "time"
  7. )
  8. /**
  9. * Write data
  10. *
  11. * Write should return exactly the number of bytes requested
  12. * except on error. An exception to this is when the file has
  13. * been opened in 'direct_io' mode, in which case the return value
  14. * of the write system call will reflect the return value of this
  15. * operation.
  16. *
  17. * Unless FUSE_CAP_HANDLE_KILLPRIV is disabled, this method is
  18. * expected to reset the setuid and setgid bits.
  19. *
  20. * fi->fh will contain the value set by the open method, or will
  21. * be undefined if the open method didn't set any value.
  22. *
  23. * Valid replies:
  24. * fuse_reply_write
  25. * fuse_reply_err
  26. *
  27. * @param req request handle
  28. * @param ino the inode number
  29. * @param buf data to write
  30. * @param size number of bytes to write
  31. * @param off offset to write to
  32. * @param fi file information
  33. */
  34. func (wfs *WFS) Write(cancel <-chan struct{}, in *fuse.WriteIn, data []byte) (written uint32, code fuse.Status) {
  35. if wfs.IsOverQuota {
  36. return 0, fuse.Status(syscall.ENOSPC)
  37. }
  38. fh := wfs.GetHandle(FileHandleId(in.Fh))
  39. if fh == nil {
  40. return 0, fuse.ENOENT
  41. }
  42. fh.dirtyPages.writerPattern.MonitorWriteAt(int64(in.Offset), int(in.Size))
  43. tsNs := time.Now().UnixNano()
  44. fh.Lock()
  45. defer fh.Unlock()
  46. entry := fh.GetEntry()
  47. if entry == nil {
  48. return 0, fuse.OK
  49. }
  50. entry.Content = nil
  51. offset := int64(in.Offset)
  52. entry.Attributes.FileSize = uint64(max(offset+int64(len(data)), int64(entry.Attributes.FileSize)))
  53. // glog.V(4).Infof("%v write [%d,%d) %d", fh.f.fullpath(), req.Offset, req.Offset+int64(len(req.Data)), len(req.Data))
  54. fh.dirtyPages.AddPage(offset, data, fh.dirtyPages.writerPattern.IsSequentialMode(), tsNs)
  55. written = uint32(len(data))
  56. if offset == 0 {
  57. // detect mime type
  58. fh.contentType = http.DetectContentType(data)
  59. }
  60. fh.dirtyMetadata = true
  61. if IsDebugFileReadWrite {
  62. // print("+")
  63. fh.mirrorFile.WriteAt(data, offset)
  64. }
  65. return written, fuse.OK
  66. }