aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/fusefrontend/file.go12
1 files changed, 4 insertions, 8 deletions
diff --git a/internal/fusefrontend/file.go b/internal/fusefrontend/file.go
index bad9bfc..1ae3386 100644
--- a/internal/fusefrontend/file.go
+++ b/internal/fusefrontend/file.go
@@ -266,13 +266,13 @@ func (f *File) Read(buf []byte, off int64) (resultData fuse.ReadResult, code fus
//
// Empty writes do nothing and are allowed.
func (f *File) doWrite(data []byte, off int64) (uint32, fuse.Status) {
- // Read header from disk, create a new one if the file is empty
- f.fileTableEntry.HeaderLock.RLock()
+ // If the file ID is not cached, read it from disk
if f.fileTableEntry.ID == nil {
- f.fileTableEntry.HeaderLock.RUnlock()
- // Somebody else may write the header here, but this would do no harm.
+ // Block other readers while we mess with the file header. Other writers
+ // are blocked by ContentLock already.
f.fileTableEntry.HeaderLock.Lock()
tmpID, err := f.readFileID()
+ // Write a new file header if the file is empty
if err == io.EOF {
tmpID, err = f.createHeader()
}
@@ -282,11 +282,7 @@ func (f *File) doWrite(data []byte, off int64) (uint32, fuse.Status) {
}
f.fileTableEntry.ID = tmpID
f.fileTableEntry.HeaderLock.Unlock()
- // The file ID may change in here. This does no harm because we
- // re-read it after the RLock().
- f.fileTableEntry.HeaderLock.RLock()
}
- defer f.fileTableEntry.HeaderLock.RUnlock()
// Handle payload data
dataBuf := bytes.NewBuffer(data)
blocks := f.contentEnc.ExplodePlainRange(uint64(off), uint64(len(data)))