aboutsummaryrefslogtreecommitdiff
path: root/pathfs_frontend
diff options
context:
space:
mode:
authorJakob Unterwurzacher2015-11-01 12:11:36 +0100
committerJakob Unterwurzacher2015-11-01 12:11:36 +0100
commit902babdf22199d73171716e643f1ffbb65e6fb48 (patch)
treec3194bce9fd9b4db0a569fca3b5041abd278be70 /pathfs_frontend
parent14276c96328a1a1ad2b354c65d8db7fa720559e1 (diff)
Refactor ciphertext <-> plaintext offset translation functions
Move all the intelligence into the new file address_translation.go. That the calculations were spread out too much became apparent when adding the file header. This should make the code much easier to modify in the future.
Diffstat (limited to 'pathfs_frontend')
-rw-r--r--pathfs_frontend/file.go50
-rw-r--r--pathfs_frontend/file_holes.go4
-rw-r--r--pathfs_frontend/fs.go2
3 files changed, 27 insertions, 29 deletions
diff --git a/pathfs_frontend/file.go b/pathfs_frontend/file.go
index 438fe77..e8d7003 100644
--- a/pathfs_frontend/file.go
+++ b/pathfs_frontend/file.go
@@ -128,8 +128,10 @@ func (f *file) doRead(off uint64, length uint64) ([]byte, fuse.Status) {
}
// Read the backing ciphertext in one go
- alignedOffset, alignedLength, skip := f.cfs.CiphertextRange(off, length)
- cryptfs.Debug.Printf("CiphertextRange(%d, %d) -> %d, %d, %d\n", off, length, alignedOffset, alignedLength, skip)
+ blocks := f.cfs.ExplodePlainRange(off, length)
+ alignedOffset, alignedLength := blocks[0].JointCiphertextRange(blocks)
+ skip := blocks[0].Skip
+ cryptfs.Debug.Printf("JointCiphertextRange(%d, %d) -> %d, %d, %d\n", off, length, alignedOffset, alignedLength, skip)
ciphertext := make([]byte, int(alignedLength))
f.fdLock.Lock()
n, err := f.fd.ReadAt(ciphertext, int64(alignedOffset))
@@ -141,27 +143,27 @@ func (f *file) doRead(off uint64, length uint64) ([]byte, fuse.Status) {
// Truncate ciphertext buffer down to actually read bytes
ciphertext = ciphertext[0:n]
- blockNo := (alignedOffset - cryptfs.HEADER_LEN) / f.cfs.CipherBS()
- cryptfs.Debug.Printf("ReadAt offset=%d bytes (%d blocks), want=%d, got=%d\n", alignedOffset, blockNo, alignedLength, n)
+ firstBlockNo := blocks[0].BlockNo
+ cryptfs.Debug.Printf("ReadAt offset=%d bytes (%d blocks), want=%d, got=%d\n", alignedOffset, firstBlockNo, alignedLength, n)
// Decrypt it
- plaintext, err := f.cfs.DecryptBlocks(ciphertext, blockNo, f.header.Id)
+ plaintext, err := f.cfs.DecryptBlocks(ciphertext, firstBlockNo, f.header.Id)
if err != nil {
- blockNo := (alignedOffset + uint64(len(plaintext))) / f.cfs.PlainBS()
- cipherOff := cryptfs.HEADER_LEN + blockNo * f.cfs.CipherBS()
- plainOff := blockNo * f.cfs.PlainBS()
- cryptfs.Warn.Printf("ino%d: doRead: corrupt block #%d (plainOff=%d/%d, cipherOff=%d/%d)\n",
- f.ino, blockNo, plainOff, f.cfs.PlainBS(), cipherOff, f.cfs.CipherBS())
+ curruptBlockNo := firstBlockNo + f.cfs.PlainOffToBlockNo(uint64(len(plaintext)))
+ cipherOff := f.cfs.BlockNoToCipherOff(curruptBlockNo)
+ plainOff := f.cfs.BlockNoToPlainOff(curruptBlockNo)
+ cryptfs.Warn.Printf("ino%d: doRead: corrupt block #%d (plainOff=%d, cipherOff=%d)\n",
+ f.ino, curruptBlockNo, plainOff, cipherOff)
return nil, fuse.EIO
}
// Crop down to the relevant part
var out []byte
lenHave := len(plaintext)
- lenWant := skip + int(length)
+ lenWant := int(skip + length)
if lenHave > lenWant {
- out = plaintext[skip : skip+int(length)]
- } else if lenHave > skip {
+ out = plaintext[skip:lenWant]
+ } else if lenHave > int(skip) {
out = plaintext[skip:lenHave]
}
// else: out stays empty, file was smaller than the requested offset
@@ -216,7 +218,7 @@ func (f *file) doWrite(data []byte, off int64) (uint32, fuse.Status) {
var written uint32
status := fuse.OK
dataBuf := bytes.NewBuffer(data)
- blocks := f.cfs.SplitRange(uint64(off), uint64(len(data)))
+ blocks := f.cfs.ExplodePlainRange(uint64(off), uint64(len(data)))
for _, b := range blocks {
blockData := dataBuf.Next(int(b.Length))
@@ -239,11 +241,7 @@ func (f *file) doWrite(data []byte, off int64) (uint32, fuse.Status) {
blockOffset, _ := b.CiphertextRange()
blockData = f.cfs.EncryptBlock(blockData, b.BlockNo, f.header.Id)
cryptfs.Debug.Printf("ino%d: Writing %d bytes to block #%d, md5=%s\n",
- f.ino, len(blockData) - cryptfs.BLOCK_OVERHEAD, b.BlockNo, cryptfs.Debug.Md5sum(blockData))
- if len(blockData) != int(f.cfs.CipherBS()) {
- cryptfs.Debug.Printf("ino%d: Writing partial block #%d (%d bytes)\n",
- f.ino, b.BlockNo, len(blockData) - cryptfs.BLOCK_OVERHEAD)
- }
+ f.ino, len(blockData)-cryptfs.BLOCK_OVERHEAD, b.BlockNo, cryptfs.Debug.Md5sum(blockData))
f.fdLock.Lock()
_, err := f.fd.WriteAt(blockData, int64(blockOffset))
f.fdLock.Unlock()
@@ -267,7 +265,7 @@ func (f *file) Write(data []byte, off int64) (uint32, fuse.Status) {
cryptfs.Warn.Printf("Write: Fstat failed: %v\n", err)
return 0, fuse.ToStatus(err)
}
- plainSize := f.cfs.PlainSize(uint64(fi.Size()))
+ plainSize := f.cfs.CipherSizeToPlainSize(uint64(fi.Size()))
if f.createsHole(plainSize, off) {
status := f.zeroPad(plainSize)
if status != fuse.OK {
@@ -332,7 +330,7 @@ func (f *file) Truncate(newSize uint64) fuse.Status {
cryptfs.Warn.Printf("Truncate: Fstat failed: %v\n", err)
return fuse.ToStatus(err)
}
- oldSize := f.cfs.PlainSize(uint64(fi.Size()))
+ oldSize := f.cfs.CipherSizeToPlainSize(uint64(fi.Size()))
{
oldB := float32(oldSize) / float32(f.cfs.PlainBS())
newB := float32(newSize) / float32(f.cfs.PlainBS())
@@ -350,7 +348,7 @@ func (f *file) Truncate(newSize uint64) fuse.Status {
}
}
- blocks := f.cfs.SplitRange(oldSize, newSize-oldSize)
+ blocks := f.cfs.ExplodePlainRange(oldSize, newSize-oldSize)
for _, b := range blocks {
// First and last block may be partial
if b.IsPartial() {
@@ -374,9 +372,9 @@ func (f *file) Truncate(newSize uint64) fuse.Status {
return fuse.OK
} else {
// File shrinks
- blockNo := f.cfs.BlockNoPlainOff(newSize)
- cipherOff := cryptfs.HEADER_LEN + blockNo * f.cfs.CipherBS()
- plainOff := blockNo * f.cfs.PlainBS()
+ blockNo := f.cfs.PlainOffToBlockNo(newSize)
+ cipherOff := f.cfs.BlockNoToCipherOff(blockNo)
+ plainOff := f.cfs.BlockNoToPlainOff(blockNo)
lastBlockLen := newSize - plainOff
var data []byte
if lastBlockLen > 0 {
@@ -430,7 +428,7 @@ func (f *file) GetAttr(a *fuse.Attr) fuse.Status {
return fuse.ToStatus(err)
}
a.FromStat(&st)
- a.Size = f.cfs.PlainSize(a.Size)
+ a.Size = f.cfs.CipherSizeToPlainSize(a.Size)
return fuse.OK
}
diff --git a/pathfs_frontend/file_holes.go b/pathfs_frontend/file_holes.go
index f906aa6..3db4828 100644
--- a/pathfs_frontend/file_holes.go
+++ b/pathfs_frontend/file_holes.go
@@ -7,8 +7,8 @@ import (
// Will a write to offset "off" create a file hole?
func (f *file) createsHole(plainSize uint64, off int64) bool {
- nextBlock := f.cfs.BlockNoPlainOff(plainSize)
- targetBlock := f.cfs.BlockNoPlainOff(uint64(off))
+ nextBlock := f.cfs.PlainOffToBlockNo(plainSize)
+ targetBlock := f.cfs.PlainOffToBlockNo(uint64(off))
if targetBlock > nextBlock {
return true
}
diff --git a/pathfs_frontend/fs.go b/pathfs_frontend/fs.go
index eebc87b..3ec503f 100644
--- a/pathfs_frontend/fs.go
+++ b/pathfs_frontend/fs.go
@@ -41,7 +41,7 @@ func (fs *FS) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Stat
return a, status
}
if a.IsRegular() {
- a.Size = fs.PlainSize(a.Size)
+ a.Size = fs.CipherSizeToPlainSize(a.Size)
} else if a.IsSymlink() {
target, _ := fs.Readlink(name, context)
a.Size = uint64(len(target))