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/fusefrontend')

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