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.

145 lines
3.0 KiB

5 years ago
5 years ago
5 years ago
  1. package filesys
  2. import (
  3. "context"
  4. "strings"
  5. "github.com/seaweedfs/fuse"
  6. "github.com/chrislusf/seaweedfs/weed/filesys/meta_cache"
  7. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  8. "github.com/chrislusf/seaweedfs/weed/util"
  9. )
  10. const (
  11. XATTR_PREFIX = "xattr-" // same as filer
  12. )
  13. func getxattr(entry *filer_pb.Entry, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error {
  14. if entry == nil {
  15. return fuse.ErrNoXattr
  16. }
  17. if entry.Extended == nil {
  18. return fuse.ErrNoXattr
  19. }
  20. data, found := entry.Extended[XATTR_PREFIX+req.Name]
  21. if !found {
  22. return fuse.ErrNoXattr
  23. }
  24. if req.Position < uint32(len(data)) {
  25. size := req.Size
  26. if req.Position+size >= uint32(len(data)) {
  27. size = uint32(len(data)) - req.Position
  28. }
  29. if size == 0 {
  30. resp.Xattr = data[req.Position:]
  31. } else {
  32. resp.Xattr = data[req.Position : req.Position+size]
  33. }
  34. }
  35. return nil
  36. }
  37. func setxattr(entry *filer_pb.Entry, req *fuse.SetxattrRequest) error {
  38. if entry == nil {
  39. return fuse.EIO
  40. }
  41. if entry.Extended == nil {
  42. entry.Extended = make(map[string][]byte)
  43. }
  44. data, _ := entry.Extended[XATTR_PREFIX+req.Name]
  45. newData := make([]byte, int(req.Position)+len(req.Xattr))
  46. copy(newData, data)
  47. copy(newData[int(req.Position):], req.Xattr)
  48. entry.Extended[XATTR_PREFIX+req.Name] = newData
  49. return nil
  50. }
  51. func removexattr(entry *filer_pb.Entry, req *fuse.RemovexattrRequest) error {
  52. if entry == nil {
  53. return fuse.ErrNoXattr
  54. }
  55. if entry.Extended == nil {
  56. return fuse.ErrNoXattr
  57. }
  58. _, found := entry.Extended[XATTR_PREFIX+req.Name]
  59. if !found {
  60. return fuse.ErrNoXattr
  61. }
  62. delete(entry.Extended, XATTR_PREFIX+req.Name)
  63. return nil
  64. }
  65. func listxattr(entry *filer_pb.Entry, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error {
  66. if entry == nil {
  67. return fuse.EIO
  68. }
  69. for k := range entry.Extended {
  70. if strings.HasPrefix(k, XATTR_PREFIX) {
  71. resp.Append(k[len(XATTR_PREFIX):])
  72. }
  73. }
  74. size := req.Size
  75. if req.Position+size >= uint32(len(resp.Xattr)) {
  76. size = uint32(len(resp.Xattr)) - req.Position
  77. }
  78. if size == 0 {
  79. resp.Xattr = resp.Xattr[req.Position:]
  80. } else {
  81. resp.Xattr = resp.Xattr[req.Position : req.Position+size]
  82. }
  83. return nil
  84. }
  85. func (wfs *WFS) maybeLoadEntry(dir, name string) (entry *filer_pb.Entry, err error) {
  86. fullpath := util.NewFullPath(dir, name)
  87. // glog.V(3).Infof("read entry cache miss %s", fullpath)
  88. // return a valid entry for the mount root
  89. if string(fullpath) == wfs.option.FilerMountRootPath {
  90. return &filer_pb.Entry{
  91. Name: name,
  92. IsDirectory: true,
  93. Attributes: &filer_pb.FuseAttributes{
  94. Mtime: wfs.option.MountMtime.Unix(),
  95. FileMode: uint32(wfs.option.MountMode),
  96. Uid: wfs.option.MountUid,
  97. Gid: wfs.option.MountGid,
  98. Crtime: wfs.option.MountCtime.Unix(),
  99. },
  100. }, nil
  101. }
  102. // read from async meta cache
  103. meta_cache.EnsureVisited(wfs.metaCache, wfs, util.FullPath(dir))
  104. cachedEntry, cacheErr := wfs.metaCache.FindEntry(context.Background(), fullpath)
  105. if cacheErr == filer_pb.ErrNotFound {
  106. return nil, fuse.ENOENT
  107. }
  108. return cachedEntry.ToProtoEntry(), cacheErr
  109. }