Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fuse: remove race conditions on fsh #53

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

btwotch
Copy link

@btwotch btwotch commented Jan 18, 2021

remove race conditions as seen with go test -race on FileSystemHost
members

@btwotch btwotch force-pushed the filesystemhost_race_conditions branch 4 times, most recently from 21feca1 to 3ee7e5b Compare January 19, 2021 18:33
fuse/host.go Outdated
@@ -577,13 +582,17 @@ func NewFileSystemHost(fsop FileSystemInterface) *FileSystemHost {
// SetCapCaseInsensitive informs the host that the hosted file system is case insensitive
// [OSX and Windows only].
func (host *FileSystemHost) SetCapCaseInsensitive(value bool) {
host.Lock()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessary.

The SetCapCaseInsensitive method is (should be) called before Mount happens. The Mount method may (implicitly or explicitly) create new file system threads, and the value of host.capCaseInsensitive will become available to them regardless of locking. Note that the value of host.capCaseInsensitive is not supposed to change after Mount.

For this reason it is not necessary to wrap the host.capCaseInsensitive = value statement in a lock.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it, although I think that it would make the code more uniform to lock it here as well.

fuse/host.go Outdated
host.capCaseInsensitive = value
}

// SetCapReaddirPlus informs the host that the hosted file system has the readdir-plus
// capability [Windows only]. A file system that has the readdir-plus capability can send
// full stat information during Readdir, thus avoiding extraneous Getattr calls.
func (host *FileSystemHost) SetCapReaddirPlus(value bool) {
host.Lock()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessary.

The SetCapReaddirPlus method is (should be) called before Mount happens. The Mount method may (implicitly or explicitly) create new file system threads, and the value of host.capReaddirPlus will become available to them regardless of locking. Note that the value of host.capReaddirPlus is not supposed to change after Mount.

For this reason it is not necessary to wrap the host.capReaddirPlus = value statement in a lock.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it.

fuse/host.go Outdated
@@ -651,6 +660,7 @@ func (host *FileSystemHost) Mount(mountpoint string, opts []string) bool {
* We need to determine the mountpoint that FUSE is going (to try) to use, so that we
* can unmount later.
*/
host.Lock()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessary.

The host.mntp variable is read-only after Mount. The Mount method may (implicitly or explicitly) create new file system threads, and the value of host.mntp will become available to them regardless of locking.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it.

fuse/host.go Outdated
@@ -685,10 +698,15 @@ func (host *FileSystemHost) Mount(mountpoint string, opts []string) bool {
defer func() {
<-done
}()
host.Lock()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessary.

The host.sigc variable is read-only after Mount. The Mount method may (implicitly or explicitly) create new file system threads, and the value of host.sigc will become available to them regardless of locking.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it.

@@ -708,6 +726,8 @@ func (host *FileSystemHost) Mount(mountpoint string, opts []string) bool {
// Unmount may be called at any time after the Init() method has been called
// and before the Destroy() method has been called.
func (host *FileSystemHost) Unmount() bool {
host.RLock()
Copy link
Collaborator

@billziss-gh billziss-gh Jan 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The host.fuse variable is modified in hostInit and hostDestroy. The Unmount method is documented as being safe only between Init and Destroy, which means that the file system should provide its own synchronization method to ensure that Unmount is not called at the wrong time.

However I agree that it might be better if Unmount is improved to catch cases where the file system calls it before Init or after Destroy.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I remove the lock here, I get into a race condition when executing go test -race; I had the same problem with my fs and I don't know how to fix it on the side of my fs.

return 0 != c_hostUnmount(host.fuse, mntp)
}

// Notify notifies the operating system about a file change.
// The action is a combination of the fuse.NOTIFY_* constants.
func (host *FileSystemHost) Notify(path string, action uint32) bool {
host.RLock()
Copy link
Collaborator

@billziss-gh billziss-gh Jan 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comments in Unmount apply here as well (especially because I failed to document that is only safe between Init and Destroy).

Copy link
Author

@btwotch btwotch Jan 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In comparison to func Unmount, it doesn't run into a race condition when running go test -race.

@btwotch btwotch force-pushed the filesystemhost_race_conditions branch from 3ee7e5b to 92831e3 Compare January 19, 2021 19:36
remove race conditions as seen with `go test -race` on FileSystemHost
members
@btwotch btwotch force-pushed the filesystemhost_race_conditions branch from 92831e3 to c6e3169 Compare February 27, 2022 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants