diff --git a/weed/mount/inode_to_path.go b/weed/mount/inode_to_path.go index 6650f2380..25e615ed6 100644 --- a/weed/mount/inode_to_path.go +++ b/weed/mount/inode_to_path.go @@ -9,19 +9,23 @@ import ( type InodeToPath struct { sync.RWMutex nextInodeId uint64 - inode2path map[uint64]util.FullPath + inode2path map[uint64]*InodeEntry path2inode map[util.FullPath]uint64 } +type InodeEntry struct { + util.FullPath + nlookup uint64 +} func NewInodeToPath() *InodeToPath { return &InodeToPath{ - inode2path: make(map[uint64]util.FullPath), + inode2path: make(map[uint64]*InodeEntry), path2inode: make(map[util.FullPath]uint64), nextInodeId: 2, // the root inode id is 1 } } -func (i *InodeToPath) GetInode(path util.FullPath) uint64 { +func (i *InodeToPath) Lookup(path util.FullPath) uint64 { if path == "/" { return 1 } @@ -32,7 +36,22 @@ func (i *InodeToPath) GetInode(path util.FullPath) uint64 { inode = i.nextInodeId i.nextInodeId++ i.path2inode[path] = inode - i.inode2path[inode] = path + i.inode2path[inode] = &InodeEntry{path, 1} + } else { + i.inode2path[inode].nlookup++ + } + return inode +} + +func (i *InodeToPath) GetInode(path util.FullPath) uint64 { + if path == "/" { + return 1 + } + i.Lock() + defer i.Unlock() + inode, found := i.path2inode[path] + if !found { + glog.Fatalf("GetInode unknown inode %d", inode) } return inode } @@ -45,9 +64,9 @@ func (i *InodeToPath) GetPath(inode uint64) util.FullPath { defer i.RUnlock() path, found := i.inode2path[inode] if !found { - glog.Fatal("not found inode %d", inode) + glog.Fatalf("not found inode %d", inode) } - return path + return path.FullPath } func (i *InodeToPath) HasPath(path util.FullPath) bool { @@ -82,15 +101,19 @@ func (i *InodeToPath) RemovePath(path util.FullPath) { delete(i.inode2path, inode) } } -func (i *InodeToPath) RemoveInode(inode uint64) { + +func (i *InodeToPath) Forget(inode, nlookup uint64) { if inode == 1 { return } - i.RLock() - defer i.RUnlock() + i.Lock() + defer i.Unlock() path, found := i.inode2path[inode] if found { - delete(i.path2inode, path) - delete(i.inode2path, inode) + path.nlookup -= nlookup + if path.nlookup <= 0 { + delete(i.path2inode, path.FullPath) + delete(i.inode2path, inode) + } } } diff --git a/weed/mount/weedfs_dir_lookup.go b/weed/mount/weedfs_dir_lookup.go index 477cfad0a..733e31908 100644 --- a/weed/mount/weedfs_dir_lookup.go +++ b/weed/mount/weedfs_dir_lookup.go @@ -50,7 +50,7 @@ func (wfs *WFS) Lookup(cancel <-chan struct{}, header *fuse.InHeader, name strin return fuse.ENOENT } - inode := wfs.inodeToPath.GetInode(fullFilePath) + inode := wfs.inodeToPath.Lookup(fullFilePath) wfs.outputFilerEntry(out, inode, localEntry) diff --git a/weed/mount/weedfs_dir_mkrm.go b/weed/mount/weedfs_dir_mkrm.go index fb854b77e..4efab078f 100644 --- a/weed/mount/weedfs_dir_mkrm.go +++ b/weed/mount/weedfs_dir_mkrm.go @@ -71,7 +71,7 @@ func (wfs *WFS) Mkdir(cancel <-chan struct{}, in *fuse.MkdirIn, name string, out return fuse.EIO } - inode := wfs.inodeToPath.GetInode(entryFullPath) + inode := wfs.inodeToPath.Lookup(entryFullPath) wfs.outputPbEntry(out, inode, newEntry) diff --git a/weed/mount/weedfs_file_mkrm.go b/weed/mount/weedfs_file_mkrm.go index 82da45179..089cb540d 100644 --- a/weed/mount/weedfs_file_mkrm.go +++ b/weed/mount/weedfs_file_mkrm.go @@ -85,7 +85,7 @@ func (wfs *WFS) Mknod(cancel <-chan struct{}, in *fuse.MknodIn, name string, out return fuse.EIO } - inode := wfs.inodeToPath.GetInode(entryFullPath) + inode := wfs.inodeToPath.Lookup(entryFullPath) wfs.outputPbEntry(out, inode, newEntry) diff --git a/weed/mount/weedfs_forget.go b/weed/mount/weedfs_forget.go index 2d09a473b..34e0eddc9 100644 --- a/weed/mount/weedfs_forget.go +++ b/weed/mount/weedfs_forget.go @@ -43,10 +43,18 @@ package mount * @param ino the inode number * @param nlookup the number of lookups to forget */ +/* + +int fuse_reply_entry ( fuse_req_t req, +const struct fuse_entry_param * e +) +Reply with a directory entry + +Possible requests: lookup, mknod, mkdir, symlink, link + +Side effects: increments the lookup count on success + +*/ func (wfs *WFS) Forget(nodeid, nlookup uint64) { - if nlookup == 0 { - // need to maintain the inode for selective filtering - // and caching for metadata updates - wfs.inodeToPath.RemoveInode(nodeid) - } + wfs.inodeToPath.Forget(nodeid, nlookup) } diff --git a/weed/mount/weedfs_link.go b/weed/mount/weedfs_link.go index c1d634a94..05710e5a0 100644 --- a/weed/mount/weedfs_link.go +++ b/weed/mount/weedfs_link.go @@ -85,7 +85,7 @@ func (wfs *WFS) Link(cancel <-chan struct{}, in *fuse.LinkIn, name string, out * return fuse.EIO } - inode := wfs.inodeToPath.GetInode(newEntryPath) + inode := wfs.inodeToPath.Lookup(newEntryPath) wfs.outputPbEntry(out, inode, request.Entry) diff --git a/weed/mount/weedfs_symlink.go b/weed/mount/weedfs_symlink.go index 2c66db7f4..86a7b50e4 100644 --- a/weed/mount/weedfs_symlink.go +++ b/weed/mount/weedfs_symlink.go @@ -56,7 +56,7 @@ func (wfs *WFS) Symlink(cancel <-chan struct{}, header *fuse.InHeader, target st return fuse.EIO } - inode := wfs.inodeToPath.GetInode(entryFullPath) + inode := wfs.inodeToPath.Lookup(entryFullPath) wfs.outputPbEntry(out, inode, request.Entry)