前言
Seafile文件系统的存储方式和Git很像,主要分为repository
、branch
、commit
、block
、fs
这几个结构
我们来一步步了解:
一、repo(repository)
官方的中文翻译是资料库,就是我们一开建的一个个库,在代码里常用repo
来缩写代替
在后端go文件中的代码描述:
// Repo contains information about a repo.
type Repo struct {
ID string
Name string
Desc string
LastModifier string
LastModificationTime int64
HeadCommitID string
RootID string
IsCorrupted bool
// Set when repo is virtual
VirtualInfo *VRepoInfo
// ID for fs and block store
StoreID string
// Encrypted repo info
IsEncrypted bool
EncVersion int
Magic string
RandomKey string
Salt string
Version int
}
// VRepoInfo contains virtual repo information.
type VRepoInfo struct {
RepoID string
OriginRepoID string
Path string
BaseCommitID string
}
数据库表中中储存了部分上述属性,而加密等信息则存在commit中,后文会提到。
二、branch
分支的概念和Git一样,每个repo都会有分支:
在客户端,seafile有且仅有两个分支local和master,当本地文件时变化时会将修改作用到local分支,然后从服务器下载master分支,最终其合并到local分支。之后在将合并后的分支上传至服务器,服务端将master分支更新至最新的提交。
服务端通常只有一个master分支。
三、commit
这个概念也和git中的类似,他存储在文件中,如我的资料库test1
的commit文件在下图路径中:
打开后的内容如下:
{
"commit_id": "5822d0e650c828b51758ff1c0d4bf99a7cfcb23a",
"root_id": "0000000000000000000000000000000000000000",
"repo_id": "d9ec3a54-e492-469c-81fe-6808dfa68afa",
"creator_name": "1297399635@qq.com",
"creator": "0000000000000000000000000000000000000000",
"description": "Created library", "ctime": 1618586527,
"parent_id": null,
"second_parent_id": null,
"repo_name": "test1",
"repo_desc": "",
"repo_category": null,
"encrypted": "true",
"enc_version": 2,
"magic": "f552b91c07f060d093dea2d5ef42df38a3d9b2cd0bfdd69f6c6f9360a21899d6",
"key": "bd40e9278268a579a5d03e67de8d38b473e993062a6d47d46d9c97ccf34b29b01c1cacd14cc2bd7a61a58c3f5d48920e",
"no_local_history": 1,
"version": 1
}
可以看到这里保存了repo
在某一commit
的几乎所有信息。
四、fs
每一个commit里边有一个root_id
,它是资料库的根目录,里边记录了当前目录里边的文件结构。和commit不同这个结构用zlib压缩过,解压后才能看到明文,拿当前的commit举例,它的”root_id”是”9643c57118b2c4c8070fdf32ff7a5693a538defa”:
{
"dirents": [
{
"id": "f0857fb999fb00d7ac4b0f42ea04433890c812ab",
"mode": 16384,
"mtime": 1551531508,
"name": "pic"
}
],
"type": 3,
"version": 1
}
这个信息表示当前的根目录里边有一个文件,名叫"PIC",mode字段和Linux上的文件mode位一致,” ‘mode’: 16384, “ 表示这个文件是一个目录,id为”f0857fb999fb00d7ac4b0f42ea04433890c812ab”,按同样的步骤找打这个文件:
{
"dirents": [
{
"id": "bc61aa586059f275b7398a207a5483868c745ddd",
"mode": 33188,
"modifier": "1297399635@qq.com",
"mtime": 1551531508,
"name": "event.png",
"size": 181343
}
],
"type": 3,
"version": 1
}
说明PIC里边只有一个文件,”‘mode’:33188”表示这是一个普通文件,另外还包含了修改事件等文件属性。根据id”bc61aa586059f275b7398a207a5483868c745ddd”就能找到event.png的具体块信息。到了文件这一级后,并没有包含一个具体的文件路径,而是同样指向了一个id,将这个id打开:
{
"block_ids": [
"adec8babaaa3f3bbff009e5b407f946570b64a07"
],
"size": 181343,
"type": 1,
"version": 1
}
五、Block
根据fs
中的描述,block
存储了文件的实际内容。
参考资料
http://www.ilovecpp.com/2018/06/28/filesystem-design/