Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Juicedata
JuiceFS
提交
b5d0cd88
JuiceFS
项目概览
Juicedata
/
JuiceFS
通知
10
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
JuiceFS
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
b5d0cd88
编写于
6月 16, 2021
作者:
D
Davies Liu
提交者:
GitHub
6月 16, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
support read-only mode (#520)
* support read-only mode * fix build and update docs * fix json tag
上级
69b05e0a
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
62 addition
and
17 deletion
+62
-17
cmd/gateway.go
cmd/gateway.go
+3
-2
cmd/mount.go
cmd/mount.go
+7
-0
cmd/mount_unix.go
cmd/mount_unix.go
+4
-0
docs/en/command_reference.md
docs/en/command_reference.md
+3
-0
docs/zh_cn/command_reference.md
docs/zh_cn/command_reference.md
+3
-0
pkg/fs/fs.go
pkg/fs/fs.go
+7
-1
pkg/meta/config.go
pkg/meta/config.go
+1
-0
pkg/meta/interface.go
pkg/meta/interface.go
+1
-1
pkg/meta/redis.go
pkg/meta/redis.go
+11
-2
pkg/meta/sql.go
pkg/meta/sql.go
+11
-2
pkg/vfs/fill.go
pkg/vfs/fill.go
+1
-1
pkg/vfs/helpers.go
pkg/vfs/helpers.go
+6
-0
pkg/vfs/vfs.go
pkg/vfs/vfs.go
+1
-1
pkg/vfs/vfs_unix.go
pkg/vfs/vfs_unix.go
+0
-6
sdk/java/libjfs/main.go
sdk/java/libjfs/main.go
+2
-1
sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java
sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java
+1
-0
未找到文件。
cmd/gateway.go
浏览文件 @
b5d0cd88
...
...
@@ -143,8 +143,9 @@ func (g *GateWay) NewGatewayLayer(creds auth.Credentials) (minio.ObjectLayer, er
c
:=
g
.
ctx
addr
:=
c
.
Args
()
.
Get
(
0
)
m
:=
meta
.
NewClient
(
addr
,
&
meta
.
Config
{
Retries
:
10
,
Strict
:
true
,
Retries
:
10
,
Strict
:
true
,
ReadOnly
:
c
.
Bool
(
"read-only"
),
})
format
,
err
:=
m
.
Load
()
if
err
!=
nil
{
...
...
cmd/mount.go
浏览文件 @
b5d0cd88
...
...
@@ -84,10 +84,17 @@ func mount(c *cli.Context) error {
logger
.
Fatalf
(
"create %s: %s"
,
mp
,
err
)
}
}
var
readOnly
=
c
.
Bool
(
"read-only"
)
for
_
,
o
:=
range
strings
.
Split
(
c
.
String
(
"o"
),
","
)
{
if
o
==
"ro"
{
readOnly
=
true
}
}
m
:=
meta
.
NewClient
(
addr
,
&
meta
.
Config
{
Retries
:
10
,
Strict
:
true
,
CaseInsensi
:
strings
.
HasSuffix
(
mp
,
":"
)
&&
runtime
.
GOOS
==
"windows"
,
ReadOnly
:
readOnly
,
MountPoint
:
mp
,
})
format
,
err
:=
m
.
Load
()
...
...
cmd/mount_unix.go
浏览文件 @
b5d0cd88
...
...
@@ -109,6 +109,10 @@ func mount_flags() []cli.Flag {
Name
:
"enable-xattr"
,
Usage
:
"enable extended attributes (xattr)"
,
},
&
cli
.
BoolFlag
{
Name
:
"read-only"
,
Usage
:
"allow lookup/read operations only"
,
},
}
}
...
...
docs/en/command_reference.md
浏览文件 @
b5d0cd88
...
...
@@ -143,6 +143,9 @@ dir entry cache timeout in seconds (default: 1)
`--enable-xattr`
\
enable extended attributes (xattr) (default: false)
`--read-only`
\
allow lookup/read operations only (default: false)
`--get-timeout value`
\
the max number of seconds to download an object (default: 60)
...
...
docs/zh_cn/command_reference.md
浏览文件 @
b5d0cd88
...
...
@@ -145,6 +145,9 @@ dir entry cache timeout in seconds (default: 1)
`--enable-xattr`
\
enable extended attributes (xattr) (default: false)
`--read-only`
\
allow lookup/read operations only (default: false)
`--get-timeout value`
\
the max number of seconds to download an object (default: 60)
...
...
pkg/fs/fs.go
浏览文件 @
b5d0cd88
...
...
@@ -263,7 +263,13 @@ func (fs *FileSystem) Open(ctx meta.Context, path string, flags uint32) (f *File
if
err
!=
0
{
return
nil
,
err
}
err
=
fs
.
m
.
Open
(
ctx
,
fi
.
inode
,
uint8
(
flags
),
nil
)
var
oflags
uint32
=
syscall
.
O_RDONLY
if
flags
==
vfs
.
MODE_MASK_W
{
oflags
=
syscall
.
O_WRONLY
}
else
if
flags
&
vfs
.
MODE_MASK_W
!=
0
{
oflags
=
syscall
.
O_RDWR
}
err
=
fs
.
m
.
Open
(
ctx
,
fi
.
inode
,
oflags
,
nil
)
if
err
!=
0
{
return
}
...
...
pkg/meta/config.go
浏览文件 @
b5d0cd88
...
...
@@ -20,6 +20,7 @@ type Config struct {
Strict
bool
// update ctime
Retries
int
CaseInsensi
bool
ReadOnly
bool
MountPoint
string
}
...
...
pkg/meta/interface.go
浏览文件 @
b5d0cd88
...
...
@@ -265,7 +265,7 @@ type Meta interface {
// Create creates a file in a directory with given name.
Create
(
ctx
Context
,
parent
Ino
,
name
string
,
mode
uint16
,
cumask
uint16
,
inode
*
Ino
,
attr
*
Attr
)
syscall
.
Errno
// Open checks permission on a node and track it as open.
Open
(
ctx
Context
,
inode
Ino
,
flags
uint
8
,
attr
*
Attr
)
syscall
.
Errno
Open
(
ctx
Context
,
inode
Ino
,
flags
uint
32
,
attr
*
Attr
)
syscall
.
Errno
// Close a file.
Close
(
ctx
Context
,
inode
Ino
)
syscall
.
Errno
// Read returns the list of slices on the given chunk.
...
...
pkg/meta/redis.go
浏览文件 @
b5d0cd88
...
...
@@ -243,6 +243,9 @@ func (r *redisMeta) Load() (*Format, error) {
}
func
(
r
*
redisMeta
)
NewSession
()
error
{
if
r
.
conf
.
ReadOnly
{
return
nil
}
var
err
error
r
.
sid
,
err
=
r
.
rdb
.
Incr
(
Background
,
"nextsession"
)
.
Result
()
if
err
!=
nil
{
...
...
@@ -852,6 +855,9 @@ func shouldRetry(err error, retryOnFailure bool) bool {
}
func
(
r
*
redisMeta
)
txn
(
ctx
Context
,
txf
func
(
tx
*
redis
.
Tx
)
error
,
keys
...
string
)
syscall
.
Errno
{
if
r
.
conf
.
ReadOnly
{
return
syscall
.
EROFS
}
var
err
error
var
khash
=
fnv
.
New32
()
_
,
_
=
khash
.
Write
([]
byte
(
keys
[
0
]))
...
...
@@ -1902,11 +1908,14 @@ func (r *redisMeta) deleteInode(inode Ino) error {
return
err
}
func
(
r
*
redisMeta
)
Open
(
ctx
Context
,
inode
Ino
,
flags
uint
8
,
attr
*
Attr
)
syscall
.
Errno
{
func
(
r
*
redisMeta
)
Open
(
ctx
Context
,
inode
Ino
,
flags
uint
32
,
attr
*
Attr
)
syscall
.
Errno
{
var
err
syscall
.
Errno
if
attr
!=
nil
{
err
=
r
.
GetAttr
(
ctx
,
inode
,
attr
)
}
if
r
.
conf
.
ReadOnly
&&
flags
&
(
syscall
.
O_WRONLY
|
syscall
.
O_RDWR
|
syscall
.
O_TRUNC
|
syscall
.
O_APPEND
)
!=
0
{
return
syscall
.
EROFS
}
if
err
==
0
{
r
.
Lock
()
r
.
openFiles
[
inode
]
=
r
.
openFiles
[
inode
]
+
1
...
...
@@ -1965,7 +1974,7 @@ func (r *redisMeta) Read(ctx Context, inode Ino, indx uint32, chunks *[]Slice) s
}
ss
:=
readSlices
(
vals
)
*
chunks
=
buildSlice
(
ss
)
if
len
(
vals
)
>=
5
||
len
(
*
chunks
)
>=
5
{
if
!
r
.
conf
.
ReadOnly
&&
(
len
(
vals
)
>=
5
||
len
(
*
chunks
)
>=
5
)
{
go
r
.
compactChunk
(
inode
,
indx
,
false
)
}
return
0
...
...
pkg/meta/sql.go
浏览文件 @
b5d0cd88
...
...
@@ -285,6 +285,9 @@ func (m *dbMeta) NewSession() error {
if
err
:=
m
.
engine
.
Sync2
(
new
(
session
));
err
!=
nil
{
// old client has no info field
return
err
}
if
m
.
conf
.
ReadOnly
{
return
nil
}
v
,
err
:=
m
.
incrCounter
(
"nextSession"
,
1
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"create session: %s"
,
err
)
...
...
@@ -484,6 +487,9 @@ func (m *dbMeta) shouldRetry(err error) bool {
}
func
(
m
*
dbMeta
)
txn
(
f
func
(
s
*
xorm
.
Session
)
error
)
error
{
if
m
.
conf
.
ReadOnly
{
return
syscall
.
EROFS
}
start
:=
time
.
Now
()
defer
func
()
{
txDist
.
Observe
(
time
.
Since
(
start
)
.
Seconds
())
}()
var
err
error
...
...
@@ -1665,11 +1671,14 @@ func (m *dbMeta) deleteInode(inode Ino) error {
return
err
}
func
(
m
*
dbMeta
)
Open
(
ctx
Context
,
inode
Ino
,
flags
uint
8
,
attr
*
Attr
)
syscall
.
Errno
{
func
(
m
*
dbMeta
)
Open
(
ctx
Context
,
inode
Ino
,
flags
uint
32
,
attr
*
Attr
)
syscall
.
Errno
{
var
err
syscall
.
Errno
if
attr
!=
nil
{
err
=
m
.
GetAttr
(
ctx
,
inode
,
attr
)
}
if
m
.
conf
.
ReadOnly
&&
flags
&
(
syscall
.
O_WRONLY
|
syscall
.
O_RDWR
|
syscall
.
O_TRUNC
|
syscall
.
O_APPEND
)
!=
0
{
return
syscall
.
EROFS
}
if
err
==
0
{
m
.
Lock
()
m
.
openFiles
[
inode
]
=
m
.
openFiles
[
inode
]
+
1
...
...
@@ -1709,7 +1718,7 @@ func (m *dbMeta) Read(ctx Context, inode Ino, indx uint32, chunks *[]Slice) sysc
}
ss
:=
readSliceBuf
(
c
.
Slices
)
*
chunks
=
buildSlice
(
ss
)
if
len
(
c
.
Slices
)
/
sliceBytes
>=
5
||
len
(
*
chunks
)
>=
5
{
if
!
m
.
conf
.
ReadOnly
&&
(
len
(
c
.
Slices
)
/
sliceBytes
>=
5
||
len
(
*
chunks
)
>=
5
)
{
go
m
.
compactChunk
(
inode
,
indx
,
false
)
}
return
0
...
...
pkg/vfs/fill.go
浏览文件 @
b5d0cd88
...
...
@@ -94,7 +94,7 @@ func resolve(p string, inode *Ino, attr *Attr) syscall.Errno {
break
}
if
i
>
0
{
if
err
=
m
.
Access
(
ctx
,
parent
,
1
,
attr
);
err
!=
0
{
if
err
=
m
.
Access
(
ctx
,
parent
,
MODE_MASK_R
|
MODE_MASK_X
,
attr
);
err
!=
0
{
return
err
}
}
...
...
pkg/vfs/helpers.go
浏览文件 @
b5d0cd88
...
...
@@ -23,6 +23,12 @@ import (
"github.com/juicedata/juicefs/pkg/meta"
)
const
(
MODE_MASK_R
=
4
MODE_MASK_W
=
2
MODE_MASK_X
=
1
)
func
strerr
(
errno
syscall
.
Errno
)
string
{
if
errno
==
0
{
return
"OK"
...
...
pkg/vfs/vfs.go
浏览文件 @
b5d0cd88
...
...
@@ -412,7 +412,7 @@ func Open(ctx Context, ino Ino, flags uint32) (entry *meta.Entry, fh uint64, err
return
}
err
=
m
.
Open
(
ctx
,
ino
,
uint8
(
flags
)
,
attr
)
err
=
m
.
Open
(
ctx
,
ino
,
flags
,
attr
)
if
err
!=
0
{
return
}
...
...
pkg/vfs/vfs_unix.go
浏览文件 @
b5d0cd88
...
...
@@ -31,12 +31,6 @@ import (
const
O_ACCMODE
=
syscall
.
O_ACCMODE
const
F_UNLCK
=
syscall
.
F_UNLCK
const
(
MODE_MASK_R
=
4
MODE_MASK_W
=
2
MODE_MASK_X
=
1
)
type
Statfs
struct
{
Bsize
uint32
Blocks
uint64
...
...
sdk/java/libjfs/main.go
浏览文件 @
b5d0cd88
...
...
@@ -214,6 +214,7 @@ func freeHandle(fd int) {
type
javaConf
struct
{
MetaURL
string
`json:"meta"`
ReadOnly
bool
`json:"readOnly"`
CacheDir
string
`json:"cacheDir"`
CacheSize
int64
`json:"cacheSize"`
FreeSpace
string
`json:"freeSpace"`
...
...
@@ -313,7 +314,7 @@ func jfs_init(cname, jsonConf, user, group, superuser, supergroup *C.char) uintp
utils
.
InitLoggers
(
false
)
addr
:=
jConf
.
MetaURL
m
:=
meta
.
NewClient
(
addr
,
&
meta
.
Config
{
Retries
:
10
,
Strict
:
true
})
m
:=
meta
.
NewClient
(
addr
,
&
meta
.
Config
{
Retries
:
10
,
Strict
:
true
,
ReadOnly
:
jConf
.
ReadOnly
})
format
,
err
:=
m
.
Load
()
if
err
!=
nil
{
logger
.
Fatalf
(
"load setting: %s"
,
err
)
...
...
sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java
浏览文件 @
b5d0cd88
...
...
@@ -310,6 +310,7 @@ public class JuiceFileSystemImpl extends FileSystem {
for
(
String
key
:
bkeys
)
{
obj
.
put
(
key
,
Boolean
.
valueOf
(
getConf
(
conf
,
key
,
"false"
)));
}
obj
.
put
(
"readOnly"
,
Boolean
.
valueOf
(
getConf
(
conf
,
"read-only"
,
"false"
)));
obj
.
put
(
"cacheDir"
,
getConf
(
conf
,
"cache-dir"
,
"memory"
));
obj
.
put
(
"cacheSize"
,
Integer
.
valueOf
(
getConf
(
conf
,
"cache-size"
,
"100"
)));
obj
.
put
(
"cacheFullBlock"
,
Boolean
.
valueOf
(
getConf
(
conf
,
"cache-full-block"
,
"true"
)));
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录