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
5f24a9ec
Commit
5f24a9ec
authored
Mar 25, 2011
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement ListXAttr.
parent
133852b3
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
121 additions
and
21 deletions
+121
-21
examplelib/stackfs.go
examplelib/stackfs.go
+2
-0
fuse/default.go
fuse/default.go
+8
-0
fuse/fuse.go
fuse/fuse.go
+9
-5
fuse/loopback.go
fuse/loopback.go
+6
-0
fuse/misc.go
fuse/misc.go
+2
-2
fuse/pathfilesystem.go
fuse/pathfilesystem.go
+20
-0
fuse/timingfs.go
fuse/timingfs.go
+6
-0
fuse/timingrawfs.go
fuse/timingrawfs.go
+6
-0
fuse/types.go
fuse/types.go
+4
-2
fuse/wrappedfs.go
fuse/wrappedfs.go
+11
-0
fuse/xattr.go
fuse/xattr.go
+6
-2
fuse/xattr_test.go
fuse/xattr_test.go
+41
-10
No files found.
examplelib/stackfs.go
View file @
5f24a9ec
...
...
@@ -87,6 +87,8 @@ type SubmountFileSystem struct {
nextFreeInode
uint64
Options
SubmountFileSystemOptions
fuse
.
DefaultRawFuseFileSystem
}
type
SubmountFileSystemOptions
struct
{
...
...
fuse/default.go
View file @
5f24a9ec
...
...
@@ -73,6 +73,10 @@ func (me *DefaultRawFuseFileSystem) GetXAttr(header *InHeader, attr string) (dat
return
nil
,
ENOSYS
}
func
(
me
*
DefaultRawFuseFileSystem
)
ListXAttr
(
header
*
InHeader
)
(
data
[]
byte
,
code
Status
)
{
return
nil
,
ENOSYS
}
func
(
me
*
DefaultRawFuseFileSystem
)
Access
(
header
*
InHeader
,
input
*
AccessIn
)
(
code
Status
)
{
return
ENOSYS
}
...
...
@@ -153,6 +157,10 @@ func (me *DefaultPathFilesystem) GetXAttr(name string, attr string) ([]byte, Sta
return
nil
,
ENOSYS
}
func
(
me
*
DefaultPathFilesystem
)
ListXAttr
(
name
string
)
([]
string
,
Status
)
{
return
nil
,
ENOSYS
}
func
(
me
*
DefaultPathFilesystem
)
Readlink
(
name
string
)
(
string
,
Status
)
{
return
""
,
ENOSYS
}
...
...
fuse/fuse.go
View file @
5f24a9ec
...
...
@@ -475,9 +475,9 @@ func (me *MountState) dispatch(req *fuseRequest) {
// case FUSE_SETXATTR:
// status = fs.SetXAttr(h, (*SetXAttrIn)(inData))
case
FUSE_GETXATTR
:
req
.
data
,
req
.
flatData
,
status
=
doGetXAttr
(
me
,
h
,
(
*
GetXAttrIn
)(
inData
),
filename
)
// case FUSE_LISTXATTR:
req
.
data
,
req
.
flatData
,
status
=
doGetXAttr
(
me
,
h
,
(
*
GetXAttrIn
)(
inData
),
filename
,
h
.
Opcode
)
case
FUSE_LISTXATTR
:
req
.
data
,
req
.
flatData
,
status
=
doGetXAttr
(
me
,
h
,
(
*
GetXAttrIn
)(
inData
),
filename
,
h
.
Opcode
)
// case FUSE_REMOVEXATTR
case
FUSE_ACCESS
:
...
...
@@ -642,8 +642,12 @@ func doSetattr(state *MountState, header *InHeader, input *SetAttrIn) (out unsaf
return
unsafe
.
Pointer
(
o
),
s
}
func
doGetXAttr
(
state
*
MountState
,
header
*
InHeader
,
input
*
GetXAttrIn
,
attr
string
)
(
out
unsafe
.
Pointer
,
data
[]
byte
,
code
Status
)
{
func
doGetXAttr
(
state
*
MountState
,
header
*
InHeader
,
input
*
GetXAttrIn
,
attr
string
,
opcode
uint32
)
(
out
unsafe
.
Pointer
,
data
[]
byte
,
code
Status
)
{
if
opcode
==
FUSE_GETXATTR
{
data
,
code
=
state
.
fileSystem
.
GetXAttr
(
header
,
attr
)
}
else
{
data
,
code
=
state
.
fileSystem
.
ListXAttr
(
header
)
}
if
code
!=
OK
{
return
nil
,
nil
,
code
}
...
...
fuse/loopback.go
View file @
5f24a9ec
...
...
@@ -152,6 +152,12 @@ func (me *LoopbackFileSystem) GetXAttr(name string, attr string) ([]byte, Status
return
data
,
Status
(
errNo
)
}
func
(
me
*
LoopbackFileSystem
)
ListXAttr
(
name
string
)
([]
string
,
Status
)
{
data
,
errNo
:=
ListXAttr
(
me
.
GetPath
(
name
))
return
data
,
Status
(
errNo
)
}
func
(
me
*
LoopbackFileSystem
)
FillOptions
(
options
*
PathFileSystemConnectorOptions
)
{
options
.
NegativeTimeout
=
3.0
options
.
AttrTimeout
=
3.0
...
...
fuse/misc.go
View file @
5f24a9ec
...
...
@@ -281,7 +281,7 @@ func init() {
FUSE_FSYNC
:
unsafe
.
Sizeof
(
FsyncIn
{}),
FUSE_SETXATTR
:
unsafe
.
Sizeof
(
SetXAttrIn
{}),
FUSE_GETXATTR
:
unsafe
.
Sizeof
(
GetXAttrIn
{}),
FUSE_LISTXATTR
:
0
,
FUSE_LISTXATTR
:
unsafe
.
Sizeof
(
GetXAttrIn
{})
,
FUSE_REMOVEXATTR
:
0
,
FUSE_FLUSH
:
unsafe
.
Sizeof
(
FlushIn
{}),
FUSE_INIT
:
unsafe
.
Sizeof
(
InitIn
{}),
...
...
@@ -322,7 +322,7 @@ func init() {
FUSE_FSYNC
:
0
,
FUSE_SETXATTR
:
0
,
FUSE_GETXATTR
:
unsafe
.
Sizeof
(
GetXAttrOut
{}),
FUSE_LISTXATTR
:
0
,
FUSE_LISTXATTR
:
unsafe
.
Sizeof
(
GetXAttrOut
{})
,
FUSE_REMOVEXATTR
:
0
,
FUSE_FLUSH
:
0
,
FUSE_INIT
:
unsafe
.
Sizeof
(
InitOut
{}),
...
...
fuse/pathfilesystem.go
View file @
5f24a9ec
...
...
@@ -728,6 +728,26 @@ func (me *PathFileSystemConnector) GetXAttr(header *InHeader, attribute string)
return
data
,
code
}
func
(
me
*
PathFileSystemConnector
)
ListXAttr
(
header
*
InHeader
)
(
data
[]
byte
,
code
Status
)
{
path
,
mount
:=
me
.
GetPath
(
header
.
NodeId
)
if
mount
==
nil
{
return
nil
,
ENOENT
}
attrs
,
code
:=
mount
.
fs
.
ListXAttr
(
path
)
if
code
!=
OK
{
return
nil
,
code
}
b
:=
bytes
.
NewBuffer
([]
byte
{})
for
_
,
v
:=
range
attrs
{
b
.
Write
([]
byte
(
v
))
b
.
WriteByte
(
0
)
}
return
b
.
Bytes
(),
code
}
////////////////////////////////////////////////////////////////
// unimplemented.
...
...
fuse/timingfs.go
View file @
5f24a9ec
...
...
@@ -96,6 +96,11 @@ func (me *TimingPathFilesystem) GetXAttr(name string, attr string) ([]byte, Stat
return
me
.
original
.
GetXAttr
(
name
,
attr
)
}
func
(
me
*
TimingPathFilesystem
)
ListXAttr
(
name
string
)
([]
string
,
Status
)
{
defer
me
.
startTimer
(
"ListXAttr"
,
name
)()
return
me
.
original
.
ListXAttr
(
name
)
}
func
(
me
*
TimingPathFilesystem
)
Readlink
(
name
string
)
(
string
,
Status
)
{
defer
me
.
startTimer
(
"Readlink"
,
name
)()
return
me
.
original
.
Readlink
(
name
)
...
...
@@ -185,3 +190,4 @@ func (me *TimingPathFilesystem) Utimens(name string, AtimeNs uint64, CtimeNs uin
defer
me
.
startTimer
(
"Utimens"
,
name
)()
return
me
.
original
.
Utimens
(
name
,
AtimeNs
,
CtimeNs
)
}
fuse/timingrawfs.go
View file @
5f24a9ec
...
...
@@ -131,6 +131,11 @@ func (me *TimingRawFilesystem) GetXAttr(header *InHeader, attr string) (data []b
return
me
.
original
.
GetXAttr
(
header
,
attr
)
}
func
(
me
*
TimingRawFilesystem
)
ListXAttr
(
header
*
InHeader
)
(
data
[]
byte
,
code
Status
)
{
defer
me
.
startTimer
(
"ListXAttr"
)()
return
me
.
original
.
ListXAttr
(
header
)
}
func
(
me
*
TimingRawFilesystem
)
Access
(
header
*
InHeader
,
input
*
AccessIn
)
(
code
Status
)
{
defer
me
.
startTimer
(
"Access"
)()
return
me
.
original
.
Access
(
header
,
input
)
...
...
@@ -170,3 +175,4 @@ func (me *TimingRawFilesystem) ReleaseDir(header *InHeader, f RawFuseDir) {
defer
me
.
startTimer
(
"ReleaseDir"
)()
me
.
original
.
ReleaseDir
(
header
,
f
)
}
fuse/types.go
View file @
5f24a9ec
...
...
@@ -517,6 +517,7 @@ type RawFileSystem interface {
Link
(
header
*
InHeader
,
input
*
LinkIn
,
filename
string
)
(
out
*
EntryOut
,
code
Status
)
GetXAttr
(
header
*
InHeader
,
attr
string
)
(
data
[]
byte
,
code
Status
)
ListXAttr
(
header
*
InHeader
)
(
attributes
[]
byte
,
code
Status
)
// Unused:
SetXAttr
(
header
*
InHeader
,
input
*
SetXAttrIn
)
Status
...
...
@@ -570,7 +571,8 @@ type PathFilesystem interface {
// Where to hook up statfs?
//
// Unimplemented:
// RemoveXAttr, SetXAttr, GetXAttr, ListXAttr.
// RemoveXAttr, SetXAttr,
ListXAttr
(
name
string
)
(
attributes
[]
string
,
code
Status
)
OpenDir
(
name
string
)
(
stream
chan
DirEntry
,
code
Status
)
...
...
fuse/wrappedfs.go
View file @
5f24a9ec
...
...
@@ -80,6 +80,13 @@ func (me *WrappingPathFilesystem) Utimens(name string, AtimeNs uint64, CtimeNs u
return
me
.
original
.
Utimens
(
name
,
AtimeNs
,
CtimeNs
)
}
func
(
me
*
WrappingPathFilesystem
)
GetXAttr
(
name
string
,
attr
string
)
([]
byte
,
Status
)
{
return
me
.
original
.
GetXAttr
(
name
,
attr
)
}
func
(
me
*
WrappingPathFilesystem
)
ListXAttr
(
name
string
)
([]
string
,
Status
)
{
return
me
.
original
.
ListXAttr
(
name
)
}
////////////////////////////////////////////////////////////////
// Wrapping raw FS.
...
...
@@ -157,6 +164,10 @@ func (me *WrappingRawFilesystem) GetXAttr(header *InHeader, attr string) (data [
return
me
.
original
.
GetXAttr
(
header
,
attr
)
}
func
(
me
*
WrappingRawFilesystem
)
ListXAttr
(
header
*
InHeader
)
(
data
[]
byte
,
code
Status
)
{
return
me
.
original
.
ListXAttr
(
header
)
}
func
(
me
*
WrappingRawFilesystem
)
Access
(
header
*
InHeader
,
input
*
AccessIn
)
(
code
Status
)
{
return
me
.
original
.
Access
(
header
,
input
)
}
...
...
fuse/xattr.go
View file @
5f24a9ec
...
...
@@ -51,7 +51,7 @@ func listxattr(path string, dest []byte) (sz int, errno int) {
return
int
(
size
),
int
(
errNo
)
}
func
ListXAttr
(
path
string
)
(
attributes
[]
[]
byte
,
errno
int
)
{
func
ListXAttr
(
path
string
)
(
attributes
[]
string
,
errno
int
)
{
dest
:=
make
([]
byte
,
1024
)
sz
,
errno
:=
listxattr
(
path
,
dest
)
if
errno
!=
0
{
...
...
@@ -65,6 +65,10 @@ func ListXAttr(path string) (attributes [][]byte, errno int) {
// -1 to drop the final empty slice.
dest
=
dest
[
:
sz
-
1
]
attributes
=
bytes
.
Split
(
dest
,
[]
byte
{
0
},
-
1
)
attributesBytes
:=
bytes
.
Split
(
dest
,
[]
byte
{
0
},
-
1
)
attributes
=
make
([]
string
,
len
(
attributesBytes
))
for
i
,
v
:=
range
attributesBytes
{
attributes
[
i
]
=
string
(
v
)
}
return
attributes
,
errno
}
fuse/xattr_test.go
View file @
5f24a9ec
package
fuse
import
(
"bytes"
"testing"
"path/filepath"
"os"
...
...
@@ -33,6 +35,7 @@ func (me *XAttrTestFs) GetAttr(name string) (*Attr, Status) {
return
nil
,
ENOENT
}
func
(
me
*
XAttrTestFs
)
GetXAttr
(
name
string
,
attr
string
)
([]
byte
,
Status
)
{
if
name
!=
me
.
filename
{
return
nil
,
ENOENT
...
...
@@ -44,19 +47,31 @@ func (me *XAttrTestFs) GetXAttr(name string, attr string) ([]byte, Status) {
return
v
,
OK
}
func
(
me
*
XAttrTestFs
)
ListXAttr
(
name
string
)
(
data
[]
string
,
code
Status
)
{
if
name
!=
me
.
filename
{
return
nil
,
ENOENT
}
for
k
,
_
:=
range
me
.
attrs
{
data
=
append
(
data
,
k
)
}
return
data
,
OK
}
func
TestXAttr
(
t
*
testing
.
T
)
{
func
TestXAttr
Read
(
t
*
testing
.
T
)
{
nm
:=
"filename"
xfs
:=
NewXAttrFs
(
nm
,
map
[
string
][]
byte
{
golden
:=
map
[
string
][]
byte
{
"user.attr1"
:
[]
byte
(
"val1"
),
"user.attr2"
:
[]
byte
(
"val2"
)})
"user.attr2"
:
[]
byte
(
"val2"
)}
xfs
:=
NewXAttrFs
(
nm
,
golden
)
connector
:=
NewPathFileSystemConnector
(
xfs
)
mountPoint
:=
MakeTempDir
()
state
:=
NewMountState
(
connector
)
state
.
Mount
(
mountPoint
)
state
.
Debug
=
true
defer
state
.
Unmount
()
go
state
.
Loop
(
false
)
...
...
@@ -69,16 +84,32 @@ func TestXAttr(t *testing.T) {
val
,
errno
:=
GetXAttr
(
mounted
,
"noexist"
)
if
errno
==
0
{
t
.
Error
(
"Expected GetXAttr error"
)
t
.
Error
(
"Expected GetXAttr error"
,
val
)
}
val
,
errno
=
GetXAttr
(
mounted
,
"user.attr1"
)
if
err
!=
nil
{
attrs
,
errno
:=
ListXAttr
(
mounted
)
readback
:=
make
(
map
[
string
][]
byte
)
if
errno
!=
0
{
t
.
Error
(
"Unexpected ListXAttr error"
,
errno
)
}
else
{
for
_
,
a
:=
range
attrs
{
val
,
errno
=
GetXAttr
(
mounted
,
a
)
if
errno
!=
0
{
t
.
Error
(
"Unexpected GetXAttr error"
,
errno
)
}
readback
[
a
]
=
val
}
}
if
string
(
val
)
!=
"val1"
{
t
.
Error
(
"Unexpected value"
,
val
)
if
len
(
readback
)
!=
len
(
golden
)
{
t
.
Error
(
"length mismatch"
,
golden
,
readback
)
}
else
{
for
k
,
v
:=
range
(
readback
)
{
if
bytes
.
Compare
(
golden
[
k
],
v
)
!=
0
{
t
.
Error
(
"val mismatch"
,
k
,
v
,
golden
[
k
])
}
}
}
}
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