jvilk / BrowserFS

BrowserFS is an in-browser filesystem that emulates the Node JS filesystem API and supports storing and retrieving files from various backends.
Other
3.06k stars 215 forks source link

Infinite recursion when there's no root (IndexedDB + OverlayFS) #225

Closed 1j01 closed 6 years ago

1j01 commented 6 years ago

It took me a while of debugging this to remember that I had cleared the IndexedDB. I hadn't thought much of it at the time at all, assuming it would effectively reset everything. (And it wasn't recent enough that I would identify it as the cause right away.)

UnlockedOverlayFS.createParentDirectoriesAsync gets into an infinite async recursion loop, adding / to toCreate: https://github.com/jvilk/BrowserFS/blob/73e4eca717f9e8c21836c5d3affb14dcfde1d9e3/src/backend/OverlayFS.ts#L857-L859

path.dirname("/") == "/"

The end result is that writeFile never calls back and subsequent calls wait infinitely as well, waiting indefinitely for the mutex unlock.

An error when there's no root would be nice! Alternatively it could re-create the root, and treat an empty store similar to if there was no store. That would be even nicer. But an error could be enough to immediately know how to resolve the problem.

Should just need to check if parent === "/" to trigger an error; I'm not sure if creating the root would be more complicated or not (haven't thought about it).

1j01 commented 6 years ago

Apparently deleting the database doesn't work either. It seems to recreate the database, empty. I don't know why.

Also, a GIF:

browserfs://////////////////////////////////////////////////////////////////////////////////////////////

1j01 commented 6 years ago

It's not creating the root in the database even in Incognito now. I should probably run a git bisect, but can you point me to the code where the root would be created for an IndexedDB store?

jvilk commented 6 years ago

I'm currently traveling, but root directory creation happens in the constructor of KeyValueFilesystem:

https://github.com/jvilk/BrowserFS/blob/master/src/generic/key_value_filesystem.ts#L430

1j01 commented 6 years ago

Thanks!

So, it apparently never gets to AsyncKeyValueFileSystem.prototype.init, and I don't see any calls to init.

I guess maybe it got left out when switching over to using Create for async constructors? Or it just gets a root thru empty or other paths and so it never came up.