From 3d93570979967b685145c7126098a419eda9fc29 Mon Sep 17 00:00:00 2001 From: chrislu Date: Sun, 13 Feb 2022 03:31:47 -0800 Subject: [PATCH] supports forget --- weed/mount/inode_to_path.go | 12 +++++++++ weed/mount/weedfs.go | 1 + weed/mount/weedfs_forget.go | 52 +++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 weed/mount/weedfs_forget.go diff --git a/weed/mount/inode_to_path.go b/weed/mount/inode_to_path.go index 21e6c867c..6650f2380 100644 --- a/weed/mount/inode_to_path.go +++ b/weed/mount/inode_to_path.go @@ -82,3 +82,15 @@ func (i *InodeToPath) RemovePath(path util.FullPath) { delete(i.inode2path, inode) } } +func (i *InodeToPath) RemoveInode(inode uint64) { + if inode == 1 { + return + } + i.RLock() + defer i.RUnlock() + path, found := i.inode2path[inode] + if found { + delete(i.path2inode, path) + delete(i.inode2path, inode) + } +} diff --git a/weed/mount/weedfs.go b/weed/mount/weedfs.go index 6788b0b36..a36e4dc97 100644 --- a/weed/mount/weedfs.go +++ b/weed/mount/weedfs.go @@ -120,6 +120,7 @@ func (wfs *WFS) maybeLoadEntry(fullpath util.FullPath) (*filer_pb.Entry, fuse.St }, fuse.OK } + // TODO Use inode to selectively filetering metadata updates // read from async meta cache meta_cache.EnsureVisited(wfs.metaCache, wfs, util.FullPath(dir)) cachedEntry, cacheErr := wfs.metaCache.FindEntry(context.Background(), fullpath) diff --git a/weed/mount/weedfs_forget.go b/weed/mount/weedfs_forget.go new file mode 100644 index 000000000..2d09a473b --- /dev/null +++ b/weed/mount/weedfs_forget.go @@ -0,0 +1,52 @@ +package mount + +// Forget is called when the kernel discards entries from its +// dentry cache. This happens on unmount, and when the kernel +// is short on memory. Since it is not guaranteed to occur at +// any moment, and since there is no return value, Forget +// should not do I/O, as there is no channel to report back +// I/O errors. +// from https://github.com/libfuse/libfuse/blob/master/include/fuse_lowlevel.h +/** + * Forget about an inode + * + * This function is called when the kernel removes an inode + * from its internal caches. + * + * The inode's lookup count increases by one for every call to + * fuse_reply_entry and fuse_reply_create. The nlookup parameter + * indicates by how much the lookup count should be decreased. + * + * Inodes with a non-zero lookup count may receive request from + * the kernel even after calls to unlink, rmdir or (when + * overwriting an existing file) rename. Filesystems must handle + * such requests properly and it is recommended to defer removal + * of the inode until the lookup count reaches zero. Calls to + * unlink, rmdir or rename will be followed closely by forget + * unless the file or directory is open, in which case the + * kernel issues forget only after the release or releasedir + * calls. + * + * Note that if a file system will be exported over NFS the + * inodes lifetime must extend even beyond forget. See the + * generation field in struct fuse_entry_param above. + * + * On unmount the lookup count for all inodes implicitly drops + * to zero. It is not guaranteed that the file system will + * receive corresponding forget messages for the affected + * inodes. + * + * Valid replies: + * fuse_reply_none + * + * @param req request handle + * @param ino the inode number + * @param nlookup the number of lookups to forget + */ +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) + } +}