Skip to content
Merged
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
9 changes: 5 additions & 4 deletions common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ const (
DefaultDirectoryPermissionBits os.FileMode = 0775
DefaultAllowOtherPermissionBits os.FileMode = 0777

MbToBytes = 1024 * 1024
GbToBytes = 1024 * 1024 * 1024
TbToBytes = 1024 * 1024 * 1024 * 1024
CfuseStats = "cloudfuse_stats"
MbToBytes = 1024 * 1024
GbToBytes = 1024 * 1024 * 1024
TbToBytes = 1024 * 1024 * 1024 * 1024
DefaultCapacityMb = TbToBytes / MbToBytes
CfuseStats = "cloudfuse_stats"

FuseAllowedFlags = "invalid FUSE options. Allowed FUSE configurations are: `-o attr_timeout=TIMEOUT`, `-o negative_timeout=TIMEOUT`, `-o entry_timeout=TIMEOUT` `-o allow_other`, `-o allow_root`, `-o umask=PERMISSIONS -o default_permissions`, `-o ro`"

Expand Down
29 changes: 20 additions & 9 deletions component/libfuse/libfuse.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ type Libfuse struct {
maxFuseThreads uint32
directIO bool
umask uint32
displayCapacityMb uint64
}

// To support pagination in readdir calls this structure holds a block of items for a given directory
Expand Down Expand Up @@ -105,6 +106,7 @@ type LibfuseOptions struct {
MaxFuseThreads uint32 `config:"max-fuse-threads" yaml:"max-fuse-threads,omitempty"`
DirectIO bool `config:"direct-io" yaml:"direct-io,omitempty"`
Umask uint32 `config:"umask" yaml:"umask,omitempty"`
DisplayCapacityMb uint64 `config:"display-capacity-mb" yaml:"display-capacity-mb,omitempty"`
}

const compName = "libfuse"
Expand Down Expand Up @@ -232,22 +234,28 @@ func (lf *Libfuse) Validate(opt *LibfuseOptions) error {
lf.negativeTimeout = defaultNegativeEntryExpiration
}

if config.IsSet(compName + ".max-fuse-threads") {
lf.maxFuseThreads = opt.MaxFuseThreads
} else {
lf.maxFuseThreads = defaultMaxFuseThreads
}

if config.IsSet(compName+".display-capacity-mb") && opt.DisplayCapacityMb > 0 {
lf.displayCapacityMb = opt.DisplayCapacityMb
} else {
lf.displayCapacityMb = common.DefaultCapacityMb
}

// NOTE/TODO: this always fails in GitHub Actions on Windows
if !(config.IsSet(compName+".uid") || config.IsSet(compName+".gid") ||
config.IsSet("lfuse.uid") || config.IsSet("lfuse.gid")) {
var err error
lf.ownerUID, lf.ownerGID, err = common.GetCurrentUser()
if err != nil {
log.Err("Libfuse::Validate : config error [unable to obtain current user info]")
return nil
}
}

if config.IsSet(compName + ".max-fuse-threads") {
lf.maxFuseThreads = opt.MaxFuseThreads
} else {
lf.maxFuseThreads = defaultMaxFuseThreads
}

log.Info("Libfuse::Validate : UID %v, GID %v", lf.ownerUID, lf.ownerGID)

return nil
Expand Down Expand Up @@ -309,9 +317,9 @@ func (lf *Libfuse) Configure(_ bool) error {
}

log.Info("Libfuse::Configure : read-only %t, allow-other %t, allow-root %t, default-perm %d, entry-timeout %d, attr-time %d, negative-timeout %d, "+
"ignore-open-flags: %t, nonempty %t, network-share %t, direct_io %t, max-fuse-threads %d, fuse-trace %t, extension %s, disable-writeback-cache %t, dirPermission %v, mountPath %v, umask %v",
"ignore-open-flags: %t, nonempty %t, network-share %t, direct_io %t, max-fuse-threads %d, fuse-trace %t, extension %s, disable-writeback-cache %t, dirPermission %v, mountPath %v, umask %v, displayCapacityMb %v",
lf.readOnly, lf.allowOther, lf.allowRoot, lf.filePermission, lf.entryExpiration, lf.attributeExpiration, lf.negativeTimeout,
lf.ignoreOpenFlags, lf.nonEmptyMount, lf.networkShare, lf.directIO, lf.maxFuseThreads, lf.traceEnable, lf.extensionPath, lf.disableWritebackCache, lf.dirPermission, lf.mountPath, lf.umask)
lf.ignoreOpenFlags, lf.nonEmptyMount, lf.networkShare, lf.directIO, lf.maxFuseThreads, lf.traceEnable, lf.extensionPath, lf.disableWritebackCache, lf.dirPermission, lf.mountPath, lf.umask, lf.displayCapacityMb)

return nil
}
Expand Down Expand Up @@ -354,4 +362,7 @@ func init() {

networkShareFlags := config.AddBoolFlag("network-share", false, "Run as a network share. Only supported on Windows.")
config.BindPFlag(compName+".network-share", networkShareFlags)

displayCapacityFlag := config.AddUint64Flag("display-capacity-mb", common.DefaultCapacityMb, "Storage capacity to display.")
config.BindPFlag(compName+".display-capacity-mb", displayCapacityFlag)
}
3 changes: 2 additions & 1 deletion component/libfuse/libfuse2_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,8 @@ func (cf *CgofuseFS) Statfs(path string, stat *fuse.Statfs_t) int {
stat.Namemax = attr.Namemax
} else {
var free, total, avail uint64
total = common.TbToBytes
// TODO: if display capacity is specified, should it overwrite populated Bavail?
total = fuseFS.displayCapacityMb * common.MbToBytes
avail = total
free = total

Expand Down
7 changes: 5 additions & 2 deletions component/libfuse/libfuse_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func (suite *libfuseTestSuite) TestDefault() {
suite.assert.Equal(uint32(120), suite.libfuse.entryExpiration)
suite.assert.Equal(uint32(120), suite.libfuse.attributeExpiration)
suite.assert.Equal(uint32(120), suite.libfuse.negativeTimeout)
suite.assert.Equal(uint64(1024*1024), suite.libfuse.displayCapacityMb)
suite.assert.False(suite.libfuse.disableWritebackCache)
suite.assert.True(suite.libfuse.ignoreOpenFlags)
suite.assert.False(suite.libfuse.directIO)
Expand All @@ -57,7 +58,7 @@ func (suite *libfuseTestSuite) TestDefault() {
func (suite *libfuseTestSuite) TestConfig() {
defer suite.cleanupTest()
suite.cleanupTest() // clean up the default libfuse generated
config := "allow-other: true\nread-only: true\nlibfuse:\n attribute-expiration-sec: 60\n entry-expiration-sec: 60\n negative-entry-expiration-sec: 60\n fuse-trace: true\n disable-writeback-cache: true\n ignore-open-flags: false\n direct-io: true\n network-share: true\n"
config := "allow-other: true\nread-only: true\nlibfuse:\n attribute-expiration-sec: 60\n entry-expiration-sec: 60\n negative-entry-expiration-sec: 60\n fuse-trace: true\n disable-writeback-cache: true\n ignore-open-flags: false\n direct-io: true\n network-share: true\n display-capacity-mb: 262144\n"
suite.setupTestHelper(config) // setup a new libfuse with a custom config (clean up will occur after the test as usual)

suite.assert.Equal("libfuse", suite.libfuse.Name())
Expand All @@ -74,13 +75,14 @@ func (suite *libfuseTestSuite) TestConfig() {
suite.assert.Equal(uint32(60), suite.libfuse.entryExpiration)
suite.assert.Equal(uint32(60), suite.libfuse.attributeExpiration)
suite.assert.Equal(uint32(60), suite.libfuse.negativeTimeout)
suite.assert.Equal(uint64(262144), suite.libfuse.displayCapacityMb)
suite.assert.True(suite.libfuse.directIO)
}

func (suite *libfuseTestSuite) TestConfigZero() {
defer suite.cleanupTest()
suite.cleanupTest() // clean up the default libfuse generated
config := "read-only: true\nlibfuse:\n attribute-expiration-sec: 0\n entry-expiration-sec: 0\n negative-entry-expiration-sec: 0\n fuse-trace: true\n direct-io: false\n"
config := "read-only: true\nlibfuse:\n attribute-expiration-sec: 0\n entry-expiration-sec: 0\n negative-entry-expiration-sec: 0\n fuse-trace: true\n direct-io: false\n display-capacity-mb: 0\n"
suite.setupTestHelper(config) // setup a new libfuse with a custom config (clean up will occur after the test as usual)

suite.assert.Equal("libfuse", suite.libfuse.Name())
Expand All @@ -95,6 +97,7 @@ func (suite *libfuseTestSuite) TestConfigZero() {
suite.assert.Equal(uint32(0), suite.libfuse.entryExpiration)
suite.assert.Equal(uint32(0), suite.libfuse.attributeExpiration)
suite.assert.Equal(uint32(0), suite.libfuse.negativeTimeout)
suite.assert.Equal(uint64(1024*1024), suite.libfuse.displayCapacityMb)
suite.assert.False(suite.libfuse.directIO)
}

Expand Down
1 change: 1 addition & 0 deletions setup/baseConfig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ libfuse:
max-fuse-threads: <number of threads allowed at libfuse layer for highly parallel operations, Default is 128>
direct-io: true|false <enable to bypass the kernel cache>
network-share: true|false <runs as a network share. may improve performance when latency to cloud is high. only supported on Windows. Known issue - only one Cloudfuse network share can be mounted at a time>
display-capacity-mb: <number of MB to display as the mounted storage capacity. Default - 1TB (1048576 MB)>

# Streaming configuration
stream:
Expand Down