diff --git a/internal/fusefrontend/file2.go b/internal/fusefrontend/file.go similarity index 92% rename from internal/fusefrontend/file2.go rename to internal/fusefrontend/file.go index 0de325c..66b3e24 100644 --- a/internal/fusefrontend/file2.go +++ b/internal/fusefrontend/file.go @@ -25,8 +25,8 @@ import ( "github.com/rfjakob/gocryptfs/internal/tlog" ) -// File2 implements the go-fuse v2 API (github.com/hanwen/go-fuse/v2/fs) -type File2 struct { +// File implements the go-fuse v2 API (github.com/hanwen/go-fuse/v2/fs) +type File struct { fd *os.File // Has Release() already been called on this file? This also means that the // wlock entry has been freed, so let's not crash trying to access it. @@ -54,11 +54,11 @@ type File2 struct { } // NewFile returns a new go-fuse File instance. -func NewFile2(fd *os.File, rn *RootNode, st *syscall.Stat_t) *File2 { +func NewFile(fd *os.File, rn *RootNode, st *syscall.Stat_t) *File { qi := inomap.QInoFromStat(st) e := openfiletable.Register(qi) - return &File2{ + return &File{ fd: fd, contentEnc: rn.contentEnc, qIno: qi, @@ -68,13 +68,13 @@ func NewFile2(fd *os.File, rn *RootNode, st *syscall.Stat_t) *File2 { } // intFd - return the backing file descriptor as an integer. -func (f *File2) intFd() int { +func (f *File) intFd() int { return int(f.fd.Fd()) } // readFileID loads the file header from disk and extracts the file ID. // Returns io.EOF if the file is empty. -func (f *File2) readFileID() ([]byte, error) { +func (f *File) readFileID() ([]byte, error) { // We read +1 byte to determine if the file has actual content // and not only the header. A header-only file will be considered empty. // This makes File ID poisoning more difficult. @@ -100,7 +100,7 @@ func (f *File2) readFileID() ([]byte, error) { // createHeader creates a new random header and writes it to disk. // Returns the new file ID. // The caller must hold fileIDLock.Lock(). -func (f *File2) createHeader() (fileID []byte, err error) { +func (f *File) createHeader() (fileID []byte, err error) { h := contentenc.RandomHeader() buf := h.Pack() // Prevent partially written (=corrupt) header by preallocating the space beforehand @@ -130,7 +130,7 @@ func (f *File2) createHeader() (fileID []byte, err error) { // // Called by Read() for normal reading, // by Write() and Truncate() via doWrite() for Read-Modify-Write. -func (f *File2) doRead(dst []byte, off uint64, length uint64) ([]byte, syscall.Errno) { +func (f *File) doRead(dst []byte, off uint64, length uint64) ([]byte, syscall.Errno) { // Get the file ID, either from the open file table, or from disk. var fileID []byte f.fileTableEntry.IDLock.Lock() @@ -221,7 +221,7 @@ func (f *File2) doRead(dst []byte, off uint64, length uint64) ([]byte, syscall.E } // Read - FUSE call -func (f *File2) Read(ctx context.Context, buf []byte, off int64) (resultData fuse.ReadResult, errno syscall.Errno) { +func (f *File) Read(ctx context.Context, buf []byte, off int64) (resultData fuse.ReadResult, errno syscall.Errno) { if len(buf) > fuse.MAX_KERNEL_WRITE { // This would crash us due to our fixed-size buffer pool tlog.Warn.Printf("Read: rejecting oversized request with EMSGSIZE, len=%d", len(buf)) @@ -257,7 +257,7 @@ func (f *File2) Read(ctx context.Context, buf []byte, off int64) (resultData fus // and by Truncate() to rewrite the last file block. // // Empty writes do nothing and are allowed. -func (f *File2) doWrite(data []byte, off int64) (uint32, syscall.Errno) { +func (f *File) doWrite(data []byte, off int64) (uint32, syscall.Errno) { fileWasEmpty := false // Get the file ID, create a new one if it does not exist yet. var fileID []byte @@ -342,7 +342,7 @@ func (f *File2) doWrite(data []byte, off int64) (uint32, syscall.Errno) { // This is an optimisation for streaming writes on NFS where a // Stat() call is very expensive. // The caller must "wlock.lock(f.devIno.ino)" otherwise this check would be racy. -func (f *File2) isConsecutiveWrite(off int64) bool { +func (f *File) isConsecutiveWrite(off int64) bool { opCount := openfiletable.WriteOpCount() return opCount == f.lastOpCount+1 && off == f.lastWrittenOffset+1 } @@ -350,7 +350,7 @@ func (f *File2) isConsecutiveWrite(off int64) bool { // Write - FUSE call // // If the write creates a hole, pads the file to the next block boundary. -func (f *File2) Write(ctx context.Context, data []byte, off int64) (uint32, syscall.Errno) { +func (f *File) Write(ctx context.Context, data []byte, off int64) (uint32, syscall.Errno) { if len(data) > fuse.MAX_KERNEL_WRITE { // This would crash us due to our fixed-size buffer pool tlog.Warn.Printf("Write: rejecting oversized request with EMSGSIZE, len=%d", len(data)) @@ -384,7 +384,7 @@ func (f *File2) Write(ctx context.Context, data []byte, off int64) (uint32, sysc } // Release - FUSE call, close file -func (f *File2) Release(ctx context.Context) syscall.Errno { +func (f *File) Release(ctx context.Context) syscall.Errno { f.fdLock.Lock() if f.released { log.Panicf("ino%d fh%d: double release", f.qIno.Ino, f.intFd()) @@ -397,7 +397,7 @@ func (f *File2) Release(ctx context.Context) syscall.Errno { } // Flush - FUSE call -func (f *File2) Flush(ctx context.Context) syscall.Errno { +func (f *File) Flush(ctx context.Context) syscall.Errno { f.fdLock.RLock() defer f.fdLock.RUnlock() @@ -414,7 +414,7 @@ func (f *File2) Flush(ctx context.Context) syscall.Errno { } // Fsync FUSE call -func (f *File2) Fsync(ctx context.Context, flags uint32) (errno syscall.Errno) { +func (f *File) Fsync(ctx context.Context, flags uint32) (errno syscall.Errno) { f.fdLock.RLock() defer f.fdLock.RUnlock() @@ -422,7 +422,7 @@ func (f *File2) Fsync(ctx context.Context, flags uint32) (errno syscall.Errno) { } // Getattr FUSE call (like stat) -func (f *File2) Getattr(ctx context.Context, a *fuse.AttrOut) syscall.Errno { +func (f *File) Getattr(ctx context.Context, a *fuse.AttrOut) syscall.Errno { f.fdLock.RLock() defer f.fdLock.RUnlock() diff --git a/internal/fusefrontend/file2_api_check.go b/internal/fusefrontend/file2_api_check.go deleted file mode 100644 index 01f9a46..0000000 --- a/internal/fusefrontend/file2_api_check.go +++ /dev/null @@ -1,23 +0,0 @@ -package fusefrontend - -import ( - "github.com/hanwen/go-fuse/v2/fs" -) - -// Check that we have implemented the fs.File* interfaces -var _ = (fs.FileGetattrer)((*File2)(nil)) -var _ = (fs.FileSetattrer)((*File2)(nil)) -var _ = (fs.FileReleaser)((*File2)(nil)) -var _ = (fs.FileReader)((*File2)(nil)) -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)) -*/ diff --git a/internal/fusefrontend/file2_allocate_truncate.go b/internal/fusefrontend/file_allocate_truncate.go similarity index 95% rename from internal/fusefrontend/file2_allocate_truncate.go rename to internal/fusefrontend/file_allocate_truncate.go index cdda974..f4e6099 100644 --- a/internal/fusefrontend/file2_allocate_truncate.go +++ b/internal/fusefrontend/file_allocate_truncate.go @@ -37,7 +37,7 @@ var allocateWarnOnce sync.Once // complicated and hard to get right. // // Other modes (hole punching, zeroing) are not supported. -func (f *File2) Allocate(ctx context.Context, off uint64, sz uint64, mode uint32) syscall.Errno { +func (f *File) Allocate(ctx context.Context, off uint64, sz uint64, mode uint32) syscall.Errno { if mode != FALLOC_DEFAULT && mode != FALLOC_FL_KEEP_SIZE { f := func() { tlog.Info.Printf("fallocate: only mode 0 (default) and 1 (keep size) are supported") @@ -93,7 +93,7 @@ func (f *File2) Allocate(ctx context.Context, off uint64, sz uint64, mode uint32 } // truncate - called from Setattr. -func (f *File2) truncate(newSize uint64) (errno syscall.Errno) { +func (f *File) truncate(newSize uint64) (errno syscall.Errno) { var err error // Common case first: Truncate to zero if newSize == 0 { @@ -154,7 +154,7 @@ func (f *File2) truncate(newSize uint64) (errno syscall.Errno) { } // statPlainSize stats the file and returns the plaintext size -func (f *File2) statPlainSize() (uint64, error) { +func (f *File) statPlainSize() (uint64, error) { fi, err := f.fd.Stat() if err != nil { tlog.Warn.Printf("ino%d fh%d: statPlainSize: %v", f.qIno.Ino, f.intFd(), err) @@ -168,7 +168,7 @@ func (f *File2) statPlainSize() (uint64, error) { // truncateGrowFile extends a file using seeking or ftruncate performing RMW on // the first and last block as necessary. New blocks in the middle become // file holes unless they have been fallocate()'d beforehand. -func (f *File2) truncateGrowFile(oldPlainSz uint64, newPlainSz uint64) syscall.Errno { +func (f *File) truncateGrowFile(oldPlainSz uint64, newPlainSz uint64) syscall.Errno { if newPlainSz <= oldPlainSz { log.Panicf("BUG: newSize=%d <= oldSize=%d", newPlainSz, oldPlainSz) } diff --git a/internal/fusefrontend/file_api_check.go b/internal/fusefrontend/file_api_check.go new file mode 100644 index 0000000..4761a4c --- /dev/null +++ b/internal/fusefrontend/file_api_check.go @@ -0,0 +1,23 @@ +package fusefrontend + +import ( + "github.com/hanwen/go-fuse/v2/fs" +) + +// Check that we have implemented the fs.File* interfaces +var _ = (fs.FileGetattrer)((*File)(nil)) +var _ = (fs.FileSetattrer)((*File)(nil)) +var _ = (fs.FileReleaser)((*File)(nil)) +var _ = (fs.FileReader)((*File)(nil)) +var _ = (fs.FileWriter)((*File)(nil)) +var _ = (fs.FileFsyncer)((*File)(nil)) +var _ = (fs.FileFlusher)((*File)(nil)) +var _ = (fs.FileAllocater)((*File)(nil)) +var _ = (fs.FileLseeker)((*File)(nil)) + +/* TODO +var _ = (fs.FileHandle)((*File)(nil)) +var _ = (fs.FileGetlker)((*File)(nil)) +var _ = (fs.FileSetlker)((*File)(nil)) +var _ = (fs.FileSetlkwer)((*File)(nil)) +*/ diff --git a/internal/fusefrontend/file2_holes.go b/internal/fusefrontend/file_holes.go similarity index 90% rename from internal/fusefrontend/file2_holes.go rename to internal/fusefrontend/file_holes.go index 5c314d3..85792f9 100644 --- a/internal/fusefrontend/file2_holes.go +++ b/internal/fusefrontend/file_holes.go @@ -13,7 +13,7 @@ import ( // Will a write to plaintext offset "targetOff" create a file hole in the // ciphertext? If yes, zero-pad the last ciphertext block. -func (f *File2) writePadHole(targetOff int64) syscall.Errno { +func (f *File) writePadHole(targetOff int64) syscall.Errno { // Get the current file size. fi, err := f.fd.Stat() if err != nil { @@ -43,7 +43,7 @@ func (f *File2) writePadHole(targetOff int64) syscall.Errno { // Zero-pad the file of size plainSize to the next block boundary. This is a no-op // if the file is already block-aligned. -func (f *File2) zeroPad(plainSize uint64) syscall.Errno { +func (f *File) zeroPad(plainSize uint64) syscall.Errno { lastBlockLen := plainSize % f.contentEnc.PlainBS() if lastBlockLen == 0 { // Already block-aligned @@ -57,7 +57,7 @@ func (f *File2) zeroPad(plainSize uint64) syscall.Errno { } // Lseek - FUSE call. -func (f *File2) Lseek(ctx context.Context, off uint64, whence uint32) (uint64, syscall.Errno) { +func (f *File) 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 { diff --git a/internal/fusefrontend/file2_setattr.go b/internal/fusefrontend/file_setattr.go similarity index 87% rename from internal/fusefrontend/file2_setattr.go rename to internal/fusefrontend/file_setattr.go index 1385f3f..0d6dc48 100644 --- a/internal/fusefrontend/file2_setattr.go +++ b/internal/fusefrontend/file_setattr.go @@ -11,7 +11,7 @@ import ( "github.com/rfjakob/gocryptfs/internal/tlog" ) -func (f *File2) Setattr(ctx context.Context, in *fuse.SetAttrIn, out *fuse.AttrOut) (errno syscall.Errno) { +func (f *File) Setattr(ctx context.Context, in *fuse.SetAttrIn, out *fuse.AttrOut) (errno syscall.Errno) { errno = f.setAttr(ctx, in) if errno != 0 { return errno @@ -19,7 +19,7 @@ func (f *File2) Setattr(ctx context.Context, in *fuse.SetAttrIn, out *fuse.AttrO return f.Getattr(ctx, out) } -func (f *File2) setAttr(ctx context.Context, in *fuse.SetAttrIn) (errno syscall.Errno) { +func (f *File) setAttr(ctx context.Context, in *fuse.SetAttrIn) (errno syscall.Errno) { f.fdLock.RLock() defer f.fdLock.RUnlock() if f.released { diff --git a/internal/fusefrontend/node.go b/internal/fusefrontend/node.go index fb38362..00d06f5 100644 --- a/internal/fusefrontend/node.go +++ b/internal/fusefrontend/node.go @@ -133,7 +133,7 @@ func (n *Node) Create(ctx context.Context, name string, flags uint32, mode uint3 ch := n.newChild(ctx, &st, out) f := os.NewFile(uintptr(fd), cName) - return ch, NewFile2(f, rn, &st), 0, 0 + return ch, NewFile(f, rn, &st), 0, 0 } // Unlink - FUSE call. Delete a file. @@ -216,7 +216,7 @@ func (n *Node) Open(ctx context.Context, flags uint32) (fh fs.FileHandle, fuseFl return } f := os.NewFile(uintptr(fd), cName) - fh = NewFile2(f, rn, &st) + fh = NewFile(f, rn, &st) return } @@ -224,7 +224,7 @@ func (n *Node) Open(ctx context.Context, flags uint32) (fh fs.FileHandle, fuseFl func (n *Node) Setattr(ctx context.Context, f fs.FileHandle, in *fuse.SetAttrIn, out *fuse.AttrOut) (errno syscall.Errno) { // Use the fd if the kernel gave us one if f != nil { - f2 := f.(*File2) + f2 := f.(*File) return f2.Setattr(ctx, in, out) } @@ -286,7 +286,7 @@ func (n *Node) Setattr(ctx context.Context, f fs.FileHandle, in *fuse.SetAttrIn, if errno != 0 { return errno } - f2 := f.(*File2) + f2 := f.(*File) defer f2.Release(ctx) errno = syscall.Errno(f2.truncate(sz)) if errno != 0 {