Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add config option to ignore signal interrupts. #153

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,17 @@ func (c *Connection) finishOp(

// LOCKS_EXCLUDED(c.mu)
func (c *Connection) handleInterrupt(fuseID uint64) {
// Allow fuse library clients to ignore interupt signals.
// NOTE(bjornleffler): Golang issues lots of SIGURG signals, which are
// interpreted as interuption signals.
// https://github.com/golang/proposal/blob/master/design/24543-non-cooperative-preemption.md
// It would have been preferrable to ignore SIGURG, but I couldn't
// figure out how to do that. From kernel documentation (https://goo.gl/H55Dnr):
// "The userspace filesystem may ignore the INTERRUPT requests entirely"
if c.cfg.IgnoreInterrupts {
return
}

c.mu.Lock()
defer c.mu.Unlock()

Expand Down
62 changes: 62 additions & 0 deletions fuseops/filetype.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package fuseops

import (
"fmt"
)

type Filetype int

const (
NoFiletype Filetype = 0
RegularFiletype = 1
DirectoryFiletype = 2
SymlinkFiletype = 3
)

const (
// Type values used in GCS metadata.
NoFiletypeString = "none"
RegularFiletypeString = "file"
DirectoryFiletypeString = "directory"
SymlinkFiletypeString = "symlink"
)

func ParseFiletype(value string) (Filetype, error) {
switch value {
case NoFiletypeString:
return NoFiletype, nil
case RegularFiletypeString:
return RegularFiletype, nil
case DirectoryFiletypeString:
return DirectoryFiletype, nil
case SymlinkFiletypeString:
return SymlinkFiletype, nil
}
return NoFiletype, fmt.Errorf("Failed to parse file type %s", value)
}

func (filetype Filetype) String() string {
switch filetype {
case RegularFiletype:
return RegularFiletypeString
case DirectoryFiletype:
return DirectoryFiletypeString
case SymlinkFiletype:
return SymlinkFiletypeString
}
return NoFiletypeString
}
9 changes: 9 additions & 0 deletions fuseops/ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,15 @@ type ReadDirOp struct {
OpContext OpContext
}

// Read all entries from a directory.
type ListDirOp struct {
// The directory inode that we are reading.
Inode InodeID

// All entries from the directory listing.
Entries []Dirent
}

// Release a previously-minted directory handle. The kernel sends this when
// there are no more references to an open directory: all file descriptors are
// closed and all memory mappings are unmapped.
Expand Down
34 changes: 34 additions & 0 deletions fuseops/simple_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package fuseops
import (
"fmt"
"os"
"syscall"
"time"

"github.com/jacobsa/fuse/internal/fusekernel"
Expand Down Expand Up @@ -59,6 +60,7 @@ func init() {
// InodeAttributes contains attributes for a file or directory inode. It
// corresponds to struct inode (cf. http://goo.gl/tvYyQt).
type InodeAttributes struct {
Type Filetype
Size uint64

// The number of incoming hard links to this inode.
Expand Down Expand Up @@ -222,3 +224,35 @@ type ChildInodeEntry struct {
// default. See notes on MountConfig.EnableVnodeCaching for more.
EntryExpiration time.Time
}

type DirentType uint32

const (
DT_Unknown DirentType = 0
DT_Socket DirentType = syscall.DT_SOCK
DT_Link DirentType = syscall.DT_LNK
DT_File DirentType = syscall.DT_REG
DT_Block DirentType = syscall.DT_BLK
DT_Directory DirentType = syscall.DT_DIR
DT_Char DirentType = syscall.DT_CHR
DT_FIFO DirentType = syscall.DT_FIFO
)

// A struct representing an entry within a directory file, describing a child.
// See notes on ReadDirOp and on WriteDirent for details.
type Dirent struct {
// The (opaque) offset within the directory file of the entry following this
// one. See notes on ReadDirOp.Offset for details.
Offset DirOffset

// The inode of the child file or directory, and its name within the parent.
Inode InodeID
Name string

// The type of the child. The zero value (DT_Unknown) is legal, but means
// that the kernel will need to call GetAttr when the type is needed.
Type DirentType

// Inode attributes for the entry.
Attributes InodeAttributes
}
32 changes: 1 addition & 31 deletions fuseutil/dirent.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,15 @@
package fuseutil

import (
"syscall"
"unsafe"

"github.com/jacobsa/fuse/fuseops"
)

type DirentType uint32

const (
DT_Unknown DirentType = 0
DT_Socket DirentType = syscall.DT_SOCK
DT_Link DirentType = syscall.DT_LNK
DT_File DirentType = syscall.DT_REG
DT_Block DirentType = syscall.DT_BLK
DT_Directory DirentType = syscall.DT_DIR
DT_Char DirentType = syscall.DT_CHR
DT_FIFO DirentType = syscall.DT_FIFO
)

// A struct representing an entry within a directory file, describing a child.
// See notes on fuseops.ReadDirOp and on WriteDirent for details.
type Dirent struct {
// The (opaque) offset within the directory file of the entry following this
// one. See notes on fuseops.ReadDirOp.Offset for details.
Offset fuseops.DirOffset

// The inode of the child file or directory, and its name within the parent.
Inode fuseops.InodeID
Name string

// The type of the child. The zero value (DT_Unknown) is legal, but means
// that the kernel will need to call GetAttr when the type is needed.
Type DirentType
}

// Write the supplied directory entry into the given buffer in the format
// expected in fuseops.ReadFileOp.Data, returning the number of bytes written.
// Return zero if the entry would not fit.
func WriteDirent(buf []byte, d Dirent) (n int) {
func WriteDirent(buf []byte, d fuseops.Dirent) (n int) {
// We want to write bytes with the layout of fuse_dirent
// (http://goo.gl/BmFxob) in host order. The struct must be aligned according
// to FUSE_DIRENT_ALIGN (http://goo.gl/UziWvH), which dictates 8-byte
Expand Down
1 change: 1 addition & 0 deletions fuseutil/file_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ type FileSystem interface {
OpenDir(context.Context, *fuseops.OpenDirOp) error
ReadDir(context.Context, *fuseops.ReadDirOp) error
ReleaseDirHandle(context.Context, *fuseops.ReleaseDirHandleOp) error
ListDir(context.Context, *fuseops.ListDirOp) error
OpenFile(context.Context, *fuseops.OpenFileOp) error
ReadFile(context.Context, *fuseops.ReadFileOp) error
WriteFile(context.Context, *fuseops.WriteFileOp) error
Expand Down
6 changes: 6 additions & 0 deletions fuseutil/not_implemented_file_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ func (fs *NotImplementedFileSystem) ReleaseDirHandle(
return fuse.ENOSYS
}

func (fs *NotImplementedFileSystem) ListDir(
ctx context.Context,
op *fuseops.ListDirOp) error {
return fuse.ENOSYS
}

func (fs *NotImplementedFileSystem) OpenFile(
ctx context.Context,
op *fuseops.OpenFileOp) error {
Expand Down
3 changes: 3 additions & 0 deletions mount_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ type MountConfig struct {
// Flag to enable async reads that are received from
// the kernel
EnableAsyncReads bool

// Flag to allow fuse library clients to ignore interrupts.
IgnoreInterrupts bool
}

// Create a map containing all of the key=value mount options to be given to
Expand Down