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.

142 lines
2.7 KiB

  1. package filesys
  2. import (
  3. "context"
  4. "path/filepath"
  5. "github.com/chrislusf/seaweedfs/weed/glog"
  6. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  7. "github.com/seaweedfs/fuse"
  8. )
  9. func getxattr(entry *filer_pb.Entry, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error {
  10. if entry == nil {
  11. return fuse.ErrNoXattr
  12. }
  13. if entry.Extended == nil {
  14. return fuse.ErrNoXattr
  15. }
  16. data, found := entry.Extended[req.Name]
  17. if !found {
  18. return fuse.ErrNoXattr
  19. }
  20. if req.Position < uint32(len(data)) {
  21. size := req.Size
  22. if req.Position+size >= uint32(len(data)) {
  23. size = uint32(len(data)) - req.Position
  24. }
  25. if size == 0 {
  26. resp.Xattr = data[req.Position:]
  27. } else {
  28. resp.Xattr = data[req.Position : req.Position+size]
  29. }
  30. }
  31. return nil
  32. }
  33. func setxattr(entry *filer_pb.Entry, req *fuse.SetxattrRequest) error {
  34. if entry == nil {
  35. return fuse.EIO
  36. }
  37. if entry.Extended == nil {
  38. entry.Extended = make(map[string][]byte)
  39. }
  40. data, _ := entry.Extended[req.Name]
  41. newData := make([]byte, int(req.Position)+len(req.Xattr))
  42. copy(newData, data)
  43. copy(newData[int(req.Position):], req.Xattr)
  44. entry.Extended[req.Name] = newData
  45. return nil
  46. }
  47. func removexattr(entry *filer_pb.Entry, req *fuse.RemovexattrRequest) error {
  48. if entry == nil {
  49. return fuse.ErrNoXattr
  50. }
  51. if entry.Extended == nil {
  52. return fuse.ErrNoXattr
  53. }
  54. _, found := entry.Extended[req.Name]
  55. if !found {
  56. return fuse.ErrNoXattr
  57. }
  58. delete(entry.Extended, req.Name)
  59. return nil
  60. }
  61. func listxattr(entry *filer_pb.Entry, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error {
  62. if entry == nil {
  63. return fuse.EIO
  64. }
  65. for k := range entry.Extended {
  66. resp.Append(k)
  67. }
  68. size := req.Size
  69. if req.Position+size >= uint32(len(resp.Xattr)) {
  70. size = uint32(len(resp.Xattr)) - req.Position
  71. }
  72. if size == 0 {
  73. resp.Xattr = resp.Xattr[req.Position:]
  74. } else {
  75. resp.Xattr = resp.Xattr[req.Position : req.Position+size]
  76. }
  77. return nil
  78. }
  79. func (wfs *WFS) maybeLoadEntry(ctx context.Context, dir, name string) (entry *filer_pb.Entry, err error) {
  80. fullpath := filepath.Join(dir, name)
  81. item := wfs.listDirectoryEntriesCache.Get(fullpath)
  82. if item != nil && !item.Expired() {
  83. entry = item.Value().(*filer_pb.Entry)
  84. return
  85. }
  86. glog.V(3).Infof("read entry cache miss %s", fullpath)
  87. err = wfs.WithFilerClient(ctx, func(client filer_pb.SeaweedFilerClient) error {
  88. request := &filer_pb.LookupDirectoryEntryRequest{
  89. Name: name,
  90. Directory: dir,
  91. }
  92. resp, err := client.LookupDirectoryEntry(ctx, request)
  93. if err != nil {
  94. glog.V(3).Infof("file attr read file %v: %v", request, err)
  95. return fuse.ENOENT
  96. }
  97. entry = resp.Entry
  98. if entry != nil {
  99. wfs.listDirectoryEntriesCache.Set(fullpath, entry, wfs.option.EntryCacheTtl)
  100. }
  101. return nil
  102. })
  103. return
  104. }