From 9ea9ec816cd786ac11f662ae44f5e51941dd8f97 Mon Sep 17 00:00:00 2001 From: Jose Matsuda Date: Thu, 24 Jul 2025 13:14:28 -0400 Subject: [PATCH 1/3] feat(readdir): fix inode leak https://github.com/kahing/goofys/pull/786 --- internal/goofys.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/internal/goofys.go b/internal/goofys.go index bf51b4c1..4abf668c 100644 --- a/internal/goofys.go +++ b/internal/goofys.go @@ -764,6 +764,17 @@ func (fs *Goofys) ForgetInode( fs.mu.Lock() defer fs.mu.Unlock() + // Fix ReadDir inode leak https://github.com/kahing/goofys/pull/786 + if inode.isDir() { + for _, child := range inode.dir.Children { + if *child.Name == "." || *child.Name == ".." { + continue + } + delete(fs.inodes, child.Id) + fs.forgotCnt += 1 + } + } + delete(fs.inodes, op.Inode) fs.forgotCnt += 1 From 5ee2c9440da03ef844bba988fdeda1ffad951d97 Mon Sep 17 00:00:00 2001 From: Jose Matsuda Date: Thu, 24 Jul 2025 13:21:41 -0400 Subject: [PATCH 2/3] clean --- internal/goofys.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/goofys.go b/internal/goofys.go index 4abf668c..ceef0067 100644 --- a/internal/goofys.go +++ b/internal/goofys.go @@ -764,7 +764,8 @@ func (fs *Goofys) ForgetInode( fs.mu.Lock() defer fs.mu.Unlock() - // Fix ReadDir inode leak https://github.com/kahing/goofys/pull/786 + // Fix ReadDir inode leak + // https://github.com/kahing/goofys/pull/786 if inode.isDir() { for _, child := range inode.dir.Children { if *child.Name == "." || *child.Name == ".." { From 1868a2115274f2de17dc28ad32313bfbcfde7370 Mon Sep 17 00:00:00 2001 From: Jose Matsuda Date: Thu, 24 Jul 2025 13:52:09 -0400 Subject: [PATCH 3/3] cleanup comments and add trace --- internal/backend_s3.go | 12 ++++++------ internal/goofys.go | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/internal/backend_s3.go b/internal/backend_s3.go index bb9d20ac..4e521814 100644 --- a/internal/backend_s3.go +++ b/internal/backend_s3.go @@ -290,7 +290,7 @@ func (s *S3Backend) Init(key string) error { } func (s *S3Backend) ListObjectsV2(params *s3.ListObjectsV2Input) (*s3.ListObjectsV2Output, string, error) { - s3Log.Debugf("MATHIS TEST: params %v, backend %v", params, s) + s3Log.Debugf("ListObjectsV2: params %v, backend %v", params, s) if s.aws { req, resp := s.S3.ListObjectsV2Request(params) err := req.Send() @@ -317,7 +317,7 @@ func (s *S3Backend) ListObjectsV2(params *s3.ListObjectsV2Input) (*s3.ListObject if err != nil { return nil, "", err } - s3Log.Debugf("MATHIS TEST: objs %v, err %v", objs, err) + s3Log.Debugf("ListObjectsV2: objs %v, err %v", objs, err) count := int64(len(objs.Contents)) v2Objs := s3.ListObjectsV2Output{ CommonPrefixes: objs.CommonPrefixes, @@ -392,7 +392,7 @@ func (s *S3Backend) HeadBlob(param *HeadBlobInput) (*HeadBlobOutput, error) { func (s *S3Backend) ListBlobs(param *ListBlobsInput) (*ListBlobsOutput, error) { var maxKeys *int64 - s3Log.Debugf("MATHIS TEST") + s3Log.Debugf("ListBlobs") if param.MaxKeys != nil { maxKeys = aws.Int64(int64(*param.MaxKeys)) } @@ -405,7 +405,7 @@ func (s *S3Backend) ListBlobs(param *ListBlobsInput) (*ListBlobsOutput, error) { StartAfter: param.StartAfter, ContinuationToken: param.ContinuationToken, }) - s3Log.Debugf("MATHIS TEST: resp %v, reqid %v, err %v", resp, reqId, err) + s3Log.Debugf("ListBlobs: resp %v, reqid %v, err %v", resp, reqId, err) if err != nil { return nil, mapAwsError(err) } @@ -425,12 +425,12 @@ func (s *S3Backend) ListBlobs(param *ListBlobsInput) (*ListBlobsOutput, error) { StorageClass: i.StorageClass, }) } - s3Log.Debugf("MATHIS TEST: prefixes %v, items %v", prefixes, items) + s3Log.Debugf("ListBlobs: prefixes %v, items %v", prefixes, items) isTruncatedFlag := false if resp.IsTruncated != nil { isTruncatedFlag = *resp.IsTruncated } else { - s3Log.Debugf("MATHIS TEST: nil pointer catch") + s3Log.Debugf("ListBlobs: nil pointer catch") } return &ListBlobsOutput{ Prefixes: prefixes, diff --git a/internal/goofys.go b/internal/goofys.go index ceef0067..65dfd839 100644 --- a/internal/goofys.go +++ b/internal/goofys.go @@ -771,6 +771,7 @@ func (fs *Goofys) ForgetInode( if *child.Name == "." || *child.Name == ".." { continue } + s3Log.Debugf("Goofys Upstream PR: Inode Dir Leak fix") delete(fs.inodes, child.Id) fs.forgotCnt += 1 }