Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go-fuse
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Levin Zimmermann
go-fuse
Commits
15ae7b59
Commit
15ae7b59
authored
Apr 09, 2019
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
newunionfs: implement Readdir
parent
1bba2c11
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
108 additions
and
1 deletion
+108
-1
newunionfs/unionfs.go
newunionfs/unionfs.go
+71
-0
newunionfs/unionfs_test.go
newunionfs/unionfs_test.go
+37
-1
No files found.
newunionfs/unionfs.go
View file @
15ae7b59
...
...
@@ -37,6 +37,29 @@ type unionFSNode struct {
const
delDir
=
"DELETIONS"
func
(
r
*
unionFSRoot
)
allMarkers
(
result
map
[
string
]
struct
{})
syscall
.
Errno
{
dir
:=
filepath
.
Join
(
r
.
roots
[
0
],
delDir
)
ds
,
errno
:=
nodefs
.
NewLoopbackDirStream
(
dir
)
if
errno
!=
0
{
return
errno
}
defer
ds
.
Close
()
for
ds
.
HasNext
()
{
e
,
errno
:=
ds
.
Next
()
if
errno
!=
0
{
return
errno
}
if
e
.
Mode
!=
syscall
.
S_IFREG
{
continue
}
result
[
e
.
Name
]
=
struct
{}{}
}
return
0
}
func
(
r
*
unionFSRoot
)
rmMarker
(
name
string
)
syscall
.
Errno
{
err
:=
syscall
.
Unlink
(
r
.
markerPath
(
name
))
if
err
!=
nil
{
...
...
@@ -297,6 +320,54 @@ func (n *unionFSNode) Readlink(ctx context.Context) ([]byte, syscall.Errno) {
return
buf
[
:
count
],
0
}
var
_
=
(
nodefs
.
Readdirer
)((
*
unionFSNode
)(
nil
))
func
(
n
*
unionFSNode
)
Readdir
(
ctx
context
.
Context
)
(
nodefs
.
DirStream
,
syscall
.
Errno
)
{
root
:=
n
.
root
()
markers
:=
map
[
string
]
struct
{}{}
// ignore error: assume no markers
root
.
allMarkers
(
markers
)
dir
:=
n
.
Path
(
nil
)
names
:=
map
[
string
]
uint32
{}
for
i
:=
range
root
.
roots
{
// deepest root first.
readRoot
(
root
.
roots
[
len
(
root
.
roots
)
-
i
-
1
],
dir
,
names
)
}
result
:=
make
([]
fuse
.
DirEntry
,
0
,
len
(
names
))
for
nm
,
mode
:=
range
names
{
marker
:=
filePathHash
(
filepath
.
Join
(
dir
,
nm
))
if
_
,
ok
:=
markers
[
marker
];
ok
{
continue
}
result
=
append
(
result
,
fuse
.
DirEntry
{
Name
:
nm
,
Mode
:
mode
,
})
}
return
nodefs
.
NewListDirStream
(
result
),
0
}
func
readRoot
(
root
string
,
dir
string
,
result
map
[
string
]
uint32
)
{
ds
,
errno
:=
nodefs
.
NewLoopbackDirStream
(
filepath
.
Join
(
root
,
dir
))
if
errno
!=
0
{
return
}
defer
ds
.
Close
()
for
ds
.
HasNext
()
{
e
,
errno
:=
ds
.
Next
()
if
errno
!=
0
{
return
}
result
[
e
.
Name
]
=
e
.
Mode
}
}
// getBranch returns the root where we can find the given file. It
// will check the deletion markers in roots[0].
func
(
n
*
unionFSNode
)
getBranch
(
st
*
syscall
.
Stat_t
)
(
string
,
int
)
{
...
...
newunionfs/unionfs_test.go
View file @
15ae7b59
...
...
@@ -9,6 +9,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"reflect"
"syscall"
"testing"
...
...
@@ -196,6 +197,41 @@ func TestDeleteRevert(t *testing.T) {
}
}
func
TestReaddir
(
t
*
testing
.
T
)
{
tc
:=
newTestCase
(
t
,
true
)
defer
tc
.
Clean
()
if
err
:=
ioutil
.
WriteFile
(
tc
.
ro
+
"/dir/file2"
,
nil
,
0644
);
err
!=
nil
{
t
.
Fatalf
(
"WriteFile: %v"
,
err
)
}
if
err
:=
os
.
Mkdir
(
tc
.
rw
+
"/dir"
,
0755
);
err
!=
nil
{
t
.
Fatalf
(
"Mkdir: %v"
,
err
)
}
if
err
:=
ioutil
.
WriteFile
(
tc
.
rw
+
"/dir/file3"
,
nil
,
0644
);
err
!=
nil
{
t
.
Fatalf
(
"WriteFile: %v"
,
err
)
}
if
err
:=
os
.
Remove
(
tc
.
mnt
+
"/dir/ro-file"
);
err
!=
nil
{
t
.
Fatalf
(
"Remove: %v"
,
err
)
}
res
,
err
:=
ioutil
.
ReadDir
(
tc
.
mnt
+
"/dir"
)
if
err
!=
nil
{
t
.
Fatalf
(
"ReadDir: %v"
,
err
)
}
got
:=
map
[
string
]
bool
{}
want
:=
map
[
string
]
bool
{
"file2"
:
true
,
"file3"
:
true
,
}
for
_
,
fi
:=
range
res
{
got
[
fi
.
Name
()]
=
true
}
if
!
reflect
.
DeepEqual
(
want
,
got
)
{
t
.
Errorf
(
"got %v want %v"
,
got
,
want
)
}
}
func
TestPosix
(
t
*
testing
.
T
)
{
cases
:=
[]
string
{
"SymlinkReadlink"
,
...
...
@@ -207,7 +243,7 @@ func TestPosix(t *testing.T) {
// "NlinkZero",
"ParallelFileOpen"
,
// "Link",
//
"ReadDir",
"ReadDir"
,
}
for
_
,
nm
:=
range
cases
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment