jacobsa/fuse

ForgetInode one inode call twices at same time lead to panic

zhjunqin opened this issue · 2 comments

Hi,

I met following problem when I use goofys on fuse.

It seems LookUpInode for file "record-00063-of-00100" happened twice as same time, then ForgetInode called twices, which lead to the panic.

I checked source code at the call stack, but didn't find any clue about this problem.
I don't have much knowledge about this. I have some questiongs.
How or Why ForgetInode is trigger? And what is ForgetInode op for?

Could someone help me about this? Thanks in advance!

2019/01/04 19:55:46.420179 fuse.DEBUG Op 0x001732af        connection.go:395] <- LookUpInode (parent 4, name "record-00063-of-00100")
2019/01/04 19:55:46.420305 fuse.DEBUG Inode.LookUp 4 record/files [record-00063-of-00100]
2019/01/04 19:55:46.420652 fuse.DEBUG Op 0x001732b0        connection.go:395] <- LookUpInode (parent 4, name "record-00063-of-00100")

...
2019/01/04 19:55:46.420778 fuse.DEBUG Inode.LookUp 4 record/files [record-00063-of-00100]
...
2019/01/04 19:55:46.422393 fuse.DEBUG <-- LookUpInode 4 record-00063-of-00100 <nil>
...
2019/01/04 19:55:46.422445 fuse.DEBUG <-- LookUpInode 4 record-00063-of-00100 <nil>
...
2019/01/04 19:55:46.422453 fuse.DEBUG Op 0x001732af        connection.go:478] -> OK (inode 12242)
...

2019/01/04 19:55:46.422504 fuse.DEBUG Op 0x001732b0        connection.go:478] -> OK (inode 12242)
2019/01/04 19:55:46.422556 fuse.DEBUG Op 0x001732b2        connection.go:395] <- ForgetInode (inode 12242)
2019/01/04 19:55:46.422577 fuse.DEBUG DeRef 12242 record/files/record-00063-of-00100 [1 1]
2019/01/04 19:55:46.422774 fuse.DEBUG Op 0x001732b2        connection.go:478] -> OK ()
2019/01/04 19:55:46.422797 fuse.DEBUG Op 0x001732b3        connection.go:395] <- ForgetInode (inode 12242)
panic: Unknown inode: 12242

goroutine 44 [running]:
github.com/kahing/goofys/internal.(*Goofys).getInodeOrDie(0xc42021dd40, 0x2fd2, 0xc4e90c4cc0)
        /opt/bin/work/src/github.com/kahing/goofys/internal/goofys.go:421 +0x126
github.com/kahing/goofys/internal.(*Goofys).ForgetInode(0xc42021dd40, 0xa01b00, 0xc599933650, 0xc4257327d0, 0x899000, 0xc4257327d0)
        /opt/bin/work/src/github.com/kahing/goofys/internal/goofys.go:696 +0x58
github.com/jacobsa/fuse/fuseutil.(*fileSystemServer).handleOp(0xc42036a2e0, 0xc420388c30, 0xa01b00, 0xc599933650, 0x899000, 0xc4257327d0)
        /opt/bin/work/src/github.com/jacobsa/fuse/fuseutil/file_system.go:151 +0x8c4
github.com/jacobsa/fuse/fuseutil.(*fileSystemServer).ServeOps(0xc42036a2e0, 0xc420388c30)
        /opt/bin/work/src/github.com/jacobsa/fuse/fuseutil/file_system.go:119 +0x11c
github.com/jacobsa/fuse.Mount.func1(0x9fcaa0, 0xc42036a2e0, 0xc420388c30, 0xc420384070)
        /opt/bin/work/src/github.com/jacobsa/fuse/mount.go:89 +0x3f
created by github.com/jacobsa/fuse.Mount
        /opt/bin/work/src/github.com/jacobsa/fuse/mount.go:88 +0x497

Following change is included, so it doesn't fix the problem.

I really want to know how ForgetInode is triggered. I searched all codes but not see any place call ForgetInode

		if _, ok := op.(*fuseops.ForgetInodeOp); ok {
			// Special case: call in this goroutine for
			// forget inode ops, which may come in a
			// flurry from the kernel and are generally
			// cheap for the file system to handle
			s.handleOp(c, ctx, op)
		} else {
			go s.handleOp(c, ctx, op)
		}

This is a goofys issue, so I want to close it.
Please refer to kahing/goofys#392.

But I really still want to know how ForgetInode is triggered. I searched all codes but not see any place call ForgetInode. Could someone can help me out of this?