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

[PR-2][Phase1 Implementation] Ignore GCSFuse interrupts #1860

Merged
merged 16 commits into from
May 2, 2024
Merged
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require (
github.com/jacobsa/syncutil v0.0.0-20180201203307-228ac8e5a6c3
github.com/jacobsa/timeutil v0.0.0-20170205232429-577e5acbbcf6
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0
github.com/stretchr/testify v1.9.0
github.com/urfave/cli v1.22.14
go.opencensus.io v0.24.0
golang.org/x/net v0.22.0
Expand Down Expand Up @@ -46,6 +47,7 @@ require (
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/envoyproxy/go-control-plane v0.12.0 // indirect
github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
Expand All @@ -61,6 +63,7 @@ require (
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/pkg/xattr v0.4.9 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/prometheus v0.35.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
Expand Down
3 changes: 2 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1076,8 +1076,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
Expand Down
121 changes: 113 additions & 8 deletions internal/fs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package fs

import (
"context"
"errors"
"fmt"
"io"
Expand All @@ -30,7 +31,7 @@ import (
"github.com/googlecloudplatform/gcsfuse/v2/internal/cache/file"
"github.com/googlecloudplatform/gcsfuse/v2/internal/cache/file/downloader"
"github.com/googlecloudplatform/gcsfuse/v2/internal/cache/lru"
"github.com/googlecloudplatform/gcsfuse/v2/internal/cache/util"
cacheutil "github.com/googlecloudplatform/gcsfuse/v2/internal/cache/util"
"github.com/googlecloudplatform/gcsfuse/v2/internal/config"
"github.com/googlecloudplatform/gcsfuse/v2/internal/contentcache"
"github.com/googlecloudplatform/gcsfuse/v2/internal/fs/handle"
Expand All @@ -39,11 +40,11 @@ import (
"github.com/googlecloudplatform/gcsfuse/v2/internal/locker"
"github.com/googlecloudplatform/gcsfuse/v2/internal/logger"
"github.com/googlecloudplatform/gcsfuse/v2/internal/storage/gcs"
"github.com/googlecloudplatform/gcsfuse/v2/internal/util"
"github.com/jacobsa/fuse"
"github.com/jacobsa/fuse/fuseops"
"github.com/jacobsa/fuse/fuseutil"
"github.com/jacobsa/timeutil"
"golang.org/x/net/context"
)

type ServerConfig struct {
Expand Down Expand Up @@ -223,20 +224,20 @@ func createFileCacheHandler(cfg *ServerConfig) (fileCacheHandler *file.CacheHand
if cfg.MountConfig.FileCacheConfig.MaxSizeMB == -1 {
sizeInBytes = math.MaxUint64
} else {
sizeInBytes = uint64(cfg.MountConfig.FileCacheConfig.MaxSizeMB) * util.MiB
sizeInBytes = uint64(cfg.MountConfig.FileCacheConfig.MaxSizeMB) * cacheutil.MiB
}
fileInfoCache := lru.NewCache(sizeInBytes)

cacheDir := string(cfg.MountConfig.CacheDir)
// Adding a new directory inside cacheDir to keep file-cache separate from
// metadata cache if and when we support storing metadata cache on disk in
// the future.
cacheDir = path.Join(cacheDir, util.FileCache)
cacheDir = path.Join(cacheDir, cacheutil.FileCache)

filePerm := util.DefaultFilePerm
dirPerm := util.DefaultDirPerm
filePerm := cacheutil.DefaultFilePerm
dirPerm := cacheutil.DefaultDirPerm

cacheDirErr := util.CreateCacheDirectoryIfNotPresentAt(cacheDir, dirPerm)
cacheDirErr := cacheutil.CreateCacheDirectoryIfNotPresentAt(cacheDir, dirPerm)
if cacheDirErr != nil {
return nil, fmt.Errorf("createFileCacheHandler: while creating file cache directory: %w", cacheDirErr)
}
Expand Down Expand Up @@ -1313,6 +1314,13 @@ func (fs *fileSystem) StatFS(
func (fs *fileSystem) LookUpInode(
ctx context.Context,
op *fuseops.LookUpInodeOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the parent directory in question.
fs.mu.Lock()
parent := fs.dirInodeOrDie(op.Parent)
Expand Down Expand Up @@ -1342,6 +1350,13 @@ func (fs *fileSystem) LookUpInode(
func (fs *fileSystem) GetInodeAttributes(
ctx context.Context,
op *fuseops.GetInodeAttributesOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the inode.
fs.mu.Lock()
in := fs.inodeOrDie(op.Inode)
Expand All @@ -1363,6 +1378,13 @@ func (fs *fileSystem) GetInodeAttributes(
func (fs *fileSystem) SetInodeAttributes(
ctx context.Context,
op *fuseops.SetInodeAttributesOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the inode.
fs.mu.Lock()
in := fs.inodeOrDie(op.Inode)
Expand Down Expand Up @@ -1422,6 +1444,13 @@ func (fs *fileSystem) ForgetInode(
func (fs *fileSystem) MkDir(
ctx context.Context,
op *fuseops.MkDirOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the parent.
fs.mu.Lock()
parent := fs.dirInodeOrDie(op.Parent)
Expand Down Expand Up @@ -1474,6 +1503,13 @@ func (fs *fileSystem) MkDir(
func (fs *fileSystem) MkNode(
ctx context.Context,
op *fuseops.MkNodeOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
if (op.Mode & (iofs.ModeNamedPipe | iofs.ModeSocket)) != 0 {
return syscall.ENOTSUP
}
Expand Down Expand Up @@ -1597,6 +1633,13 @@ func (fs *fileSystem) createLocalFile(
func (fs *fileSystem) CreateFile(
ctx context.Context,
op *fuseops.CreateFileOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Create the child.
var child inode.Inode
if fs.mountConfig.CreateEmptyFile {
Expand Down Expand Up @@ -1639,6 +1682,13 @@ func (fs *fileSystem) CreateFile(
func (fs *fileSystem) CreateSymlink(
ctx context.Context,
op *fuseops.CreateSymlinkOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the parent.
fs.mu.Lock()
parent := fs.dirInodeOrDie(op.Parent)
Expand Down Expand Up @@ -1702,6 +1752,13 @@ func (fs *fileSystem) RmDir(

ctx context.Context,
op *fuseops.RmDirOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the parent.
fs.mu.Lock()
parent := fs.dirInodeOrDie(op.Parent)
Expand Down Expand Up @@ -1797,6 +1854,13 @@ func (fs *fileSystem) RmDir(
func (fs *fileSystem) Rename(
ctx context.Context,
op *fuseops.RenameOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the old and new parents.
fs.mu.Lock()
oldParent := fs.dirInodeOrDie(op.OldParent)
Expand Down Expand Up @@ -2009,6 +2073,13 @@ func (fs *fileSystem) renameDir(
func (fs *fileSystem) Unlink(
ctx context.Context,
op *fuseops.UnlinkOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the parent.
fs.mu.Lock()
parent := fs.dirInodeOrDie(op.Parent)
Expand Down Expand Up @@ -2077,6 +2148,13 @@ func (fs *fileSystem) OpenDir(
func (fs *fileSystem) ReadDir(
ctx context.Context,
op *fuseops.ReadDirOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the handle.
fs.mu.Lock()
dh := fs.handles[op.Handle].(*handle.DirHandle)
Expand Down Expand Up @@ -2142,7 +2220,13 @@ func (fs *fileSystem) OpenFile(
func (fs *fileSystem) ReadFile(
ctx context.Context,
op *fuseops.ReadFileOp) (err error) {

if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Save readOp in context for access in logs.
ctx = context.WithValue(ctx, gcsx.ReadOp, op)

Expand Down Expand Up @@ -2187,6 +2271,13 @@ func (fs *fileSystem) ReadSymlink(
func (fs *fileSystem) WriteFile(
ctx context.Context,
op *fuseops.WriteFileOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the inode.
fs.mu.Lock()
in := fs.fileInodeOrDie(op.Inode)
Expand All @@ -2207,6 +2298,13 @@ func (fs *fileSystem) WriteFile(
func (fs *fileSystem) SyncFile(
ctx context.Context,
op *fuseops.SyncFileOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the inode.
fs.mu.Lock()
in := fs.inodeOrDie(op.Inode)
Expand All @@ -2233,6 +2331,13 @@ func (fs *fileSystem) SyncFile(
func (fs *fileSystem) FlushFile(
ctx context.Context,
op *fuseops.FlushFileOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the inode.
fs.mu.Lock()
in := fs.fileInodeOrDie(op.Inode)
Expand Down
8 changes: 8 additions & 0 deletions internal/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package util

import (
"context"
"encoding/json"
"fmt"
"math"
Expand Down Expand Up @@ -102,3 +103,10 @@ func BytesToHigherMiBs(bytes uint64) uint64 {
const bytesInOneMiB uint64 = 1 << 20
return uint64(math.Ceil(float64(bytes) / float64(bytesInOneMiB)))
}

// IsolateContextFromParentContext creates a copy of the parent context which is
// not cancelled when parent context is cancelled.
func IsolateContextFromParentContext(ctx context.Context) (context.Context, context.CancelFunc) {
ctx = context.WithoutCancel(ctx)
return context.WithCancel(ctx)
}
Loading
Loading