weedfs_dir_lookup.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package mount
  2. import (
  3. "context"
  4. "github.com/hanwen/go-fuse/v2/fuse"
  5. "github.com/seaweedfs/seaweedfs/weed/filer"
  6. "github.com/seaweedfs/seaweedfs/weed/glog"
  7. "github.com/seaweedfs/seaweedfs/weed/mount/meta_cache"
  8. "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
  9. )
  10. // Lookup is called by the kernel when the VFS wants to know
  11. // about a file inside a directory. Many lookup calls can
  12. // occur in parallel, but only one call happens for each (dir,
  13. // name) pair.
  14. func (wfs *WFS) Lookup(cancel <-chan struct{}, header *fuse.InHeader, name string, out *fuse.EntryOut) (code fuse.Status) {
  15. if s := checkName(name); s != fuse.OK {
  16. return s
  17. }
  18. dirPath, code := wfs.inodeToPath.GetPath(header.NodeId)
  19. if code != fuse.OK {
  20. return
  21. }
  22. fullFilePath := dirPath.Child(name)
  23. visitErr := meta_cache.EnsureVisited(wfs.metaCache, wfs, dirPath)
  24. if visitErr != nil {
  25. glog.Errorf("dir Lookup %s: %v", dirPath, visitErr)
  26. return fuse.EIO
  27. }
  28. localEntry, cacheErr := wfs.metaCache.FindEntry(context.Background(), fullFilePath)
  29. if cacheErr == filer_pb.ErrNotFound {
  30. return fuse.ENOENT
  31. }
  32. if localEntry == nil {
  33. // glog.V(3).Infof("dir Lookup cache miss %s", fullFilePath)
  34. entry, err := filer_pb.GetEntry(wfs, fullFilePath)
  35. if err != nil {
  36. glog.V(1).Infof("dir GetEntry %s: %v", fullFilePath, err)
  37. return fuse.ENOENT
  38. }
  39. localEntry = filer.FromPbEntry(string(dirPath), entry)
  40. } else {
  41. glog.V(4).Infof("dir Lookup cache hit %s", fullFilePath)
  42. }
  43. if localEntry == nil {
  44. return fuse.ENOENT
  45. }
  46. inode := wfs.inodeToPath.Lookup(fullFilePath, localEntry.Crtime.Unix(), localEntry.IsDirectory(), len(localEntry.HardLinkId) > 0, localEntry.Inode, true)
  47. if fh, found := wfs.fhmap.FindFileHandle(inode); found {
  48. fh.entryLock.RLock()
  49. if entry := fh.GetEntry(); entry != nil {
  50. glog.V(4).Infof("lookup opened file %s size %d", dirPath.Child(localEntry.Name()), filer.FileSize(entry))
  51. localEntry = filer.FromPbEntry(string(dirPath), entry)
  52. }
  53. fh.entryLock.RUnlock()
  54. }
  55. wfs.outputFilerEntry(out, inode, localEntry)
  56. return fuse.OK
  57. }