summaryrefslogtreecommitdiff
path: root/internal/fusefrontend/file_allocate_truncate.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2018-07-22 22:29:22 +0200
committerJakob Unterwurzacher2018-07-22 22:29:22 +0200
commitf316f1b2df47dca651174e574ab072f6b46c0b01 (patch)
tree16176cb053718ba6b2815d08df44040f75d3fdae /internal/fusefrontend/file_allocate_truncate.go
parentc70df522d2a78f3152fa61511bed9fafa7c495a3 (diff)
fusefronted: disallow writes running concurrently with reads
As uncovered by xfstests generic/465, concurrent reads and writes could lead to this, doRead 3015532: corrupt block #1039: stupidgcm: message authentication failed, as the read could pick up a block that has not yet been completely written - write() is not atomic! Now writes take ContentLock exclusively, while reads take it shared, meaning that multiple reads can run in parallel with each other, but not with a write. This also simplifies the file header locking.
Diffstat (limited to 'internal/fusefrontend/file_allocate_truncate.go')
-rw-r--r--internal/fusefrontend/file_allocate_truncate.go6
1 files changed, 1 insertions, 5 deletions
diff --git a/internal/fusefrontend/file_allocate_truncate.go b/internal/fusefrontend/file_allocate_truncate.go
index 81ac8d3..34fe2c0 100644
--- a/internal/fusefrontend/file_allocate_truncate.go
+++ b/internal/fusefrontend/file_allocate_truncate.go
@@ -111,9 +111,7 @@ func (f *File) Truncate(newSize uint64) fuse.Status {
return fuse.ToStatus(err)
}
// Truncate to zero kills the file header
- f.fileTableEntry.HeaderLock.Lock()
f.fileTableEntry.ID = nil
- f.fileTableEntry.HeaderLock.Unlock()
return fuse.OK
}
// We need the old file size to determine if we are growing or shrinking
@@ -144,7 +142,7 @@ func (f *File) Truncate(newSize uint64) fuse.Status {
var data []byte
if lastBlockLen > 0 {
var status fuse.Status
- data, status = f.doRead(nil, plainOff, lastBlockLen, false)
+ data, status = f.doRead(nil, plainOff, lastBlockLen)
if status != fuse.OK {
tlog.Warn.Printf("Truncate: shrink doRead returned error: %v", err)
return status
@@ -206,8 +204,6 @@ func (f *File) truncateGrowFile(oldPlainSz uint64, newPlainSz uint64) fuse.Statu
if newPlainSz%f.contentEnc.PlainBS() == 0 {
// The file was empty, so it did not have a header. Create one.
if oldPlainSz == 0 {
- f.fileTableEntry.HeaderLock.Lock()
- defer f.fileTableEntry.HeaderLock.Unlock()
id, err := f.createHeader()
if err != nil {
return fuse.ToStatus(err)