xattr.go 2.7 KB

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