fuse用户空间文件系统

用户空间的文件系统(FUSE),无需理解文件系统的内幕,也不用学习内核模块编程的知识,就可以开发用户空间的文件系统框架。在用户空间的文件系统出现之前,文件系统的开发曾是内核开发人员的工作。创建文件系统需要了解内核编程和内核技术(例如 vfs)方面的知识。调试则需要 C 和 C++ 方面的专业技能。使用 FUSE 您可以开发功能完备的文件系统:其具有简单的 API 库,可以被非特权用户访问,并可以安全的实施。更重要的是,FUSE 以往的表现充分证明了其稳定性。


使用 FUSE,您可以像可执行二进制文件一样来开发文件系统,它们需要链接到 FUSE 库上 —— 换言之,这个文件系统框架并不需要您了解文件系统的内幕和内核模块编程的知识。要在 FUSE 中创建一个文件系统,您需要安装一个 FUSE 内核模块,然后使用 FUSE 库和 API 来创建自己的文件系统。

要开发一个文件系统,首先请下载 FUSE 的源代码(请参阅 参考资料)并展开这个包:tar -zxvf fuse-2.2.tar.gz。这会创建一个 FUSE 目录,其中保存的是源代码。fuse-2.2 目录的内容如下:
./doc 包含了与 FUSE 有关的文档。现在,这只有一个文件 how-fuse-works。
./kernel 包含了 FUSE 内核模块的源代码(对于使用 FUSE 开发文件系统来说,您当然不用懂得这些代码的机制)。
./include 包含了 FUSE API 头,您需要这些文件来创建文件系统。您现在唯一需要的就是 fuse.h。
./lib 中存放的是创建 FUSE 库的源代码,您需要将它们与您的二进制文件链接在一起来创建文件系统。
./util 中存放的是 FUSE 工具库的源代码。
./example 当然包含的是一些供您参考的例子,例如 fusexmp.null 和 hello 文件系统。


Fuse开发文件系统的GO语言库bazil.org/fuse:https://godoc.org/bazil.org/fuse

https://bazil.org/fuse/fs/ 这个是fuse文件系统的高层级接口:https://bazil.org/fuse/fs/

bazil.org/fuse/fs contains a higher-level API for creating FUSE filesystems, that keeps track of directory entries and open files the kernel knows about.

Servers of synthesized file systems tend to share common bookkeeping abstracted away by the second approach, which is to call fs.Serve to serve the FUSE protocol using an implementation of the service methods in the interfaces FS* (file system), Node* (file or directory), and Handle* (opened file or directory). 


vim的 godef安装

[root@localhost cgroupfs-master]# go get code.google.com/p/rog-go/exp/cmd/godef
package code.google.com/p/rog-go/exp/cmd/godef: unable to detect version control system for code.google.com/ path
[root@localhost cgroupfs-master]# go get github.com/rogpeppe/godef

Go语言下的hello.go


// Hellofs implements a simple "hello world" file system.
package main

import (
	"flag"
	"fmt"
	"log"
	"os"

	"bazil.org/fuse"
	"bazil.org/fuse/fs"
	_ "bazil.org/fuse/fs/fstestutil"
	"golang.org/x/net/context"
)

func usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	fmt.Fprintf(os.Stderr, "  %s MOUNTPOINT\n", os.Args[0])
	flag.PrintDefaults()
}

func main() {
	flag.Usage = usage
	flag.Parse()

	if flag.NArg() != 1 {
		usage()
		os.Exit(2)
	}
	mountpoint := flag.Arg(0)

	c, err := fuse.Mount( //建立一个新的fuse连接,返回一个连接c 用于读写
		mountpoint,
		fuse.FSName("helloworld"),
		fuse.Subtype("hellofs"),
		fuse.LocalVolume(),
		fuse.VolumeName("Hello world!"),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	err = fs.Serve(c, FS{})//使用连接c提供服务。<span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(0, 136, 255);">An</span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(192, 192, 192);"> </span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(0, 136, 255);">FS</span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(192, 192, 192);"> </span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(0, 136, 255);">is</span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(192, 192, 192);"> </span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(0, 136, 255);">the</span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(192, 192, 192);"> </span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(0, 136, 255);">interface</span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(192, 192, 192);"> </span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(0, 136, 255);">required</span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(192, 192, 192);"> </span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(0, 136, 255);">of</span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(192, 192, 192);"> </span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(0, 136, 255);">a</span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(192, 192, 192);"> </span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(0, 136, 255);">file</span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(192, 192, 192);"> </span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: rgb(0, 136, 255);">system.</span>

	if err != nil {
		log.Fatal(err)
	}

	// check if the mount process has an error to report
	<-c.Ready
	if err := c.MountError; err != nil {
		log.Fatal(err)
	}
}

// FS implements the hello world file system.
type FS struct{}

func (FS) Root() (fs.Node, error) { //FS实现root接口
	return Dir{}, nil
}

// Dir implements both Node and Handle for the root directory.
type Dir struct{}

func (Dir) Attr(ctx context.Context, a *fuse.Attr) error {
	a.Inode = 1
	a.Mode = os.ModeDir | 0555
	return nil
}

func (Dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
	if name == "hello" {
		return File{}, nil
	}
	return nil, fuse.ENOENT
}

var dirDirs = []fuse.Dirent{
	{Inode: 2, Name: "hello", Type: fuse.DT_File},
}

func (Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
	return dirDirs, nil
}

// File implements both Node and Handle for the hello file.
type File struct{}

const greeting = "hello, world\n"

func (File) Attr(ctx context.Context, a *fuse.Attr) error {
	a.Inode = 2
	a.Mode = 0444
	a.Size = uint64(len(greeting))
	return nil
}

func (File) ReadAll(ctx context.Context) ([]byte, error) {
	return []byte(greeting), nil
}


fuse的原理说明:


FUSE分为三大模块:
Ø FUSE内核模块(内核态)
Ø LibFUSE模块(用户态)
Ø 用户程序模块(用户态)
用户程序在用户空间实现LibFUSE库封装的文件系统操作;
LibFUSE实现文件系统主要框架、对“用户实现的文件系统操作代码“的封装、mount管理、通过字符设备/dev/fuse与内核模块通信;

FUSE内核模块实现VFS接口(实现fuse文件驱动模块的注册、fuse 的(虚拟)设备驱动、提供supper block、dentry、inode的维护),接收来至后者的请求,传递给LibFUSE,LibFUSE再传递给我们用户程序的接口进行实现操作。



  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
gocryptfs 是一个使用 Go 开发的,加密的覆盖文件系统。gocryptfs 基于 go-fuse FUSE 库和其 LoopbackFileSystem API 构建。gocryptfs 灵感来源于 EncFS,修复了其安全问题,提供更好的性能。gocryptfs 当前只支持 Linux 系统,以后会继续支持 OS X。安装:$ go get github.com/rfjakob/gocryptfs使用:$ mkdir cipher plain $ $GOPATH/bin/gocryptfs --init cipher   [...] $ $GOPATH/bin/gocryptfs cipher plain   [...] $ echo test > plain/test.txt $ ls -l cipher   total 8   -rw-rw-r--. 1 user  user   33  7. Okt 23:23 0ao8Hyyf1A-A88sfNvkUxA==   -rw-rw-r--. 1 user  user  233  7. Okt 23:23 gocryptfs.conf $ fusermount -u plain性能:./benchmark.bash gocryptfs v0.3.1-30-gd69e0df-dirty; on-disk format 2 PASS BenchmarkStreamWrite-2       100      12246070 ns/op      85.63 MB/s BenchmarkStreamRead-2        200       9125990 ns/op     114.90 MB/s BenchmarkCreate0B-2        10000        101284 ns/op BenchmarkCreate1B-2        10000        178356 ns/op       0.01 MB/s BenchmarkCreate100B-2       5000        361014 ns/op       0.28 MB/s BenchmarkCreate4kB-2        5000        375035 ns/op      10.92 MB/s BenchmarkCreate10kB-2       3000        491071 ns/op      20.85 MB/s ok      github.com/rfjakob/gocryptfs/integration_tests  17.216s 标签:文件加密

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值