diff options
author | Jakob Unterwurzacher | 2015-11-01 12:11:36 +0100 |
---|---|---|
committer | Jakob Unterwurzacher | 2015-11-01 12:11:36 +0100 |
commit | 902babdf22199d73171716e643f1ffbb65e6fb48 (patch) | |
tree | c3194bce9fd9b4db0a569fca3b5041abd278be70 /pathfs_frontend/file.go | |
parent | 14276c96328a1a1ad2b354c65d8db7fa720559e1 (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/file.go')
-rw-r--r-- | pathfs_frontend/file.go | 50 |
1 files changed, 24 insertions, 26 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 } |