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
e32d0aa0
Commit
e32d0aa0
authored
Mar 09, 2019
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nodefs: write loopbackFile using syscall directly, skipping os.File
parent
9fa9d995
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
25 additions
and
24 deletions
+25
-24
nodefs/api.go
nodefs/api.go
+1
-0
nodefs/files.go
nodefs/files.go
+17
-17
nodefs/files_linux.go
nodefs/files_linux.go
+2
-2
nodefs/loopback.go
nodefs/loopback.go
+5
-5
No files found.
nodefs/api.go
View file @
e32d0aa0
...
@@ -103,6 +103,7 @@ type Operations interface {
...
@@ -103,6 +103,7 @@ type Operations interface {
StatFs
(
ctx
context
.
Context
,
out
*
fuse
.
StatfsOut
)
fuse
.
Status
StatFs
(
ctx
context
.
Context
,
out
*
fuse
.
StatfsOut
)
fuse
.
Status
Access
(
ctx
context
.
Context
,
mask
uint32
)
fuse
.
Status
Access
(
ctx
context
.
Context
,
mask
uint32
)
fuse
.
Status
// File locking
// File locking
GetLk
(
ctx
context
.
Context
,
f
FileHandle
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
,
out
*
fuse
.
FileLock
)
(
status
fuse
.
Status
)
GetLk
(
ctx
context
.
Context
,
f
FileHandle
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
,
out
*
fuse
.
FileLock
)
(
status
fuse
.
Status
)
SetLk
(
ctx
context
.
Context
,
f
FileHandle
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
)
(
status
fuse
.
Status
)
SetLk
(
ctx
context
.
Context
,
f
FileHandle
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
)
(
status
fuse
.
Status
)
...
...
nodefs/files.go
View file @
e32d0aa0
...
@@ -7,20 +7,20 @@ package nodefs
...
@@ -7,20 +7,20 @@ package nodefs
import
(
import
(
"context"
"context"
// "time"
// "time"
"os"
"sync"
"sync"
"syscall"
"syscall"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse"
)
)
func
newLoopbackFile
(
f
*
os
.
File
)
*
loopbackFile
{
func
newLoopbackFile
(
f
d
int
)
*
loopbackFile
{
return
&
loopbackFile
{
File
:
f
}
return
&
loopbackFile
{
fd
:
fd
}
}
}
// loopbackFile delegates all operations back to an underlying
os.F
ile.
// loopbackFile delegates all operations back to an underlying
f
ile.
type
loopbackFile
struct
{
type
loopbackFile
struct
{
File
*
os
.
File
fd
int
// os.File is not threadsafe. Although fd themselves are
// os.File is not threadsafe. Although fd themselves are
// constant during the lifetime of an open file, the OS may
// constant during the lifetime of an open file, the OS may
...
@@ -34,21 +34,21 @@ func (f *loopbackFile) Read(ctx context.Context, buf []byte, off int64) (res fus
...
@@ -34,21 +34,21 @@ func (f *loopbackFile) Read(ctx context.Context, buf []byte, off int64) (res fus
f
.
mu
.
Lock
()
f
.
mu
.
Lock
()
// This is not racy by virtue of the kernel properly
// This is not racy by virtue of the kernel properly
// synchronizing the open/write/close.
// synchronizing the open/write/close.
r
:=
fuse
.
ReadResultFd
(
f
.
File
.
Fd
(
),
off
,
len
(
buf
))
r
:=
fuse
.
ReadResultFd
(
uintptr
(
f
.
fd
),
off
,
len
(
buf
))
f
.
mu
.
Unlock
()
f
.
mu
.
Unlock
()
return
r
,
fuse
.
OK
return
r
,
fuse
.
OK
}
}
func
(
f
*
loopbackFile
)
Write
(
ctx
context
.
Context
,
data
[]
byte
,
off
int64
)
(
uint32
,
fuse
.
Status
)
{
func
(
f
*
loopbackFile
)
Write
(
ctx
context
.
Context
,
data
[]
byte
,
off
int64
)
(
uint32
,
fuse
.
Status
)
{
f
.
mu
.
Lock
()
f
.
mu
.
Lock
()
n
,
err
:=
f
.
File
.
WriteAt
(
data
,
off
)
n
,
err
:=
syscall
.
Pwrite
(
f
.
fd
,
data
,
off
)
f
.
mu
.
Unlock
()
f
.
mu
.
Unlock
()
return
uint32
(
n
),
fuse
.
ToStatus
(
err
)
return
uint32
(
n
),
fuse
.
ToStatus
(
err
)
}
}
func
(
f
*
loopbackFile
)
Release
()
{
func
(
f
*
loopbackFile
)
Release
()
{
f
.
mu
.
Lock
()
f
.
mu
.
Lock
()
f
.
File
.
Close
(
)
syscall
.
Close
(
f
.
fd
)
f
.
mu
.
Unlock
()
f
.
mu
.
Unlock
()
}
}
...
@@ -58,7 +58,7 @@ func (f *loopbackFile) Flush(ctx context.Context) fuse.Status {
...
@@ -58,7 +58,7 @@ func (f *loopbackFile) Flush(ctx context.Context) fuse.Status {
// Since Flush() may be called for each dup'd fd, we don't
// Since Flush() may be called for each dup'd fd, we don't
// want to really close the file, we just want to flush. This
// want to really close the file, we just want to flush. This
// is achieved by closing a dup'd fd.
// is achieved by closing a dup'd fd.
newFd
,
err
:=
syscall
.
Dup
(
int
(
f
.
File
.
Fd
())
)
newFd
,
err
:=
syscall
.
Dup
(
f
.
fd
)
f
.
mu
.
Unlock
()
f
.
mu
.
Unlock
()
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -70,7 +70,7 @@ func (f *loopbackFile) Flush(ctx context.Context) fuse.Status {
...
@@ -70,7 +70,7 @@ func (f *loopbackFile) Flush(ctx context.Context) fuse.Status {
func
(
f
*
loopbackFile
)
Fsync
(
ctx
context
.
Context
,
flags
uint32
)
(
status
fuse
.
Status
)
{
func
(
f
*
loopbackFile
)
Fsync
(
ctx
context
.
Context
,
flags
uint32
)
(
status
fuse
.
Status
)
{
f
.
mu
.
Lock
()
f
.
mu
.
Lock
()
r
:=
fuse
.
ToStatus
(
syscall
.
Fsync
(
int
(
f
.
File
.
Fd
())
))
r
:=
fuse
.
ToStatus
(
syscall
.
Fsync
(
f
.
fd
))
f
.
mu
.
Unlock
()
f
.
mu
.
Unlock
()
return
r
return
r
...
@@ -85,7 +85,7 @@ const (
...
@@ -85,7 +85,7 @@ const (
func
(
f
*
loopbackFile
)
GetLk
(
ctx
context
.
Context
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
,
out
*
fuse
.
FileLock
)
(
status
fuse
.
Status
)
{
func
(
f
*
loopbackFile
)
GetLk
(
ctx
context
.
Context
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
,
out
*
fuse
.
FileLock
)
(
status
fuse
.
Status
)
{
flk
:=
syscall
.
Flock_t
{}
flk
:=
syscall
.
Flock_t
{}
lk
.
ToFlockT
(
&
flk
)
lk
.
ToFlockT
(
&
flk
)
status
=
fuse
.
ToStatus
(
syscall
.
FcntlFlock
(
f
.
File
.
Fd
(
),
_OFD_GETLK
,
&
flk
))
status
=
fuse
.
ToStatus
(
syscall
.
FcntlFlock
(
uintptr
(
f
.
fd
),
_OFD_GETLK
,
&
flk
))
out
.
FromFlockT
(
&
flk
)
out
.
FromFlockT
(
&
flk
)
return
return
}
}
...
@@ -114,7 +114,7 @@ func (f *loopbackFile) setLock(ctx context.Context, owner uint64, lk *fuse.FileL
...
@@ -114,7 +114,7 @@ func (f *loopbackFile) setLock(ctx context.Context, owner uint64, lk *fuse.FileL
if
!
blocking
{
if
!
blocking
{
op
|=
syscall
.
LOCK_NB
op
|=
syscall
.
LOCK_NB
}
}
return
fuse
.
ToStatus
(
syscall
.
Flock
(
int
(
f
.
File
.
Fd
())
,
op
))
return
fuse
.
ToStatus
(
syscall
.
Flock
(
f
.
fd
,
op
))
}
else
{
}
else
{
flk
:=
syscall
.
Flock_t
{}
flk
:=
syscall
.
Flock_t
{}
lk
.
ToFlockT
(
&
flk
)
lk
.
ToFlockT
(
&
flk
)
...
@@ -124,13 +124,13 @@ func (f *loopbackFile) setLock(ctx context.Context, owner uint64, lk *fuse.FileL
...
@@ -124,13 +124,13 @@ func (f *loopbackFile) setLock(ctx context.Context, owner uint64, lk *fuse.FileL
}
else
{
}
else
{
op
=
_OFD_SETLK
op
=
_OFD_SETLK
}
}
return
fuse
.
ToStatus
(
syscall
.
FcntlFlock
(
f
.
File
.
Fd
(
),
op
,
&
flk
))
return
fuse
.
ToStatus
(
syscall
.
FcntlFlock
(
uintptr
(
f
.
fd
),
op
,
&
flk
))
}
}
}
}
func
(
f
*
loopbackFile
)
Truncate
(
ctx
context
.
Context
,
size
uint64
)
fuse
.
Status
{
func
(
f
*
loopbackFile
)
Truncate
(
ctx
context
.
Context
,
size
uint64
)
fuse
.
Status
{
f
.
mu
.
Lock
()
f
.
mu
.
Lock
()
r
:=
fuse
.
ToStatus
(
syscall
.
Ftruncate
(
int
(
f
.
File
.
Fd
())
,
int64
(
size
)))
r
:=
fuse
.
ToStatus
(
syscall
.
Ftruncate
(
f
.
fd
,
int64
(
size
)))
f
.
mu
.
Unlock
()
f
.
mu
.
Unlock
()
return
r
return
r
...
@@ -138,7 +138,7 @@ func (f *loopbackFile) Truncate(ctx context.Context, size uint64) fuse.Status {
...
@@ -138,7 +138,7 @@ func (f *loopbackFile) Truncate(ctx context.Context, size uint64) fuse.Status {
func
(
f
*
loopbackFile
)
Chmod
(
ctx
context
.
Context
,
mode
uint32
)
fuse
.
Status
{
func
(
f
*
loopbackFile
)
Chmod
(
ctx
context
.
Context
,
mode
uint32
)
fuse
.
Status
{
f
.
mu
.
Lock
()
f
.
mu
.
Lock
()
r
:=
fuse
.
ToStatus
(
f
.
File
.
Chmod
(
os
.
FileMode
(
mode
)
))
r
:=
fuse
.
ToStatus
(
syscall
.
Fchmod
(
f
.
fd
,
mode
))
f
.
mu
.
Unlock
()
f
.
mu
.
Unlock
()
return
r
return
r
...
@@ -146,7 +146,7 @@ func (f *loopbackFile) Chmod(ctx context.Context, mode uint32) fuse.Status {
...
@@ -146,7 +146,7 @@ func (f *loopbackFile) Chmod(ctx context.Context, mode uint32) fuse.Status {
func
(
f
*
loopbackFile
)
Chown
(
ctx
context
.
Context
,
uid
uint32
,
gid
uint32
)
fuse
.
Status
{
func
(
f
*
loopbackFile
)
Chown
(
ctx
context
.
Context
,
uid
uint32
,
gid
uint32
)
fuse
.
Status
{
f
.
mu
.
Lock
()
f
.
mu
.
Lock
()
r
:=
fuse
.
ToStatus
(
f
.
File
.
Chown
(
int
(
uid
),
int
(
gid
)))
r
:=
fuse
.
ToStatus
(
syscall
.
Fchown
(
f
.
fd
,
int
(
uid
),
int
(
gid
)))
f
.
mu
.
Unlock
()
f
.
mu
.
Unlock
()
return
r
return
r
...
@@ -155,7 +155,7 @@ func (f *loopbackFile) Chown(ctx context.Context, uid uint32, gid uint32) fuse.S
...
@@ -155,7 +155,7 @@ func (f *loopbackFile) Chown(ctx context.Context, uid uint32, gid uint32) fuse.S
func
(
f
*
loopbackFile
)
GetAttr
(
ctx
context
.
Context
,
a
*
fuse
.
AttrOut
)
fuse
.
Status
{
func
(
f
*
loopbackFile
)
GetAttr
(
ctx
context
.
Context
,
a
*
fuse
.
AttrOut
)
fuse
.
Status
{
st
:=
syscall
.
Stat_t
{}
st
:=
syscall
.
Stat_t
{}
f
.
mu
.
Lock
()
f
.
mu
.
Lock
()
err
:=
syscall
.
Fstat
(
int
(
f
.
File
.
Fd
())
,
&
st
)
err
:=
syscall
.
Fstat
(
f
.
fd
,
&
st
)
f
.
mu
.
Unlock
()
f
.
mu
.
Unlock
()
if
err
!=
nil
{
if
err
!=
nil
{
return
fuse
.
ToStatus
(
err
)
return
fuse
.
ToStatus
(
err
)
...
...
nodefs/files_linux.go
View file @
e32d0aa0
...
@@ -14,7 +14,7 @@ import (
...
@@ -14,7 +14,7 @@ import (
func
(
f
*
loopbackFile
)
Allocate
(
ctx
context
.
Context
,
off
uint64
,
sz
uint64
,
mode
uint32
)
fuse
.
Status
{
func
(
f
*
loopbackFile
)
Allocate
(
ctx
context
.
Context
,
off
uint64
,
sz
uint64
,
mode
uint32
)
fuse
.
Status
{
f
.
mu
.
Lock
()
f
.
mu
.
Lock
()
err
:=
syscall
.
Fallocate
(
int
(
f
.
File
.
Fd
())
,
mode
,
int64
(
off
),
int64
(
sz
))
err
:=
syscall
.
Fallocate
(
f
.
fd
,
mode
,
int64
(
off
),
int64
(
sz
))
f
.
mu
.
Unlock
()
f
.
mu
.
Unlock
()
if
err
!=
nil
{
if
err
!=
nil
{
return
fuse
.
ToStatus
(
err
)
return
fuse
.
ToStatus
(
err
)
...
@@ -28,7 +28,7 @@ func (f *loopbackFile) Utimens(ctx context.Context, a *time.Time, m *time.Time)
...
@@ -28,7 +28,7 @@ func (f *loopbackFile) Utimens(ctx context.Context, a *time.Time, m *time.Time)
ts
[
0
]
=
fuse
.
UtimeToTimespec
(
a
)
ts
[
0
]
=
fuse
.
UtimeToTimespec
(
a
)
ts
[
1
]
=
fuse
.
UtimeToTimespec
(
m
)
ts
[
1
]
=
fuse
.
UtimeToTimespec
(
m
)
f
.
mu
.
Lock
()
f
.
mu
.
Lock
()
err
:=
futimens
(
int
(
f
.
File
.
Fd
()
),
&
ts
)
err
:=
futimens
(
int
(
f
.
fd
),
&
ts
)
f
.
mu
.
Unlock
()
f
.
mu
.
Unlock
()
return
fuse
.
ToStatus
(
err
)
return
fuse
.
ToStatus
(
err
)
}
}
nodefs/loopback.go
View file @
e32d0aa0
...
@@ -176,20 +176,20 @@ func idFromStat(st *syscall.Stat_t) FileID {
...
@@ -176,20 +176,20 @@ func idFromStat(st *syscall.Stat_t) FileID {
func
(
n
*
loopbackNode
)
Create
(
ctx
context
.
Context
,
name
string
,
flags
uint32
,
mode
uint32
)
(
inode
*
Inode
,
fh
FileHandle
,
fuseFlags
uint32
,
status
fuse
.
Status
)
{
func
(
n
*
loopbackNode
)
Create
(
ctx
context
.
Context
,
name
string
,
flags
uint32
,
mode
uint32
)
(
inode
*
Inode
,
fh
FileHandle
,
fuseFlags
uint32
,
status
fuse
.
Status
)
{
p
:=
filepath
.
Join
(
n
.
path
(),
name
)
p
:=
filepath
.
Join
(
n
.
path
(),
name
)
f
,
err
:=
os
.
OpenFile
(
p
,
int
(
flags
)
|
os
.
O_CREATE
,
os
.
FileMode
(
mode
)
)
f
d
,
err
:=
syscall
.
Open
(
p
,
int
(
flags
)
|
os
.
O_CREATE
,
mode
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
nil
,
0
,
fuse
.
ToStatus
(
err
)
return
nil
,
nil
,
0
,
fuse
.
ToStatus
(
err
)
}
}
st
:=
syscall
.
Stat_t
{}
st
:=
syscall
.
Stat_t
{}
if
err
:=
syscall
.
Fstat
(
int
(
f
.
Fd
())
,
&
st
);
err
!=
nil
{
if
err
:=
syscall
.
Fstat
(
fd
,
&
st
);
err
!=
nil
{
f
.
Close
(
)
syscall
.
Close
(
fd
)
return
nil
,
nil
,
0
,
fuse
.
ToStatus
(
err
)
return
nil
,
nil
,
0
,
fuse
.
ToStatus
(
err
)
}
}
node
:=
n
.
rootNode
.
newLoopbackNode
()
node
:=
n
.
rootNode
.
newLoopbackNode
()
ch
:=
n
.
inode
()
.
NewInode
(
node
,
uint32
(
st
.
Mode
),
idFromStat
(
&
st
))
ch
:=
n
.
inode
()
.
NewInode
(
node
,
uint32
(
st
.
Mode
),
idFromStat
(
&
st
))
lf
:=
newLoopbackFile
(
f
)
lf
:=
newLoopbackFile
(
f
d
)
n
.
mu
.
Lock
()
n
.
mu
.
Lock
()
defer
n
.
mu
.
Unlock
()
defer
n
.
mu
.
Unlock
()
n
.
openFiles
[
lf
]
=
flags
|
syscall
.
O_CREAT
n
.
openFiles
[
lf
]
=
flags
|
syscall
.
O_CREAT
...
@@ -252,7 +252,7 @@ func (n *loopbackNode) Readlink(ctx context.Context) (string, fuse.Status) {
...
@@ -252,7 +252,7 @@ func (n *loopbackNode) Readlink(ctx context.Context) (string, fuse.Status) {
func
(
n
*
loopbackNode
)
Open
(
ctx
context
.
Context
,
flags
uint32
)
(
fh
FileHandle
,
fuseFlags
uint32
,
status
fuse
.
Status
)
{
func
(
n
*
loopbackNode
)
Open
(
ctx
context
.
Context
,
flags
uint32
)
(
fh
FileHandle
,
fuseFlags
uint32
,
status
fuse
.
Status
)
{
p
:=
n
.
path
()
p
:=
n
.
path
()
f
,
err
:=
os
.
OpenFile
(
p
,
int
(
flags
),
0
)
f
,
err
:=
syscall
.
Open
(
p
,
int
(
flags
),
0
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
0
,
fuse
.
ToStatus
(
err
)
return
nil
,
0
,
fuse
.
ToStatus
(
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