Zero-pad last block if a file hole is created on Write()
Fixes TestFileHoles test
This commit is contained in:
parent
5229b8f5f5
commit
2003ca965d
@ -113,7 +113,7 @@ func (f *file) doRead(off uint64, length uint64) ([]byte, fuse.Status) {
|
||||
|
||||
// Read - FUSE call
|
||||
func (f *file) Read(buf []byte, off int64) (resultData fuse.ReadResult, code fuse.Status) {
|
||||
cryptfs.Debug.Printf("ino%d: Read: offset=%d length=%d\n", f.ino, len(buf), off)
|
||||
cryptfs.Debug.Printf("ino%d: FUSE Read: offset=%d length=%d\n", f.ino, len(buf), off)
|
||||
|
||||
if f.writeOnly {
|
||||
cryptfs.Warn.Printf("ino%d: Tried to read from write-only file\n", f.ino)
|
||||
@ -133,10 +133,8 @@ func (f *file) Read(buf []byte, off int64) (resultData fuse.ReadResult, code fus
|
||||
return fuse.ReadResultData(out), status
|
||||
}
|
||||
|
||||
// Write - FUSE call
|
||||
func (f *file) Write(data []byte, off int64) (uint32, fuse.Status) {
|
||||
cryptfs.Debug.Printf("ino%d: Write %s: offset=%d length=%d\n", f.ino, off, len(data))
|
||||
|
||||
// Do the actual write
|
||||
func (f *file) doWrite(data []byte, off int64) (uint32, fuse.Status) {
|
||||
var written uint32
|
||||
status := fuse.OK
|
||||
dataBuf := bytes.NewBuffer(data)
|
||||
@ -177,10 +175,16 @@ func (f *file) Write(data []byte, off int64) (uint32, fuse.Status) {
|
||||
}
|
||||
written += uint32(b.Length)
|
||||
}
|
||||
|
||||
return written, status
|
||||
}
|
||||
|
||||
// Write - FUSE call
|
||||
func (f *file) Write(data []byte, off int64) (uint32, fuse.Status) {
|
||||
cryptfs.Debug.Printf("ino%d: FUSE Write %s: offset=%d length=%d\n", f.ino, off, len(data))
|
||||
f.conditionalZeroPad(off)
|
||||
return f.doWrite(data, off)
|
||||
}
|
||||
|
||||
// Release - FUSE call, forget file
|
||||
func (f *file) Release() {
|
||||
f.lock.Lock()
|
||||
|
38
pathfs_frontend/file_holes.go
Normal file
38
pathfs_frontend/file_holes.go
Normal file
@ -0,0 +1,38 @@
|
||||
package pathfs_frontend
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hanwen/go-fuse/fuse"
|
||||
"github.com/rfjakob/gocryptfs/cryptfs"
|
||||
)
|
||||
|
||||
// Will a write to offset "off" create a file hole?
|
||||
func (f *file) createsHole(cipherSize uint64, off int64) bool {
|
||||
nextBlock := f.cfs.BlockNoCipherOff(cipherSize)
|
||||
targetBlock := f.cfs.BlockNoPlainOff(uint64(off))
|
||||
if targetBlock > nextBlock {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Zero-pad the file if a write to "off" creates a file hole
|
||||
func (f *file) conditionalZeroPad(off int64) fuse.Status {
|
||||
fi, err := f.fd.Stat()
|
||||
if err != nil {
|
||||
cryptfs.Warn.Printf("conditionalZeroPad: Stat: %v\n", err)
|
||||
return fuse.ToStatus(err)
|
||||
}
|
||||
cipherSize := uint64(fi.Size())
|
||||
|
||||
if f.createsHole(cipherSize, off) == false {
|
||||
return fuse.OK
|
||||
}
|
||||
|
||||
plainSize := f.cfs.PlainSize(cipherSize)
|
||||
lastBlockLen := plainSize % f.cfs.PlainBS()
|
||||
missing := f.cfs.PlainBS() - lastBlockLen
|
||||
pad := make([]byte, missing)
|
||||
_, status := f.doWrite(pad, int64(plainSize))
|
||||
return status
|
||||
}
|
Loading…
Reference in New Issue
Block a user