xattr.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package filesys
  2. import (
  3. "context"
  4. "github.com/seaweedfs/fuse"
  5. "github.com/chrislusf/seaweedfs/weed/filesys/meta_cache"
  6. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  7. "github.com/chrislusf/seaweedfs/weed/util"
  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(dir, name string) (entry *filer_pb.Entry, err error) {
  80. fullpath := util.NewFullPath(dir, name)
  81. // glog.V(3).Infof("read entry cache miss %s", fullpath)
  82. // return a valid entry for the mount root
  83. if string(fullpath) == wfs.option.FilerMountRootPath {
  84. return &filer_pb.Entry{
  85. Name: wfs.option.FilerMountRootPath,
  86. IsDirectory: true,
  87. Attributes: &filer_pb.FuseAttributes{
  88. Mtime: wfs.option.MountMtime.Unix(),
  89. FileMode: uint32(wfs.option.MountMode),
  90. Uid: wfs.option.MountUid,
  91. Gid: wfs.option.MountGid,
  92. Crtime: wfs.option.MountCtime.Unix(),
  93. },
  94. }, nil
  95. }
  96. // read from async meta cache
  97. meta_cache.EnsureVisited(wfs.metaCache, wfs, util.FullPath(dir))
  98. cachedEntry, cacheErr := wfs.metaCache.FindEntry(context.Background(), fullpath)
  99. if cacheErr == filer_pb.ErrNotFound {
  100. return nil, fuse.ENOENT
  101. }
  102. return cachedEntry.ToProtoEntry(), cacheErr
  103. }