From 9cd24d79a2a5499eefc3403516eba9d9fcbf1079 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Thu, 23 Jul 2020 22:55:07 +0200 Subject: v2api: implement Lseek This also fixes the last remaining tests/fsck failure. --- internal/fusefrontend/file2_api_check.go | 2 +- internal/fusefrontend/file2_holes.go | 40 +++++++------------------------- 2 files changed, 9 insertions(+), 33 deletions(-) (limited to 'internal') diff --git a/internal/fusefrontend/file2_api_check.go b/internal/fusefrontend/file2_api_check.go index 4a6d6a1..01f9a46 100644 --- a/internal/fusefrontend/file2_api_check.go +++ b/internal/fusefrontend/file2_api_check.go @@ -13,11 +13,11 @@ var _ = (fs.FileWriter)((*File2)(nil)) var _ = (fs.FileFsyncer)((*File2)(nil)) var _ = (fs.FileFlusher)((*File2)(nil)) var _ = (fs.FileAllocater)((*File2)(nil)) +var _ = (fs.FileLseeker)((*File2)(nil)) /* TODO var _ = (fs.FileHandle)((*File2)(nil)) var _ = (fs.FileGetlker)((*File2)(nil)) var _ = (fs.FileSetlker)((*File2)(nil)) var _ = (fs.FileSetlkwer)((*File2)(nil)) -var _ = (fs.FileLseeker)((*File2)(nil)) */ diff --git a/internal/fusefrontend/file2_holes.go b/internal/fusefrontend/file2_holes.go index 83918d2..5c314d3 100644 --- a/internal/fusefrontend/file2_holes.go +++ b/internal/fusefrontend/file2_holes.go @@ -3,7 +3,7 @@ package fusefrontend // Helper functions for sparse files (files with holes) import ( - "runtime" + "context" "syscall" "github.com/hanwen/go-fuse/v2/fs" @@ -56,37 +56,13 @@ func (f *File2) zeroPad(plainSize uint64) syscall.Errno { return errno } -// SeekData calls the lseek syscall with SEEK_DATA. It returns the offset of the -// next data bytes, skipping over file holes. -func (f *File2) SeekData(oldOffset int64) (int64, error) { - if runtime.GOOS != "linux" { - // Does MacOS support something like this? - return 0, syscall.EOPNOTSUPP - } - const SEEK_DATA = 3 - - // Convert plaintext offset to ciphertext offset and round down to the - // start of the current block. File holes smaller than a full block will - // be ignored. - blockNo := f.contentEnc.PlainOffToBlockNo(uint64(oldOffset)) - oldCipherOff := int64(f.contentEnc.BlockNoToCipherOff(blockNo)) - - // Determine the next data offset. If the old offset points to (or beyond) - // the end of the file, the Seek syscall fails with syscall.ENXIO. - newCipherOff, err := syscall.Seek(f.intFd(), oldCipherOff, SEEK_DATA) +// Lseek - FUSE call. +func (f *File2) Lseek(ctx context.Context, off uint64, whence uint32) (uint64, syscall.Errno) { + cipherOff := f.rootNode.contentEnc.PlainSizeToCipherSize(off) + newCipherOff, err := syscall.Seek(f.intFd(), int64(cipherOff), int(whence)) if err != nil { - return 0, err + return uint64(newCipherOff), fs.ToErrno(err) } - - // Convert ciphertext offset back to plaintext offset. At this point, - // newCipherOff should always be >= contentenc.HeaderLen. Round down, - // but ensure that the result is never smaller than the initial offset - // (to avoid endless loops). - blockNo = f.contentEnc.CipherOffToBlockNo(uint64(newCipherOff)) - newOffset := int64(f.contentEnc.BlockNoToPlainOff(blockNo)) - if newOffset < oldOffset { - newOffset = oldOffset - } - - return newOffset, nil + newOff := f.contentEnc.CipherSizeToPlainSize(uint64(newCipherOff)) + return newOff, 0 } -- cgit v1.2.3