* The backing map is protected by a RWMutex
* This commit double checks for the existence of the directory inside the write lock to avoid potential data races when multiple goroutines tries to create
the same directory.
Fixes#361Fixes#298
- "/" should have mode `os.ModeDir|0755`, not `0000`. Among other
things, this had resulted in `mode.IsDir()` returning false for root
prior to this patch.
- `Mkdir`, `MkdirAll`, and `OpenFile` shouldn't be allowed to set
permissions that are otherwise illegal through `Chmod`. This mirrors
what Go's `os` package does: it calls `syscallMode(mode)`, which
effectively clears out the same bits that are disallowed by `Chmod`.
- `MkdirAll` should use the given permissions for all intermediate
directories that are created, not just for the final directory. Prior
to this patch, intermediate directories were created with mode bits
`0000`. Besides the permission bits being wrong, `mode.IsDir()` would
return false for these directories prior to this patch.
Fixes a pass-by-value error in FileData.Name() which causes the mutex to be copied, and use that method to retrieve the name of the file from a mem.File. This really fixes the data race that motivated PR #95. (#96)
I can't explain why moving the lock improves the situation, nor why calling through the accessor Name() instead of locking and reading f.fileData.name is not the same, but go vet indicates that the mutex in fileData was being copied, not preserved.
The reproducing test case upstream is:
check out github.com/google/mtail
make install_deps
go test -race -timeout 1m -v -run TestProcessEvents --count=10000 ./vm
Prior to this change, the test reports a data race 3 times out of 10000, after, 0 times consistently.