Add pathfs frontend, part II
Fix issues in read and write paths. Now passes selftest.
This commit is contained in:
parent
889ae90081
commit
caaad7c8d7
@ -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}
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user