in component/libfuse/libfuse2_handler.go [190:260]
func populateFuseArgs(opts *C.fuse_options_t, args *C.fuse_args_t) (*C.fuse_options_t, C.int) {
log.Trace("Libfuse::populateFuseArgs")
if args == nil {
return nil, 1
}
args.argc = 0
args.allocated = 1
arguments := make([]string, 0)
options := fmt.Sprintf("entry_timeout=%d,attr_timeout=%d,negative_timeout=%d",
opts.entry_expiry,
opts.attr_expiry,
opts.negative_expiry)
if opts.allow_other {
options += ",allow_other"
}
if opts.allow_root {
options += ",allow_root"
}
if opts.non_empty {
options += ",nonempty"
}
if opts.readonly {
options += ",ro"
}
if opts.umask != 0 {
options += fmt.Sprintf(",umask=%04d", opts.umask)
}
// force the fuse library to always pass O_TRUNC flag on open call
// Not checking the options since we don't allow user to configure this flag.
// This is the default behaviour for the fuse3 hence we don't pass this flag there.
// ref: https://github.com/libfuse/libfuse/blob/7f86f3be7148b15b71b63357813c66dd32177cf6/lib/fuse_lowlevel.c#L2161C2-L2161C16
options += ",atomic_o_trunc"
// direct_io option is used to bypass the kernel cache. It disables the use of
// page cache (file content cache) in the kernel for the filesystem.
if fuseFS.directIO {
options += ",direct_io"
} else {
options += ",kernel_cache"
}
// Why we pass -f
// CGo is not very good with handling forks - so if the user wants to run blobfuse in the
// background we fork on mount in GO (mount.go) and we just always force libfuse to mount in foreground
arguments = append(arguments, "blobfuse2",
C.GoString(opts.mount_path),
"-o", options,
"-f", "-ofsname=blobfuse2")
if opts.trace_enable {
arguments = append(arguments, "-d")
}
for _, a := range arguments {
log.Debug("Libfuse::populateFuseArgs : opts : %s", a)
arg := C.CString(a)
defer C.free(unsafe.Pointer(arg))
err := C.fuse_opt_add_arg(args, arg)
if err != 0 {
return nil, err
}
}
return opts, 0
}