in component/libfuse/libfuse_handler.go [258:341]
func libfuse_init(conn *C.fuse_conn_info_t, cfg *C.fuse_config_t) (res unsafe.Pointer) {
log.Trace("Libfuse::libfuse_init : init (read : %v, write %v, read-ahead %v)", conn.max_read, conn.max_write, conn.max_readahead)
log.Info("Libfuse::NotifyMountToParent : Notifying parent for successful mount")
if err := common.NotifyMountToParent(); err != nil {
log.Err("Libfuse::NotifyMountToParent : Failed to notify parent, error: [%v]", err)
}
C.populate_uid_gid()
log.Info("Libfuse::libfuse_init : Kernel Caps : %d", conn.capable)
// Populate connection information
// conn.want |= C.FUSE_CAP_NO_OPENDIR_SUPPORT
// Allow fuse to perform parallel operations on a directory
if (conn.capable & C.FUSE_CAP_PARALLEL_DIROPS) != 0 {
log.Info("Libfuse::libfuse_init : Enable Capability : FUSE_CAP_PARALLEL_DIROPS")
conn.want |= C.FUSE_CAP_PARALLEL_DIROPS
}
// Kernel shall invalidate the data in page cache if file size of LMT changes
if (conn.capable & C.FUSE_CAP_AUTO_INVAL_DATA) != 0 {
log.Info("Libfuse::libfuse_init : Enable Capability : FUSE_CAP_AUTO_INVAL_DATA")
conn.want |= C.FUSE_CAP_AUTO_INVAL_DATA
}
// Enable read-dir plus where attributes of each file are returned back
// in the list call itself and fuse does not need to fire getAttr after list
if (conn.capable & C.FUSE_CAP_READDIRPLUS) != 0 {
log.Info("Libfuse::libfuse_init : Enable Capability : FUSE_CAP_READDIRPLUS")
conn.want |= C.FUSE_CAP_READDIRPLUS
}
// Allow fuse to read a file in parallel on different offsets
if (conn.capable & C.FUSE_CAP_ASYNC_READ) != 0 {
log.Info("Libfuse::libfuse_init : Enable Capability : FUSE_CAP_ASYNC_READ")
conn.want |= C.FUSE_CAP_ASYNC_READ
}
if (conn.capable & C.FUSE_CAP_SPLICE_WRITE) != 0 {
// While writing to fuse device let libfuse collate the data and write big chunks
log.Info("Libfuse::libfuse_init : Enable Capability : FUSE_CAP_SPLICE_WRITE")
conn.want |= C.FUSE_CAP_SPLICE_WRITE
}
/*
FUSE_CAP_WRITEBACK_CACHE flag is not suitable for network filesystems. If a partial page is
written, then the page needs to be first read from userspace. This means, that
even for files opened for O_WRONLY it is possible that READ requests will be
generated by the kernel.
*/
if (!fuseFS.directIO) && (!fuseFS.disableWritebackCache) && ((conn.capable & C.FUSE_CAP_WRITEBACK_CACHE) != 0) {
// Buffer write requests at libfuse and then hand it off to application
log.Info("Libfuse::libfuse_init : Enable Capability : FUSE_CAP_WRITEBACK_CACHE")
conn.want |= C.FUSE_CAP_WRITEBACK_CACHE
}
// Max background thread on the fuse layer for high parallelism
conn.max_background = C.uint(fuseFS.maxFuseThreads)
// While reading a file let kernel do readahed for better perf
conn.max_readahead = (4 * 1024 * 1024)
conn.max_read = (1 * 1024 * 1024)
// RHEL still has 3.3 fuse version and it does not allow max_write beyond 128K
// Setting this value to 1 MB will fail the mount.
fuse_minor := common.GetFuseMinorVersion()
if fuse_minor > 4 {
log.Info("Libfuse::libfuse_init : Setting 1MB max_write for fuse minor %v", fuse_minor)
conn.max_write = (1 * 1024 * 1024)
} else {
log.Info("Libfuse::libfuse_init : Ignoring max_write for fuse minor %v", fuse_minor)
conn.max_write = (128 * 1024)
}
// 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 {
cfg.direct_io = C.int(1)
}
return nil
}