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
Kirill Smelkov
go-fuse
Commits
037f7b0e
Commit
037f7b0e
authored
Mar 01, 2019
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nodefs: symlink/readlink.
parent
f8379610
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
88 additions
and
4 deletions
+88
-4
nodefs/README.md
nodefs/README.md
+4
-0
nodefs/api.go
nodefs/api.go
+2
-1
nodefs/bridge.go
nodefs/bridge.go
+18
-3
nodefs/default.go
nodefs/default.go
+10
-0
nodefs/loopback.go
nodefs/loopback.go
+37
-0
nodefs/simple_test.go
nodefs/simple_test.go
+17
-0
No files found.
nodefs/README.md
View file @
037f7b0e
...
...
@@ -60,4 +60,8 @@ To decide
*
cancellation through context.Context (standard, more GC overhead)
or a custom context (could reuse across requests.)?
*
Readlink return: []byte or string ?
*
Should Operations.Lookup return
*
Inode or Operations ?
*
Should bridge.Lookup() add the child, bridge.Unlink remove the child, etc.?
nodefs/api.go
View file @
037f7b0e
...
...
@@ -105,7 +105,8 @@ type Operations interface {
Unlink
(
ctx
context
.
Context
,
name
string
)
fuse
.
Status
Rename
(
ctx
context
.
Context
,
name
string
,
newParent
Operations
,
newName
string
,
flags
uint32
)
fuse
.
Status
Create
(
ctx
context
.
Context
,
name
string
,
flags
uint32
,
mode
uint32
)
(
node
*
Inode
,
fh
FileHandle
,
fuseFlags
uint32
,
code
fuse
.
Status
)
Symlink
(
ctx
context
.
Context
,
target
,
name
string
,
out
*
fuse
.
EntryOut
)
(
node
*
Inode
,
code
fuse
.
Status
)
Readlink
(
ctx
context
.
Context
)
(
string
,
fuse
.
Status
)
Open
(
ctx
context
.
Context
,
flags
uint32
)
(
fh
FileHandle
,
fuseFlags
uint32
,
code
fuse
.
Status
)
Read
(
ctx
context
.
Context
,
f
FileHandle
,
dest
[]
byte
,
off
int64
)
(
fuse
.
ReadResult
,
fuse
.
Status
)
...
...
nodefs/bridge.go
View file @
037f7b0e
...
...
@@ -374,12 +374,27 @@ func (b *rawBridge) Link(input *fuse.LinkIn, filename string, out *fuse.EntryOut
return
fuse
.
ENOSYS
}
func
(
b
*
rawBridge
)
Symlink
(
header
*
fuse
.
InHeader
,
pointedTo
string
,
linkName
string
,
out
*
fuse
.
EntryOut
)
(
code
fuse
.
Status
)
{
return
fuse
.
ENOSYS
func
(
b
*
rawBridge
)
Symlink
(
header
*
fuse
.
InHeader
,
target
string
,
name
string
,
out
*
fuse
.
EntryOut
)
(
code
fuse
.
Status
)
{
log
.
Println
(
"symlink1"
)
parent
,
_
:=
b
.
inode
(
header
.
NodeId
,
0
)
child
,
code
:=
parent
.
node
.
Symlink
(
context
.
TODO
(),
target
,
name
,
out
)
if
!
code
.
Ok
()
{
return
code
}
b
.
addNewChild
(
parent
,
name
,
child
,
nil
,
out
)
b
.
setEntryOutTimeout
(
out
)
return
fuse
.
OK
}
func
(
b
*
rawBridge
)
Readlink
(
header
*
fuse
.
InHeader
)
(
out
[]
byte
,
code
fuse
.
Status
)
{
return
nil
,
fuse
.
ENOSYS
n
,
_
:=
b
.
inode
(
header
.
NodeId
,
0
)
result
,
code
:=
n
.
node
.
Readlink
(
context
.
TODO
())
if
!
code
.
Ok
()
{
return
nil
,
code
}
return
[]
byte
(
result
),
fuse
.
OK
}
func
(
b
*
rawBridge
)
Access
(
input
*
fuse
.
AccessIn
)
(
code
fuse
.
Status
)
{
...
...
nodefs/default.go
View file @
037f7b0e
...
...
@@ -6,6 +6,7 @@ package nodefs
import
(
"context"
"log"
"time"
"github.com/hanwen/go-fuse/fuse"
...
...
@@ -57,6 +58,15 @@ func (n *DefaultOperations) Read(ctx context.Context, f FileHandle, dest []byte,
return
nil
,
fuse
.
ENOSYS
}
func
(
n
*
DefaultOperations
)
Symlink
(
ctx
context
.
Context
,
target
,
name
string
,
out
*
fuse
.
EntryOut
)
(
node
*
Inode
,
code
fuse
.
Status
)
{
log
.
Println
(
"defsyml"
)
return
nil
,
fuse
.
ENOSYS
}
func
(
n
*
DefaultOperations
)
Readlink
(
ctx
context
.
Context
)
(
string
,
fuse
.
Status
)
{
return
""
,
fuse
.
ENOSYS
}
func
(
n
*
DefaultOperations
)
Fsync
(
ctx
context
.
Context
,
f
FileHandle
,
flags
uint32
)
fuse
.
Status
{
if
f
!=
nil
{
return
f
.
Fsync
(
ctx
,
flags
)
...
...
nodefs/loopback.go
View file @
037f7b0e
...
...
@@ -6,6 +6,7 @@ package nodefs
import
(
"context"
"log"
"os"
"path/filepath"
"sync"
...
...
@@ -14,6 +15,8 @@ import (
"github.com/hanwen/go-fuse/fuse"
)
var
_
=
log
.
Printf
type
loopbackRoot
struct
{
loopbackNode
...
...
@@ -183,6 +186,40 @@ func (n *loopbackNode) Create(ctx context.Context, name string, flags uint32, mo
return
ch
,
lf
,
0
,
fuse
.
OK
}
func
(
n
*
loopbackNode
)
Symlink
(
ctx
context
.
Context
,
target
,
name
string
,
out
*
fuse
.
EntryOut
)
(
*
Inode
,
fuse
.
Status
)
{
p
:=
filepath
.
Join
(
n
.
path
(),
name
)
err
:=
syscall
.
Symlink
(
target
,
p
)
if
err
!=
nil
{
return
nil
,
fuse
.
ToStatus
(
err
)
}
st
:=
syscall
.
Stat_t
{}
if
syscall
.
Lstat
(
p
,
&
st
);
err
!=
nil
{
syscall
.
Unlink
(
p
)
return
nil
,
fuse
.
ToStatus
(
err
)
}
node
:=
n
.
rootNode
.
newLoopbackNode
()
ch
:=
n
.
inode
()
.
NewInode
(
node
,
st
.
Mode
,
idFromStat
(
&
st
))
out
.
Attr
.
FromStat
(
&
st
)
return
ch
,
fuse
.
OK
}
func
(
n
*
loopbackNode
)
Readlink
(
ctx
context
.
Context
)
(
string
,
fuse
.
Status
)
{
p
:=
n
.
path
()
for
l
:=
256
;
;
l
*=
2
{
buf
:=
make
([]
byte
,
l
)
sz
,
err
:=
syscall
.
Readlink
(
p
,
buf
)
if
err
!=
nil
{
return
""
,
fuse
.
ToStatus
(
err
)
}
if
sz
<
len
(
buf
)
{
return
string
(
buf
[
:
sz
]),
fuse
.
OK
}
}
}
func
(
n
*
loopbackNode
)
Open
(
ctx
context
.
Context
,
flags
uint32
)
(
fh
FileHandle
,
fuseFlags
uint32
,
code
fuse
.
Status
)
{
p
:=
n
.
path
()
f
,
err
:=
os
.
OpenFile
(
p
,
int
(
flags
),
0
)
...
...
nodefs/simple_test.go
View file @
037f7b0e
...
...
@@ -407,3 +407,20 @@ func TestParallelFileOpen(t *testing.T) {
}
wg
.
Wait
()
}
func
TestSymlink
(
t
*
testing
.
T
)
{
tc
:=
newTestCase
(
t
)
defer
tc
.
Clean
()
fn
:=
tc
.
mntDir
+
"/link"
target
:=
"target"
if
err
:=
os
.
Symlink
(
target
,
fn
);
err
!=
nil
{
t
.
Fatalf
(
"Symlink: %v"
,
err
)
}
if
got
,
err
:=
os
.
Readlink
(
fn
);
err
!=
nil
{
t
.
Fatalf
(
"Readlink: %v"
,
err
)
}
else
if
got
!=
target
{
t
.
Errorf
(
"Readlink: got %q, want %q"
,
got
,
target
)
}
}
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