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
6b4bb98b
Commit
6b4bb98b
authored
Feb 22, 2019
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nodefs: Mkdir/Mknod/Rmdir/Unlink
parent
74f62108
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
148 additions
and
21 deletions
+148
-21
nodefs/api.go
nodefs/api.go
+5
-0
nodefs/bridge.go
nodefs/bridge.go
+61
-20
nodefs/loopback.go
nodefs/loopback.go
+53
-0
nodefs/simple_test.go
nodefs/simple_test.go
+29
-1
No files found.
nodefs/api.go
View file @
6b4bb98b
...
@@ -87,6 +87,11 @@ type Node interface {
...
@@ -87,6 +87,11 @@ type Node interface {
// pair.
// pair.
Lookup
(
ctx
context
.
Context
,
name
string
,
out
*
fuse
.
EntryOut
)
(
*
Inode
,
fuse
.
Status
)
Lookup
(
ctx
context
.
Context
,
name
string
,
out
*
fuse
.
EntryOut
)
(
*
Inode
,
fuse
.
Status
)
Mkdir
(
ctx
context
.
Context
,
name
string
,
mode
uint32
,
out
*
fuse
.
EntryOut
)
(
*
Inode
,
fuse
.
Status
)
Mknod
(
ctx
context
.
Context
,
name
string
,
mode
uint32
,
dev
uint32
,
out
*
fuse
.
EntryOut
)
(
*
Inode
,
fuse
.
Status
)
Rmdir
(
ctx
context
.
Context
,
name
string
)
fuse
.
Status
Unlink
(
ctx
context
.
Context
,
name
string
)
fuse
.
Status
Open
(
ctx
context
.
Context
,
flags
uint32
)
(
fh
File
,
fuseFlags
uint32
,
code
fuse
.
Status
)
Open
(
ctx
context
.
Context
,
flags
uint32
)
(
fh
File
,
fuseFlags
uint32
,
code
fuse
.
Status
)
Create
(
ctx
context
.
Context
,
name
string
,
flags
uint32
,
mode
uint32
)
(
node
*
Inode
,
fh
File
,
fuseFlags
uint32
,
code
fuse
.
Status
)
Create
(
ctx
context
.
Context
,
name
string
,
flags
uint32
,
mode
uint32
)
(
node
*
Inode
,
fh
File
,
fuseFlags
uint32
,
code
fuse
.
Status
)
...
...
nodefs/bridge.go
View file @
6b4bb98b
...
@@ -6,6 +6,7 @@ package nodefs
...
@@ -6,6 +6,7 @@ package nodefs
import
(
import
(
"context"
"context"
"log"
"sync"
"sync"
"time"
"time"
...
@@ -89,6 +90,61 @@ func (b *rawBridge) Lookup(header *fuse.InHeader, name string, out *fuse.EntryOu
...
@@ -89,6 +90,61 @@ func (b *rawBridge) Lookup(header *fuse.InHeader, name string, out *fuse.EntryOu
return
code
return
code
}
}
b
.
addNewChild
(
parent
,
name
,
child
,
out
)
b
.
setEntryOutTimeout
(
out
)
return
fuse
.
OK
}
func
(
b
*
rawBridge
)
Rmdir
(
header
*
fuse
.
InHeader
,
name
string
)
fuse
.
Status
{
parent
,
_
:=
b
.
inode
(
header
.
NodeId
,
0
)
code
:=
parent
.
node
.
Rmdir
(
context
.
TODO
(),
name
)
if
code
.
Ok
()
{
parent
.
RmChild
(
name
)
}
return
code
}
func
(
b
*
rawBridge
)
Unlink
(
header
*
fuse
.
InHeader
,
name
string
)
fuse
.
Status
{
parent
,
_
:=
b
.
inode
(
header
.
NodeId
,
0
)
code
:=
parent
.
node
.
Unlink
(
context
.
TODO
(),
name
)
if
code
.
Ok
()
{
parent
.
RmChild
(
name
)
}
return
code
}
func
(
b
*
rawBridge
)
Mkdir
(
input
*
fuse
.
MkdirIn
,
name
string
,
out
*
fuse
.
EntryOut
)
(
code
fuse
.
Status
)
{
parent
,
_
:=
b
.
inode
(
input
.
NodeId
,
0
)
child
,
code
:=
parent
.
node
.
Mkdir
(
context
.
TODO
(),
name
,
input
.
Mode
,
out
)
if
!
code
.
Ok
()
{
return
code
}
if
out
.
Attr
.
Mode
&^
07777
!=
fuse
.
S_IFDIR
{
log
.
Panicf
(
"Mkdir: mode must be S_IFDIR (%o), got %o"
,
fuse
.
S_IFDIR
,
out
.
Attr
.
Mode
)
}
b
.
addNewChild
(
parent
,
name
,
child
,
out
)
b
.
setEntryOutTimeout
(
out
)
return
fuse
.
OK
}
func
(
b
*
rawBridge
)
Mknod
(
input
*
fuse
.
MknodIn
,
name
string
,
out
*
fuse
.
EntryOut
)
(
code
fuse
.
Status
)
{
parent
,
_
:=
b
.
inode
(
input
.
NodeId
,
0
)
child
,
code
:=
parent
.
node
.
Mknod
(
context
.
TODO
(),
name
,
input
.
Mode
,
input
.
Rdev
,
out
)
if
!
code
.
Ok
()
{
return
code
}
b
.
addNewChild
(
parent
,
name
,
child
,
out
)
b
.
setEntryOutTimeout
(
out
)
return
fuse
.
OK
}
func
(
b
*
rawBridge
)
addNewChild
(
parent
*
Inode
,
name
string
,
child
*
Inode
,
out
*
fuse
.
EntryOut
)
{
lockNodes
(
parent
,
child
)
lockNodes
(
parent
,
child
)
parent
.
setEntry
(
name
,
child
)
parent
.
setEntry
(
name
,
child
)
b
.
mu
.
Lock
()
b
.
mu
.
Lock
()
...
@@ -99,9 +155,6 @@ func (b *rawBridge) Lookup(header *fuse.InHeader, name string, out *fuse.EntryOu
...
@@ -99,9 +155,6 @@ func (b *rawBridge) Lookup(header *fuse.InHeader, name string, out *fuse.EntryOu
out
.
Generation
=
b
.
nodes
[
out
.
NodeId
]
.
generation
out
.
Generation
=
b
.
nodes
[
out
.
NodeId
]
.
generation
b
.
mu
.
Unlock
()
b
.
mu
.
Unlock
()
unlockNodes
(
parent
,
child
)
unlockNodes
(
parent
,
child
)
b
.
setEntryOutTimeout
(
out
)
return
fuse
.
OK
}
}
func
(
b
*
rawBridge
)
setEntryOutTimeout
(
out
*
fuse
.
EntryOut
)
{
func
(
b
*
rawBridge
)
setEntryOutTimeout
(
out
*
fuse
.
EntryOut
)
{
...
@@ -155,11 +208,15 @@ func (b *rawBridge) Create(input *fuse.CreateIn, name string, out *fuse.CreateOu
...
@@ -155,11 +208,15 @@ func (b *rawBridge) Create(input *fuse.CreateIn, name string, out *fuse.CreateOu
b
.
mu
.
Unlock
()
b
.
mu
.
Unlock
()
unlockNode2
(
parent
,
child
)
unlockNode2
(
parent
,
child
)
b
.
setEntryOutTimeout
(
o
ut
)
b
.
setEntryOutTimeout
(
&
out
.
EntryO
ut
)
out
.
OpenFlags
=
flags
out
.
OpenFlags
=
flags
f
.
GetAttr
(
ctx
,
&
out
.
Attr
)
f
.
GetAttr
(
ctx
,
&
out
.
Attr
)
if
out
.
Attr
.
Mode
&^
07777
!=
fuse
.
S_IFREG
{
log
.
Panicf
(
"Create: mode must be S_IFREG (%o), got %o"
,
fuse
.
S_IFREG
,
out
.
Attr
.
Mode
)
}
return
fuse
.
OK
return
fuse
.
OK
}
}
...
@@ -269,22 +326,6 @@ func (b *rawBridge) SetAttr(input *fuse.SetAttrIn, out *fuse.AttrOut) (code fuse
...
@@ -269,22 +326,6 @@ func (b *rawBridge) SetAttr(input *fuse.SetAttrIn, out *fuse.AttrOut) (code fuse
return
code
return
code
}
}
func
(
b
*
rawBridge
)
Mknod
(
input
*
fuse
.
MknodIn
,
name
string
,
out
*
fuse
.
EntryOut
)
(
code
fuse
.
Status
)
{
return
fuse
.
ENOSYS
}
func
(
b
*
rawBridge
)
Mkdir
(
input
*
fuse
.
MkdirIn
,
name
string
,
out
*
fuse
.
EntryOut
)
(
code
fuse
.
Status
)
{
return
fuse
.
ENOSYS
}
func
(
b
*
rawBridge
)
Unlink
(
header
*
fuse
.
InHeader
,
name
string
)
(
code
fuse
.
Status
)
{
return
fuse
.
ENOSYS
}
func
(
b
*
rawBridge
)
Rmdir
(
header
*
fuse
.
InHeader
,
name
string
)
(
code
fuse
.
Status
)
{
return
fuse
.
ENOSYS
}
func
(
b
*
rawBridge
)
Rename
(
input
*
fuse
.
RenameIn
,
oldName
string
,
newName
string
)
(
code
fuse
.
Status
)
{
func
(
b
*
rawBridge
)
Rename
(
input
*
fuse
.
RenameIn
,
oldName
string
,
newName
string
)
(
code
fuse
.
Status
)
{
return
fuse
.
ENOSYS
return
fuse
.
ENOSYS
}
}
...
...
nodefs/loopback.go
View file @
6b4bb98b
...
@@ -62,6 +62,59 @@ func (n *loopbackNode) Lookup(ctx context.Context, name string, out *fuse.EntryO
...
@@ -62,6 +62,59 @@ func (n *loopbackNode) Lookup(ctx context.Context, name string, out *fuse.EntryO
return
ch
,
fuse
.
OK
return
ch
,
fuse
.
OK
}
}
func
(
n
*
loopbackNode
)
Mknod
(
ctx
context
.
Context
,
name
string
,
mode
,
rdev
uint32
,
out
*
fuse
.
EntryOut
)
(
*
Inode
,
fuse
.
Status
)
{
p
:=
filepath
.
Join
(
n
.
path
(),
name
)
err
:=
syscall
.
Mknod
(
p
,
mode
,
int
(
rdev
))
if
err
!=
nil
{
return
nil
,
fuse
.
ToStatus
(
err
)
}
st
:=
syscall
.
Stat_t
{}
if
err
:=
syscall
.
Lstat
(
p
,
&
st
);
err
!=
nil
{
syscall
.
Rmdir
(
p
)
return
nil
,
fuse
.
ToStatus
(
err
)
}
out
.
Attr
.
FromStat
(
&
st
)
node
:=
&
loopbackNode
{
rootNode
:
n
.
rootNode
}
ch
:=
n
.
inode
()
.
NewInode
(
node
,
out
.
Attr
.
Mode
,
out
.
Attr
.
Ino
)
return
ch
,
fuse
.
OK
}
func
(
n
*
loopbackNode
)
Mkdir
(
ctx
context
.
Context
,
name
string
,
mode
uint32
,
out
*
fuse
.
EntryOut
)
(
*
Inode
,
fuse
.
Status
)
{
// NOSUBMIT what about umask
p
:=
filepath
.
Join
(
n
.
path
(),
name
)
err
:=
os
.
Mkdir
(
p
,
os
.
FileMode
(
mode
))
if
err
!=
nil
{
return
nil
,
fuse
.
ToStatus
(
err
)
}
st
:=
syscall
.
Stat_t
{}
if
err
:=
syscall
.
Lstat
(
p
,
&
st
);
err
!=
nil
{
syscall
.
Rmdir
(
p
)
return
nil
,
fuse
.
ToStatus
(
err
)
}
out
.
Attr
.
FromStat
(
&
st
)
node
:=
&
loopbackNode
{
rootNode
:
n
.
rootNode
}
ch
:=
n
.
inode
()
.
NewInode
(
node
,
out
.
Attr
.
Mode
,
out
.
Attr
.
Ino
)
return
ch
,
fuse
.
OK
}
func
(
n
*
loopbackNode
)
Rmdir
(
ctx
context
.
Context
,
name
string
)
fuse
.
Status
{
p
:=
filepath
.
Join
(
n
.
path
(),
name
)
err
:=
syscall
.
Rmdir
(
p
)
return
fuse
.
ToStatus
(
err
)
}
func
(
n
*
loopbackNode
)
Unlink
(
ctx
context
.
Context
,
name
string
)
fuse
.
Status
{
p
:=
filepath
.
Join
(
n
.
path
(),
name
)
err
:=
syscall
.
Unlink
(
p
)
return
fuse
.
ToStatus
(
err
)
}
func
(
n
*
loopbackNode
)
Create
(
ctx
context
.
Context
,
name
string
,
flags
uint32
,
mode
uint32
)
(
inode
*
Inode
,
fh
File
,
fuseFlags
uint32
,
code
fuse
.
Status
)
{
func
(
n
*
loopbackNode
)
Create
(
ctx
context
.
Context
,
name
string
,
flags
uint32
,
mode
uint32
)
(
inode
*
Inode
,
fh
File
,
fuseFlags
uint32
,
code
fuse
.
Status
)
{
p
:=
filepath
.
Join
(
n
.
path
(),
name
)
p
:=
filepath
.
Join
(
n
.
path
(),
name
)
...
...
nodefs/simple_test.go
View file @
6b4bb98b
...
@@ -88,7 +88,8 @@ func TestBasic(t *testing.T) {
...
@@ -88,7 +88,8 @@ func TestBasic(t *testing.T) {
tc
.
writeOrig
(
"file"
,
"hello"
,
0644
)
tc
.
writeOrig
(
"file"
,
"hello"
,
0644
)
fi
,
err
:=
os
.
Lstat
(
tc
.
mntDir
+
"/file"
)
fn
:=
tc
.
mntDir
+
"/file"
fi
,
err
:=
os
.
Lstat
(
fn
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"Lstat: %v"
,
err
)
t
.
Fatalf
(
"Lstat: %v"
,
err
)
}
}
...
@@ -101,6 +102,14 @@ func TestBasic(t *testing.T) {
...
@@ -101,6 +102,14 @@ func TestBasic(t *testing.T) {
if
got
,
want
:=
stat
.
Mode
,
uint32
(
fuse
.
S_IFREG
|
0644
);
got
!=
want
{
if
got
,
want
:=
stat
.
Mode
,
uint32
(
fuse
.
S_IFREG
|
0644
);
got
!=
want
{
t
.
Errorf
(
"got mode %o, want %o"
,
got
,
want
)
t
.
Errorf
(
"got mode %o, want %o"
,
got
,
want
)
}
}
if
err
:=
os
.
Remove
(
fn
);
err
!=
nil
{
t
.
Errorf
(
"Remove: %v"
,
err
)
}
if
fi
,
err
:=
os
.
Lstat
(
fn
);
err
==
nil
{
t
.
Errorf
(
"Lstat after remove: got file %v"
,
fi
)
}
}
}
func
TestFile
(
t
*
testing
.
T
)
{
func
TestFile
(
t
*
testing
.
T
)
{
...
@@ -216,3 +225,22 @@ func TestFileFdLeak(t *testing.T) {
...
@@ -216,3 +225,22 @@ func TestFileFdLeak(t *testing.T) {
t
.
Errorf
(
"found %d used file handles, should be <= 3"
,
got
)
t
.
Errorf
(
"found %d used file handles, should be <= 3"
,
got
)
}
}
}
}
func
TestMkdir
(
t
*
testing
.
T
)
{
tc
:=
newTestCase
(
t
)
defer
tc
.
Clean
()
if
err
:=
os
.
Mkdir
(
tc
.
mntDir
+
"/dir"
,
0755
);
err
!=
nil
{
t
.
Fatalf
(
"Mkdir: %v"
,
err
)
}
if
fi
,
err
:=
os
.
Lstat
(
tc
.
mntDir
+
"/dir"
);
err
!=
nil
{
t
.
Fatalf
(
"Lstat %v"
,
err
)
}
else
if
!
fi
.
IsDir
()
{
t
.
Fatalf
(
"is not a directory"
)
}
if
err
:=
os
.
Remove
(
tc
.
mntDir
+
"/dir"
);
err
!=
nil
{
t
.
Fatalf
(
"Remove: %v"
,
err
)
}
}
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