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
340517c2
Commit
340517c2
authored
Aug 13, 2010
by
Ivan Krasin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
A step to decompose low level details from the FileSystem logic
parent
a63a983f
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
112 additions
and
78 deletions
+112
-78
fuse/fuse.go
fuse/fuse.go
+110
-76
fuse/fuse_test.go
fuse/fuse_test.go
+2
-2
No files found.
fuse/fuse.go
View file @
340517c2
package
fuse
package
fuse
// Written with a look to http://ptspts.blogspot.com/2009/11/fuse-protocol-tutorial-for-linux-26.html
import
(
import
(
"bytes"
"bytes"
"encoding/binary"
"encoding/binary"
"fmt"
"fmt"
"io"
"os"
"os"
)
)
...
@@ -14,8 +13,8 @@ const (
...
@@ -14,8 +13,8 @@ const (
)
)
type
FileSystem
interface
{
type
FileSystem
interface
{
Init
(
in
*
InitIn
)
(
out
*
InitOut
,
code
Error
)
Init
(
in
*
InitIn
)
(
out
*
InitOut
,
code
Error
,
err
os
.
Error
)
GetAttr
(
h
*
InHeader
,
in
*
GetAttrIn
)
(
out
*
AttrOut
,
code
Error
)
GetAttr
(
h
*
InHeader
,
in
*
GetAttrIn
)
(
out
*
AttrOut
,
code
Error
,
err
os
.
Error
)
}
}
var
was
bool
var
was
bool
...
@@ -50,11 +49,11 @@ func loop(f *os.File, fs FileSystem, errors chan os.Error) {
...
@@ -50,11 +49,11 @@ func loop(f *os.File, fs FileSystem, errors chan os.Error) {
break
break
}
}
handle
(
fs
,
buf
[
0
:
n
],
toW
,
errors
)
dispatch
(
fs
,
buf
[
0
:
n
],
toW
,
errors
)
}
}
}
}
func
handle
(
fs
FileSystem
,
in_data
[]
byte
,
toW
chan
[][]
byte
,
errors
chan
os
.
Error
)
{
func
dispatch
(
fs
FileSystem
,
in_data
[]
byte
,
toW
chan
[][]
byte
,
errors
chan
os
.
Error
)
{
fmt
.
Printf
(
"in_data: %v
\n
"
,
in_data
)
fmt
.
Printf
(
"in_data: %v
\n
"
,
in_data
)
r
:=
bytes
.
NewBuffer
(
in_data
)
r
:=
bytes
.
NewBuffer
(
in_data
)
h
:=
new
(
InHeader
)
h
:=
new
(
InHeader
)
...
@@ -66,62 +65,125 @@ func handle(fs FileSystem, in_data []byte, toW chan [][]byte, errors chan os.Err
...
@@ -66,62 +65,125 @@ func handle(fs FileSystem, in_data []byte, toW chan [][]byte, errors chan os.Err
errors
<-
err
errors
<-
err
return
return
}
}
var
out
interface
{}
var
out
[][]
byte
var
result
Error
=
OK
fmt
.
Printf
(
"Opcode: %v, NodeId: %v, h: %v
\n
"
,
h
.
Opcode
,
h
.
NodeId
,
h
)
fmt
.
Printf
(
"Opcode: %v, NodeId: %v, h: %v
\n
"
,
h
.
Opcode
,
h
.
NodeId
,
h
)
switch
h
.
Opcode
{
switch
h
.
Opcode
{
case
FUSE_INIT
:
case
FUSE_INIT
:
out
,
err
=
initFuse
(
fs
,
h
,
r
)
case
FUSE_FORGET
:
return
case
FUSE_GETATTR
:
out
,
err
=
getAttr
(
fs
,
h
,
r
)
case
FUSE_GETXATTR
:
out
,
err
=
getXAttr
(
h
,
r
)
case
FUSE_OPENDIR
:
out
,
err
=
openDir
(
h
,
r
)
case
FUSE_READDIR
:
out
,
err
=
readDir
(
h
,
r
)
case
FUSE_LOOKUP
:
out
,
err
=
lookup
(
h
,
r
)
case
FUSE_RELEASEDIR
:
out
,
err
=
releaseDir
(
h
,
r
)
default
:
errors
<-
os
.
NewError
(
fmt
.
Sprintf
(
"Unsupported OpCode: %d"
,
h
.
Opcode
))
out
,
err
=
serialize
(
h
,
EIO
,
nil
)
}
if
err
!=
nil
{
errors
<-
err
out
,
err
=
serialize
(
h
,
EIO
,
nil
)
}
if
out
==
nil
||
len
(
out
)
==
0
{
fmt
.
Printf
(
"out is empty
\n
"
)
return
}
fmt
.
Printf
(
"Sending to writer: %v
\n
"
,
out
)
toW
<-
out
}
func
serialize
(
h
*
InHeader
,
res
Error
,
out
interface
{})
(
data
[][]
byte
,
err
os
.
Error
)
{
b
:=
new
(
bytes
.
Buffer
)
out_data
:=
make
([]
byte
,
0
)
fmt
.
Printf
(
"OpCode: %v result: %v
\n
"
,
h
.
Opcode
,
res
)
if
out
!=
nil
&&
res
==
OK
{
fmt
.
Printf
(
"out = %v, out == nil: %v
\n
"
,
out
,
out
==
nil
)
err
=
binary
.
Write
(
b
,
binary
.
LittleEndian
,
out
)
if
err
==
nil
{
out_data
=
b
.
Bytes
()
}
else
{
err
=
os
.
NewError
(
fmt
.
Sprintf
(
"Can serialize out: %v"
,
err
))
return
}
}
fmt
.
Printf
(
"out_data: %v, len(out_data): %d, SizeOfOutHeader: %d
\n
"
,
out_data
,
len
(
out_data
),
SizeOfOutHeader
)
var
hout
OutHeader
hout
.
Unique
=
h
.
Unique
hout
.
Error
=
int32
(
res
)
hout
.
Length
=
uint32
(
len
(
out_data
)
+
SizeOfOutHeader
)
b
=
new
(
bytes
.
Buffer
)
err
=
binary
.
Write
(
b
,
binary
.
LittleEndian
,
&
hout
)
if
err
!=
nil
{
return
}
_
,
_
=
b
.
Write
(
out_data
)
data
=
[][]
byte
{
b
.
Bytes
()
}
return
}
func
initFuse
(
fs
FileSystem
,
h
*
InHeader
,
r
io
.
Reader
)
(
data
[][]
byte
,
err
os
.
Error
)
{
in
:=
new
(
InitIn
)
in
:=
new
(
InitIn
)
err
=
binary
.
Read
(
r
,
binary
.
LittleEndian
,
in
)
err
=
binary
.
Read
(
r
,
binary
.
LittleEndian
,
in
)
if
err
!=
nil
{
if
err
!=
nil
{
break
return
}
}
fmt
.
Printf
(
"in: %v
\n
"
,
in
)
fmt
.
Printf
(
"in: %v
\n
"
,
in
)
var
init_
out
*
InitOut
var
out
*
InitOut
init_out
,
result
=
fs
.
Init
(
in
)
out
,
res
,
err
:
=
fs
.
Init
(
in
)
if
init_out
!=
nil
{
if
err
!=
nil
{
out
=
init_out
return
}
}
case
FUSE_FORGET
:
data
,
err
=
serialize
(
h
,
res
,
out
)
return
return
}
case
FUSE_GETATTR
:
func
getAttr
(
fs
FileSystem
,
h
*
InHeader
,
r
io
.
Reader
)
(
data
[][]
byte
,
err
os
.
Error
)
{
in
:=
new
(
GetAttrIn
)
in
:=
new
(
GetAttrIn
)
err
=
binary
.
Read
(
r
,
binary
.
LittleEndian
,
in
)
err
=
binary
.
Read
(
r
,
binary
.
LittleEndian
,
in
)
if
err
!=
nil
{
if
err
!=
nil
{
break
return
}
}
fmt
.
Printf
(
"FUSE_GETATTR: %v
\n
"
,
in
)
fmt
.
Printf
(
"FUSE_GETATTR: %v
\n
"
,
in
)
var
attr_
out
*
AttrOut
var
out
*
AttrOut
attr_out
,
result
=
fs
.
GetAttr
(
h
,
in
)
out
,
res
,
err
:
=
fs
.
GetAttr
(
h
,
in
)
if
attr_out
!=
nil
{
if
err
!=
nil
{
out
=
attr_out
return
}
}
case
FUSE_GETXATTR
:
data
,
err
=
serialize
(
h
,
res
,
out
)
re
sult
=
OK
re
turn
out
=
new
(
GetXAttrOut
)
}
case
FUSE_OPENDIR
:
func
getXAttr
(
h
*
InHeader
,
r
io
.
Reader
)
(
data
[][]
byte
,
err
os
.
Error
)
{
out
:=
new
(
GetXAttrOut
)
data
,
err
=
serialize
(
h
,
OK
,
out
)
return
}
func
openDir
(
h
*
InHeader
,
r
io
.
Reader
)
(
data
[][]
byte
,
err
os
.
Error
)
{
in
:=
new
(
OpenIn
)
in
:=
new
(
OpenIn
)
err
=
binary
.
Read
(
r
,
binary
.
LittleEndian
,
in
)
err
=
binary
.
Read
(
r
,
binary
.
LittleEndian
,
in
)
if
err
!=
nil
{
if
err
!=
nil
{
break
return
}
}
fmt
.
Printf
(
"FUSE_OPENDIR: %v
\n
"
,
in
)
fmt
.
Printf
(
"FUSE_OPENDIR: %v
\n
"
,
in
)
var
open_out
*
OpenOut
out
:=
new
(
OpenOut
)
open_out
=
new
(
OpenOut
)
out
.
Fh
=
1
open_out
.
Fh
=
1
out
=
open_out
was
=
false
was
=
false
res
:=
OK
data
,
err
=
serialize
(
h
,
res
,
out
)
return
}
case
FUSE_READDIR
:
func
readDir
(
h
*
InHeader
,
r
io
.
Reader
)
(
data
[][]
byte
,
err
os
.
Error
)
{
if
was
{
if
was
{
break
data
,
err
=
serialize
(
h
,
OK
,
nil
)
return
}
}
in
:=
new
(
ReadIn
)
in
:=
new
(
ReadIn
)
err
=
binary
.
Read
(
r
,
binary
.
LittleEndian
,
in
)
err
=
binary
.
Read
(
r
,
binary
.
LittleEndian
,
in
)
if
err
!=
nil
{
if
err
!=
nil
{
break
return
}
}
fmt
.
Printf
(
"FUSE_READDIR: %v
\n
"
,
in
)
fmt
.
Printf
(
"FUSE_READDIR: %v
\n
"
,
in
)
...
@@ -138,54 +200,26 @@ func handle(fs FileSystem, in_data []byte, toW chan [][]byte, errors chan os.Err
...
@@ -138,54 +200,26 @@ func handle(fs FileSystem, in_data []byte, toW chan [][]byte, errors chan os.Err
}
}
buf
.
Write
([]
byte
(
"hello12"
))
buf
.
Write
([]
byte
(
"hello12"
))
buf
.
WriteByte
(
0
)
buf
.
WriteByte
(
0
)
out
=
buf
.
Bytes
()
out
:
=
buf
.
Bytes
()
was
=
true
was
=
true
case
FUSE_LOOKUP
:
res
:=
OK
data
,
err
=
serialize
(
h
,
res
,
out
)
return
}
func
lookup
(
h
*
InHeader
,
r
*
bytes
.
Buffer
)
(
data
[][]
byte
,
err
os
.
Error
)
{
filename
:=
string
(
r
.
Bytes
())
filename
:=
string
(
r
.
Bytes
())
fmt
.
Printf
(
"filename: %s
\n
"
,
filename
)
fmt
.
Printf
(
"filename: %s
\n
"
,
filename
)
entry_
out
:=
new
(
EntryOut
)
out
:=
new
(
EntryOut
)
entry_
out
.
NodeId
=
h
.
NodeId
+
1
out
.
NodeId
=
h
.
NodeId
+
1
entry_
out
.
Mode
=
S_IFDIR
out
.
Mode
=
S_IFDIR
out
=
entry_out
res
:=
OK
case
FUSE_RELEASEDIR
:
data
,
err
=
serialize
(
h
,
res
,
out
)
return
return
}
default
:
func
releaseDir
(
h
*
InHeader
,
r
io
.
Reader
)
(
data
[][]
byte
,
err
os
.
Error
)
{
errors
<-
os
.
NewError
(
fmt
.
Sprintf
(
"Unsupported OpCode: %d"
,
h
.
Opcode
))
return
result
=
EIO
}
if
err
!=
nil
{
errors
<-
err
out
=
nil
result
=
EIO
// Add sending result msg with error
}
b
:=
new
(
bytes
.
Buffer
)
out_data
:=
make
([]
byte
,
0
)
fmt
.
Printf
(
"OpCode: %v result: %v
\n
"
,
h
.
Opcode
,
result
)
if
out
!=
nil
&&
result
==
OK
{
fmt
.
Printf
(
"out = %v, out == nil: %v
\n
"
,
out
,
out
==
nil
)
err
=
binary
.
Write
(
b
,
binary
.
LittleEndian
,
out
)
if
err
==
nil
{
out_data
=
b
.
Bytes
()
}
else
{
errors
<-
os
.
NewError
(
fmt
.
Sprintf
(
"Can serialize out: %v"
,
err
))
}
}
fmt
.
Printf
(
"out_data: %v, len(out_data): %d, SizeOfOutHeader: %d
\n
"
,
out_data
,
len
(
out_data
),
SizeOfOutHeader
)
var
hout
OutHeader
hout
.
Unique
=
h
.
Unique
hout
.
Error
=
int32
(
result
)
hout
.
Length
=
uint32
(
len
(
out_data
)
+
SizeOfOutHeader
)
b
=
new
(
bytes
.
Buffer
)
err
=
binary
.
Write
(
b
,
binary
.
LittleEndian
,
&
hout
)
if
err
!=
nil
{
errors
<-
err
return
}
_
,
_
=
b
.
Write
(
out_data
)
fmt
.
Printf
(
"Sending to writer: %v
\n
"
,
b
.
Bytes
())
toW
<-
[][]
byte
{
b
.
Bytes
()}
}
}
func
writer
(
f
*
os
.
File
,
in
chan
[][]
byte
,
errors
chan
os
.
Error
)
{
func
writer
(
f
*
os
.
File
,
in
chan
[][]
byte
,
errors
chan
os
.
Error
)
{
...
...
fuse/fuse_test.go
View file @
340517c2
...
@@ -13,7 +13,7 @@ const (
...
@@ -13,7 +13,7 @@ const (
type
testFuse
struct
{}
type
testFuse
struct
{}
func
(
fs
*
testFuse
)
Init
(
in
*
InitIn
)
(
out
*
InitOut
,
code
Error
)
{
func
(
fs
*
testFuse
)
Init
(
in
*
InitIn
)
(
out
*
InitOut
,
code
Error
,
err
os
.
Error
)
{
if
in
.
Major
!=
FUSE_KERNEL_VERSION
{
if
in
.
Major
!=
FUSE_KERNEL_VERSION
{
fmt
.
Printf
(
"Major versions does not match. Given %d, want %d
\n
"
,
in
.
Major
,
FUSE_KERNEL_VERSION
)
fmt
.
Printf
(
"Major versions does not match. Given %d, want %d
\n
"
,
in
.
Major
,
FUSE_KERNEL_VERSION
)
code
=
EIO
code
=
EIO
...
@@ -32,7 +32,7 @@ func (fs *testFuse) Init(in *InitIn) (out *InitOut, code Error) {
...
@@ -32,7 +32,7 @@ func (fs *testFuse) Init(in *InitIn) (out *InitOut, code Error) {
return
return
}
}
func
(
fs
*
testFuse
)
GetAttr
(
h
*
InHeader
,
in
*
GetAttrIn
)
(
out
*
AttrOut
,
code
Error
)
{
func
(
fs
*
testFuse
)
GetAttr
(
h
*
InHeader
,
in
*
GetAttrIn
)
(
out
*
AttrOut
,
code
Error
,
err
os
.
Error
)
{
out
=
new
(
AttrOut
)
out
=
new
(
AttrOut
)
out
.
Ino
=
h
.
NodeId
out
.
Ino
=
h
.
NodeId
out
.
Mode
=
S_IFDIR
out
.
Mode
=
S_IFDIR
...
...
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