Add pathfs frontend, part II

Fix issues in read and write paths.
Now passes selftest.
This commit is contained in:
Jakob Unterwurzacher 2015-09-08 21:35:06 +02:00
parent 889ae90081
commit caaad7c8d7
2 changed files with 33 additions and 20 deletions

View File

@ -15,5 +15,5 @@ func (l logChannel) Printf(format string, args ...interface{}) {
} }
var Debug = logChannel{true} var Debug = logChannel{false}
var Warn = logChannel{true} var Warn = logChannel{true}

View File

@ -51,44 +51,58 @@ func (f *file) String() string {
return fmt.Sprintf("cryptFile(%s)", f.fd.Name()) return fmt.Sprintf("cryptFile(%s)", f.fd.Name())
} }
// Read - FUSE call // Called by Read() and for RMW in Write()
func (f *file) Read(buf []byte, off int64) (resultData fuse.ReadResult, code fuse.Status) { func (f *file) doRead(off uint64, length uint64) ([]byte, fuse.Status) {
cryptfs.Debug.Printf("\n\nGot read request: len=%d off=%d\n", len(buf), off)
if f.writeOnly {
return nil, fuse.EBADF
}
// Read the backing ciphertext in one go // Read the backing ciphertext in one go
alignedOffset, alignedLength, skip := f.cfs.CiphertextRange(uint64(off), uint64(len(buf))) alignedOffset, alignedLength, skip := f.cfs.CiphertextRange(off, length)
ciphertext := make([]byte, int(alignedLength)) ciphertext := make([]byte, int(alignedLength))
_, err := f.fd.ReadAt(ciphertext, int64(alignedOffset)) n, err := f.fd.ReadAt(ciphertext, int64(alignedOffset))
ciphertext = ciphertext[0:n]
cryptfs.Debug.Printf("ReadAt length=%d offset=%d -> n=%d len=%d\n", alignedLength, alignedOffset, n, len(ciphertext))
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
cryptfs.Warn.Printf("Read error: %s\n", err.Error()) cryptfs.Warn.Printf("read: ReadAt: %s\n", err.Error())
return nil, fuse.ToStatus(err) return nil, fuse.ToStatus(err)
} }
// Decrypt it // Decrypt it
plaintext, err := f.cfs.DecryptBlocks(ciphertext) plaintext, err := f.cfs.DecryptBlocks(ciphertext)
if err != nil { if err != nil {
cryptfs.Warn.Printf("Decryption error: %s\n", err.Error()) cryptfs.Warn.Printf("read: DecryptBlocks: %s\n", err.Error())
return nil, fuse.EIO return nil, fuse.EIO
} }
// Crop down to the relevant part // Crop down to the relevant part
var out []byte var out []byte
lenHave := len(plaintext) lenHave := len(plaintext)
lenWant := skip + len(buf) lenWant := skip + int(length)
if lenHave > lenWant { if lenHave > lenWant {
out = plaintext[skip:skip + len(buf)] out = plaintext[skip:skip + int(length)]
} else if lenHave > skip { } else if lenHave > skip {
out = plaintext[skip:lenHave] out = plaintext[skip:lenHave]
} else {
// Out stays empty, file was smaller than the requested offset
} }
// else: out stays empty
fmt.Printf("Read: returning %d bytes\n", len(plaintext)) return out, fuse.OK
}
return fuse.ReadResultData(out), fuse.OK // Read - FUSE call
func (f *file) Read(buf []byte, off int64) (resultData fuse.ReadResult, code fuse.Status) {
cryptfs.Debug.Printf("\n\nGot read request: len=%d off=%d\n", len(buf), off)
if f.writeOnly {
cryptfs.Warn.Printf("Tried to read from write-only file\n")
return nil, fuse.EBADF
}
out, status := f.doRead(uint64(off), uint64(len(buf)))
if status != fuse.OK {
return nil, status
}
cryptfs.Debug.Printf("Read: returning %d bytes\n", len(out))
return fuse.ReadResultData(out), status
} }
// Write - FUSE call // Write - FUSE call
@ -104,11 +118,10 @@ func (f *file) Write(data []byte, off int64) (uint32, fuse.Status) {
// Incomplete block -> Read-Modify-Write // Incomplete block -> Read-Modify-Write
if b.IsPartial() { if b.IsPartial() {
// Read // Read
oldData := make([]byte, f.cfs.PlainBS())
o, _ := b.PlaintextRange() o, _ := b.PlaintextRange()
res, status := f.Read(oldData, int64(o)) oldData, status := f.doRead(f.cfs.PlainBS(), o)
oldData, _ = res.Bytes(oldData)
if status != fuse.OK { if status != fuse.OK {
cryptfs.Warn.Printf("RMW read failed: %s\n", status.String())
return written, status return written, status
} }
// Modify // Modify