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.

134 lines
2.6 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. resp.Xattr = data[req.Position : req.Position+size]
  26. }
  27. return nil
  28. }
  29. func setxattr(entry *filer_pb.Entry, req *fuse.SetxattrRequest) error {
  30. if entry == nil {
  31. return fuse.EIO
  32. }
  33. if entry.Extended == nil {
  34. entry.Extended = make(map[string][]byte)
  35. }
  36. data, _ := entry.Extended[req.Name]
  37. newData := make([]byte, int(req.Position)+len(req.Xattr))
  38. copy(newData, data)
  39. copy(newData[int(req.Position):], req.Xattr)
  40. entry.Extended[req.Name] = newData
  41. return nil
  42. }
  43. func removexattr(entry *filer_pb.Entry, req *fuse.RemovexattrRequest) error {
  44. if entry == nil {
  45. return fuse.ErrNoXattr
  46. }
  47. if entry.Extended == nil {
  48. return fuse.ErrNoXattr
  49. }
  50. _, found := entry.Extended[req.Name]
  51. if !found {
  52. return fuse.ErrNoXattr
  53. }
  54. delete(entry.Extended, req.Name)
  55. return nil
  56. }
  57. func listxattr(entry *filer_pb.Entry, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error {
  58. if entry == nil {
  59. return fuse.EIO
  60. }
  61. for k := range entry.Extended {
  62. resp.Append(k)
  63. }
  64. size := req.Size
  65. if req.Position+size >= uint32(len(resp.Xattr)) {
  66. size = uint32(len(resp.Xattr)) - req.Position
  67. }
  68. resp.Xattr = resp.Xattr[req.Position : req.Position+size]
  69. return nil
  70. }
  71. func (wfs *WFS) maybeLoadEntry(ctx context.Context, dir, name string) (entry *filer_pb.Entry, err error) {
  72. fullpath := filepath.Join(dir, name)
  73. item := wfs.listDirectoryEntriesCache.Get(fullpath)
  74. if item != nil && !item.Expired() {
  75. entry = item.Value().(*filer_pb.Entry)
  76. return
  77. }
  78. glog.V(3).Infof("read entry cache miss %s", fullpath)
  79. err = wfs.WithFilerClient(ctx, func(client filer_pb.SeaweedFilerClient) error {
  80. request := &filer_pb.LookupDirectoryEntryRequest{
  81. Name: name,
  82. Directory: dir,
  83. }
  84. resp, err := client.LookupDirectoryEntry(ctx, request)
  85. if err != nil {
  86. glog.V(3).Infof("file attr read file %v: %v", request, err)
  87. return fuse.ENOENT
  88. }
  89. entry = resp.Entry
  90. if entry != nil {
  91. wfs.listDirectoryEntriesCache.Set(fullpath, entry, wfs.option.EntryCacheTtl)
  92. }
  93. return nil
  94. })
  95. return
  96. }