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
d0dbfc98
Commit
d0dbfc98
authored
Sep 05, 2011
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make fsInode lookups return fsInodes directly.
Use inodeFs as layer between FileSystemConnector and FileSystem.
parent
76583006
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
199 additions
and
68 deletions
+199
-68
fuse/fsconnector.go
fuse/fsconnector.go
+5
-5
fuse/fsinode.go
fuse/fsinode.go
+113
-34
fuse/fsmount.go
fuse/fsmount.go
+4
-1
fuse/fsops.go
fuse/fsops.go
+46
-26
fuse/inode.go
fuse/inode.go
+29
-1
fuse/pathdebug.go
fuse/pathdebug.go
+1
-1
fuse/types.go
fuse/types.go
+1
-0
No files found.
fuse/fsconnector.go
View file @
d0dbfc98
...
...
@@ -59,8 +59,6 @@ func (me *FileSystemConnector) verify() {
func
(
me
*
FileSystemConnector
)
newInode
(
isDir
bool
)
*
inode
{
data
:=
new
(
inode
)
data
.
nodeId
=
me
.
inodeMap
.
Register
(
&
data
.
handled
)
data
.
fsInode
=
new
(
fsInode
)
data
.
fsInode
.
inode
=
data
if
isDir
{
data
.
children
=
make
(
map
[
string
]
*
inode
,
initDirSize
)
}
...
...
@@ -259,7 +257,8 @@ func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem, opts *Fil
opts
=
me
.
rootNode
.
mountPoint
.
options
}
node
.
mountFs
(
fs
,
opts
)
ifs
:=
newInodeFs
(
fs
)
node
.
mountFs
(
ifs
,
opts
)
parent
.
addChild
(
base
,
node
)
if
parent
.
mounts
==
nil
{
...
...
@@ -276,8 +275,9 @@ func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem, opts *Fil
}
func
(
me
*
FileSystemConnector
)
mountRoot
(
fs
FileSystem
,
opts
*
FileSystemOptions
)
{
me
.
rootNode
.
mountFs
(
fs
,
opts
)
fs
.
Mount
(
me
)
ifs
:=
newInodeFs
(
fs
)
me
.
rootNode
.
mountFs
(
ifs
,
opts
)
ifs
.
Mount
(
me
)
me
.
verify
()
}
...
...
fuse/fsinode.go
View file @
d0dbfc98
...
...
@@ -8,12 +8,46 @@ import (
var
_
=
log
.
Println
type
inodeFs
struct
{
fs
FileSystem
root
*
fsInode
}
func
(
me
*
inodeFs
)
Unmount
()
{
}
func
(
me
*
inodeFs
)
Mount
(
conn
*
FileSystemConnector
)
{
me
.
fs
.
Mount
(
conn
)
}
func
(
me
*
inodeFs
)
StatFs
()
*
StatfsOut
{
return
me
.
fs
.
StatFs
()
}
func
newInodeFs
(
fs
FileSystem
)
*
inodeFs
{
root
:=
new
(
fsInode
)
root
.
fs
=
fs
me
:=
&
inodeFs
{
fs
:
fs
,
root
:
root
,
}
root
.
ifs
=
me
return
me
}
func
(
me
*
inodeFs
)
RootNode
()
*
fsInode
{
return
me
.
root
}
// This is a combination of dentry (entry in the file/directory and
// the inode). This structure is used to implement glue for FSes where
// there is a one-to-one mapping of paths and inodes, ie. FSes that
// disallow hardlinks.
type
fsInode
struct
{
*
inode
ifs
*
inodeFs
fs
FileSystem
Name
string
// This is nil at the root of the mount.
...
...
@@ -28,11 +62,6 @@ func (me *fsInode) GetPath() (path string) {
me
.
inode
.
treeLock
.
RLock
()
defer
me
.
inode
.
treeLock
.
RUnlock
()
if
me
.
inode
.
mount
==
nil
{
// Node from unmounted file system.
return
".deleted"
}
rev_components
:=
make
([]
string
,
0
,
10
)
n
:=
me
for
;
n
.
Parent
!=
nil
;
n
=
n
.
Parent
{
...
...
@@ -56,35 +85,42 @@ func (me *fsInode) rmChild(name string, ch *fsInode) {
ch
.
Parent
=
nil
}
func
(
me
*
fsInode
)
SetInode
(
node
*
inode
)
{
if
me
.
inode
!=
nil
{
panic
(
"already have inode"
)
}
me
.
inode
=
node
}
////////////////////////////////////////////////////////////////
func
(
me
*
fsInode
)
Readlink
(
c
*
Context
)
([]
byte
,
Status
)
{
path
:=
me
.
GetPath
()
val
,
err
:=
me
.
inode
.
mount
.
fs
.
Readlink
(
path
,
c
)
val
,
err
:=
me
.
fs
.
Readlink
(
path
,
c
)
return
[]
byte
(
val
),
err
}
func
(
me
*
fsInode
)
Access
(
mode
uint32
,
context
*
Context
)
(
code
Status
)
{
p
:=
me
.
GetPath
()
return
me
.
inode
.
mount
.
fs
.
Access
(
p
,
mode
,
context
)
return
me
.
fs
.
Access
(
p
,
mode
,
context
)
}
func
(
me
*
fsInode
)
GetXAttr
(
attribute
string
,
context
*
Context
)
(
data
[]
byte
,
code
Status
)
{
return
me
.
inode
.
mount
.
fs
.
GetXAttr
(
me
.
GetPath
(),
attribute
,
context
)
return
me
.
fs
.
GetXAttr
(
me
.
GetPath
(),
attribute
,
context
)
}
func
(
me
*
fsInode
)
RemoveXAttr
(
attr
string
,
context
*
Context
)
Status
{
p
:=
me
.
GetPath
()
return
me
.
inode
.
mount
.
fs
.
RemoveXAttr
(
p
,
attr
,
context
)
return
me
.
fs
.
RemoveXAttr
(
p
,
attr
,
context
)
}
func
(
me
*
fsInode
)
SetXAttr
(
attr
string
,
data
[]
byte
,
flags
int
,
context
*
Context
)
Status
{
return
me
.
inode
.
mount
.
fs
.
SetXAttr
(
me
.
GetPath
(),
attr
,
data
,
flags
,
context
)
return
me
.
fs
.
SetXAttr
(
me
.
GetPath
(),
attr
,
data
,
flags
,
context
)
}
func
(
me
*
fsInode
)
ListXAttr
(
context
*
Context
)
(
attrs
[]
string
,
code
Status
)
{
return
me
.
inode
.
mount
.
fs
.
ListXAttr
(
me
.
GetPath
(),
context
)
return
me
.
fs
.
ListXAttr
(
me
.
GetPath
(),
context
)
}
func
(
me
*
fsInode
)
Flush
(
file
File
,
openFlags
uint32
,
context
*
Context
)
(
code
Status
)
{
...
...
@@ -93,34 +129,55 @@ func (me *fsInode) Flush(file File, openFlags uint32, context *Context) (code St
// We only signal releases to the FS if the
// open could have changed things.
path
:=
me
.
GetPath
()
code
=
me
.
inode
.
mount
.
fs
.
Flush
(
path
)
code
=
me
.
fs
.
Flush
(
path
)
}
return
code
}
func
(
me
*
fsInode
)
OpenDir
(
context
*
Context
)
(
chan
DirEntry
,
Status
)
{
return
me
.
inode
.
mount
.
fs
.
OpenDir
(
me
.
GetPath
(),
context
)
return
me
.
fs
.
OpenDir
(
me
.
GetPath
(),
context
)
}
func
(
me
*
fsInode
)
Mknod
(
name
string
,
mode
uint32
,
dev
uint32
,
context
*
Context
)
Status
{
func
(
me
*
fsInode
)
Mknod
(
name
string
,
mode
uint32
,
dev
uint32
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
*
fsInode
,
code
Status
)
{
p
:=
me
.
GetPath
()
return
me
.
inode
.
mount
.
fs
.
Mknod
(
filepath
.
Join
(
p
,
name
),
mode
,
dev
,
context
)
code
=
me
.
fs
.
Mknod
(
filepath
.
Join
(
p
,
name
),
mode
,
dev
,
context
)
if
code
.
Ok
()
{
newNode
=
me
.
createChild
(
name
)
fi
=
&
os
.
FileInfo
{
Mode
:
S_IFIFO
|
mode
,
// TODO
}
}
return
}
func
(
me
*
fsInode
)
Mkdir
(
name
string
,
mode
uint32
,
context
*
Context
)
(
code
Status
)
{
return
me
.
inode
.
mount
.
fs
.
Mkdir
(
filepath
.
Join
(
me
.
GetPath
(),
name
),
mode
,
context
)
func
(
me
*
fsInode
)
Mkdir
(
name
string
,
mode
uint32
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
*
fsInode
,
code
Status
)
{
code
=
me
.
fs
.
Mkdir
(
filepath
.
Join
(
me
.
GetPath
(),
name
),
mode
,
context
)
if
code
.
Ok
()
{
newNode
=
me
.
createChild
(
name
)
fi
=
&
os
.
FileInfo
{
Mode
:
S_IFDIR
|
mode
,
}
}
return
}
func
(
me
*
fsInode
)
Unlink
(
name
string
,
context
*
Context
)
(
code
Status
)
{
return
me
.
inode
.
mount
.
fs
.
Unlink
(
filepath
.
Join
(
me
.
GetPath
(),
name
),
context
)
return
me
.
fs
.
Unlink
(
filepath
.
Join
(
me
.
GetPath
(),
name
),
context
)
}
func
(
me
*
fsInode
)
Rmdir
(
name
string
,
context
*
Context
)
(
code
Status
)
{
return
me
.
inode
.
mount
.
fs
.
Rmdir
(
filepath
.
Join
(
me
.
GetPath
(),
name
),
context
)
return
me
.
fs
.
Rmdir
(
filepath
.
Join
(
me
.
GetPath
(),
name
),
context
)
}
func
(
me
*
fsInode
)
Symlink
(
name
string
,
content
string
,
context
*
Context
)
(
code
Status
)
{
return
me
.
inode
.
mount
.
fs
.
Symlink
(
content
,
filepath
.
Join
(
me
.
GetPath
(),
name
),
context
)
func
(
me
*
fsInode
)
Symlink
(
name
string
,
content
string
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
*
fsInode
,
code
Status
)
{
code
=
me
.
fs
.
Symlink
(
content
,
filepath
.
Join
(
me
.
GetPath
(),
name
),
context
)
if
code
.
Ok
()
{
newNode
=
me
.
createChild
(
name
)
fi
=
&
os
.
FileInfo
{
Mode
:
S_IFLNK
|
0666
,
// TODO
}
}
return
}
...
...
@@ -128,26 +185,48 @@ func (me *fsInode) Rename(oldName string, newParent *fsInode, newName string, co
oldPath
:=
filepath
.
Join
(
me
.
GetPath
(),
oldName
)
newPath
:=
filepath
.
Join
(
newParent
.
GetPath
(),
newName
)
return
me
.
inode
.
mount
.
fs
.
Rename
(
oldPath
,
newPath
,
context
)
return
me
.
fs
.
Rename
(
oldPath
,
newPath
,
context
)
}
func
(
me
*
fsInode
)
Link
(
name
string
,
existing
*
fsInode
,
context
*
Context
)
(
code
Status
)
{
return
me
.
inode
.
mount
.
fs
.
Link
(
existing
.
GetPath
(),
filepath
.
Join
(
me
.
GetPath
(),
name
),
context
)
return
me
.
fs
.
Link
(
existing
.
GetPath
(),
filepath
.
Join
(
me
.
GetPath
(),
name
),
context
)
}
func
(
me
*
fsInode
)
Create
(
name
string
,
flags
uint32
,
mode
uint32
,
context
*
Context
)
(
file
File
,
code
Status
)
{
func
(
me
*
fsInode
)
Create
(
name
string
,
flags
uint32
,
mode
uint32
,
context
*
Context
)
(
file
File
,
fi
*
os
.
FileInfo
,
newNode
*
fsInode
,
code
Status
)
{
fullPath
:=
filepath
.
Join
(
me
.
GetPath
(),
name
)
return
me
.
inode
.
mount
.
fs
.
Create
(
fullPath
,
flags
,
mode
,
context
)
file
,
code
=
me
.
fs
.
Create
(
fullPath
,
flags
,
mode
,
context
)
if
code
.
Ok
()
{
newNode
=
me
.
createChild
(
name
)
fi
=
&
os
.
FileInfo
{
Mode
:
S_IFREG
|
mode
,
// TODO - ctime, mtime, atime?
}
}
return
}
func
(
me
*
fsInode
)
createChild
(
name
string
)
*
fsInode
{
i
:=
new
(
fsInode
)
i
.
Parent
=
me
i
.
Name
=
name
i
.
fs
=
me
.
fs
i
.
ifs
=
me
.
ifs
return
i
}
func
(
me
*
fsInode
)
Open
(
flags
uint32
,
context
*
Context
)
(
file
File
,
code
Status
)
{
return
me
.
inode
.
mount
.
fs
.
Open
(
me
.
GetPath
(),
flags
,
context
)
return
me
.
fs
.
Open
(
me
.
GetPath
(),
flags
,
context
)
}
// TO
DO: should return fsInode
.
func
(
me
*
fsInode
)
Lookup
(
name
string
)
(
fi
*
os
.
FileInfo
,
code
Status
)
{
// TO
OD - need context
.
func
(
me
*
fsInode
)
Lookup
(
name
string
)
(
fi
*
os
.
FileInfo
,
node
*
fsInode
,
code
Status
)
{
fullPath
:=
filepath
.
Join
(
me
.
GetPath
(),
name
)
return
me
.
inode
.
mount
.
fs
.
GetAttr
(
fullPath
,
nil
)
fi
,
code
=
me
.
fs
.
GetAttr
(
fullPath
,
nil
)
if
code
.
Ok
()
{
node
=
me
.
createChild
(
name
)
}
return
}
func
(
me
*
fsInode
)
GetAttr
(
file
File
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
code
Status
)
{
...
...
@@ -161,7 +240,7 @@ func (me *fsInode) GetAttr(file File, context *Context) (fi *os.FileInfo, code S
}
if
file
==
nil
||
code
==
ENOSYS
{
fi
,
code
=
me
.
inode
.
mount
.
fs
.
GetAttr
(
me
.
GetPath
(),
context
)
fi
,
code
=
me
.
fs
.
GetAttr
(
me
.
GetPath
(),
context
)
}
if
fi
!=
nil
&&
!
fi
.
IsDirectory
()
{
...
...
@@ -181,7 +260,7 @@ func (me *fsInode) Chmod(file File, perms uint32, context *Context) (code Status
}
if
len
(
files
)
==
0
||
code
==
ENOSYS
{
code
=
me
.
inode
.
mount
.
fs
.
Chmod
(
me
.
GetPath
(),
perms
,
context
)
code
=
me
.
fs
.
Chmod
(
me
.
GetPath
(),
perms
,
context
)
}
return
code
}
...
...
@@ -198,7 +277,7 @@ func (me *fsInode) Chown(file File, uid uint32, gid uint32, context *Context) (c
}
if
len
(
files
)
==
0
||
code
==
ENOSYS
{
// TODO - can we get just FATTR_GID but not FATTR_UID ?
code
=
me
.
inode
.
mount
.
fs
.
Chown
(
me
.
GetPath
(),
uid
,
gid
,
context
)
code
=
me
.
fs
.
Chown
(
me
.
GetPath
(),
uid
,
gid
,
context
)
}
return
code
}
...
...
@@ -214,7 +293,7 @@ func (me *fsInode) Truncate(file File, size uint64, context *Context) (code Stat
}
}
if
len
(
files
)
==
0
||
code
==
ENOSYS
{
code
=
me
.
inode
.
mount
.
fs
.
Truncate
(
me
.
GetPath
(),
size
,
context
)
code
=
me
.
fs
.
Truncate
(
me
.
GetPath
(),
size
,
context
)
}
return
code
}
...
...
@@ -229,7 +308,7 @@ func (me *fsInode) Utimens(file File, atime uint64, mtime uint64, context *Conte
}
}
if
len
(
files
)
==
0
||
code
==
ENOSYS
{
code
=
me
.
inode
.
mount
.
fs
.
Utimens
(
me
.
GetPath
(),
atime
,
mtime
,
context
)
code
=
me
.
fs
.
Utimens
(
me
.
GetPath
(),
atime
,
mtime
,
context
)
}
return
code
}
fuse/fsmount.go
View file @
d0dbfc98
package
fuse
import
(
"log"
"os"
"sync"
"unsafe"
)
var
_
=
log
.
Println
// openedFile stores either an open dir or an open file.
type
openedFile
struct
{
...
...
@@ -21,7 +24,7 @@ type openedFile struct {
type
fileSystemMount
struct
{
// The file system we mounted here.
fs
FileSystem
fs
*
inodeFs
// Node that we were mounted on.
mountInode
*
inode
...
...
fuse/fsops.go
View file @
d0dbfc98
...
...
@@ -4,8 +4,8 @@ package fuse
import
(
"bytes"
"fmt"
"log"
"os"
"time"
)
...
...
@@ -23,7 +23,7 @@ func (me *FileSystemConnector) Lookup(header *InHeader, name string) (out *Entry
}
func
(
me
*
FileSystemConnector
)
internalMountLookup
(
mount
*
fileSystemMount
,
lookupCount
int
)
(
out
*
EntryOut
,
status
Status
,
node
*
inode
)
{
fi
,
err
:=
mount
.
fs
.
GetAttr
(
""
,
nil
)
fi
,
err
:=
mount
.
fs
.
RootNode
()
.
GetAttr
(
nil
,
nil
)
if
err
==
ENOENT
&&
mount
.
options
.
NegativeTimeout
>
0.0
{
return
NegativeEntry
(
mount
.
options
.
NegativeTimeout
),
OK
,
nil
}
...
...
@@ -41,12 +41,16 @@ func (me *FileSystemConnector) internalMountLookup(mount *fileSystemMount, looku
return
out
,
OK
,
mount
.
mountInode
}
func
(
me
*
FileSystemConnector
)
internalLookup
(
parent
*
inode
,
name
string
,
lookupCount
int
,
context
*
Context
)
(
out
*
EntryOut
,
status
Status
,
node
*
inode
)
{
func
(
me
*
FileSystemConnector
)
internalLookup
(
parent
*
inode
,
name
string
,
lookupCount
int
,
context
*
Context
)
(
out
*
EntryOut
,
code
Status
,
node
*
inode
)
{
if
mount
:=
me
.
lookupMount
(
parent
,
name
,
lookupCount
);
mount
!=
nil
{
return
me
.
internalMountLookup
(
mount
,
lookupCount
)
}
fi
,
code
:=
parent
.
fsInode
.
Lookup
(
name
)
var
fi
*
os
.
FileInfo
child
:=
parent
.
getChild
(
name
)
if
child
!=
nil
{
fi
,
code
=
child
.
fsInode
.
GetAttr
(
nil
,
nil
)
}
mount
:=
parent
.
mount
if
code
==
ENOENT
&&
mount
.
options
.
NegativeTimeout
>
0.0
{
return
NegativeEntry
(
mount
.
options
.
NegativeTimeout
),
OK
,
nil
...
...
@@ -54,13 +58,25 @@ func (me *FileSystemConnector) internalLookup(parent *inode, name string, lookup
if
!
code
.
Ok
()
{
return
nil
,
code
,
nil
}
node
=
me
.
lookupUpdate
(
parent
,
name
,
fi
.
IsDirectory
(),
lookupCount
)
out
=
&
EntryOut
{
NodeId
:
node
.
nodeId
,
Generation
:
1
,
// where to get the generation?
if
child
!=
nil
&&
code
.
Ok
()
{
out
=
&
EntryOut
{
NodeId
:
child
.
nodeId
,
Generation
:
1
,
// where to get the generation?
}
parent
.
mount
.
fileInfoToEntry
(
fi
,
out
)
return
out
,
OK
,
child
}
parent
.
mount
.
fileInfoToEntry
(
fi
,
out
)
out
.
Attr
.
Ino
=
node
.
nodeId
fi
,
fsNode
,
code
:=
parent
.
fsInode
.
Lookup
(
name
)
if
code
==
ENOENT
&&
mount
.
options
.
NegativeTimeout
>
0.0
{
return
NegativeEntry
(
mount
.
options
.
NegativeTimeout
),
OK
,
nil
}
if
!
code
.
Ok
()
{
return
nil
,
code
,
nil
}
out
,
_
=
me
.
createChild
(
parent
,
name
,
fi
,
fsNode
)
return
out
,
OK
,
node
}
...
...
@@ -122,7 +138,6 @@ func (me *FileSystemConnector) Open(header *InHeader, input *OpenIn) (flags uint
if
!
code
.
Ok
()
{
return
0
,
0
,
code
}
h
,
opened
:=
node
.
mount
.
registerFileHandle
(
node
,
nil
,
f
,
input
.
Flags
)
return
opened
.
FuseFlags
,
h
,
OK
}
...
...
@@ -178,20 +193,30 @@ func (me *FileSystemConnector) Readlink(header *InHeader) (out []byte, code Stat
}
func
(
me
*
FileSystemConnector
)
Mknod
(
header
*
InHeader
,
input
*
MknodIn
,
name
string
)
(
out
*
EntryOut
,
code
Status
)
{
n
:=
me
.
getInodeData
(
header
.
NodeId
)
code
=
n
.
fsInode
.
Mknod
(
name
,
input
.
Mode
,
uint32
(
input
.
Rdev
),
&
header
.
Context
)
parent
:=
me
.
getInodeData
(
header
.
NodeId
)
fi
,
fsNode
,
code
:=
parent
.
fsInode
.
Mknod
(
name
,
input
.
Mode
,
uint32
(
input
.
Rdev
),
&
header
.
Context
)
if
code
.
Ok
()
{
out
,
code
,
_
=
me
.
internalLookup
(
n
,
name
,
1
,
&
header
.
Context
)
out
,
_
=
me
.
createChild
(
parent
,
name
,
fi
,
fsNode
)
}
return
out
,
code
}
func
(
me
*
FileSystemConnector
)
createChild
(
parent
*
inode
,
name
string
,
fi
*
os
.
FileInfo
,
fsi
*
fsInode
)
(
out
*
EntryOut
,
child
*
inode
)
{
child
=
parent
.
createChild
(
name
,
fi
.
IsDirectory
(),
fsi
,
me
)
out
=
&
EntryOut
{}
parent
.
mount
.
fileInfoToEntry
(
fi
,
out
)
out
.
Ino
=
child
.
nodeId
out
.
NodeId
=
child
.
nodeId
return
out
,
child
}
func
(
me
*
FileSystemConnector
)
Mkdir
(
header
*
InHeader
,
input
*
MkdirIn
,
name
string
)
(
out
*
EntryOut
,
code
Status
)
{
parent
:=
me
.
getInodeData
(
header
.
NodeId
)
code
=
parent
.
fsInode
.
Mkdir
(
name
,
input
.
Mode
,
&
header
.
Context
)
fi
,
fsInode
,
code
:
=
parent
.
fsInode
.
Mkdir
(
name
,
input
.
Mode
,
&
header
.
Context
)
if
code
.
Ok
()
{
out
,
code
,
_
=
me
.
internalLookup
(
parent
,
name
,
1
,
&
header
.
Context
)
out
,
_
=
me
.
createChild
(
parent
,
name
,
fi
,
fsInode
)
}
return
out
,
code
}
...
...
@@ -218,9 +243,9 @@ func (me *FileSystemConnector) Rmdir(header *InHeader, name string) (code Status
func
(
me
*
FileSystemConnector
)
Symlink
(
header
*
InHeader
,
pointedTo
string
,
linkName
string
)
(
out
*
EntryOut
,
code
Status
)
{
parent
:=
me
.
getInodeData
(
header
.
NodeId
)
code
=
parent
.
fsInode
.
Symlink
(
linkName
,
pointedTo
,
&
header
.
Context
)
fi
,
fsNode
,
code
:
=
parent
.
fsInode
.
Symlink
(
linkName
,
pointedTo
,
&
header
.
Context
)
if
code
.
Ok
()
{
out
,
code
,
_
=
me
.
internalLookup
(
parent
,
linkName
,
1
,
&
header
.
Context
)
out
,
_
=
me
.
createChild
(
parent
,
linkName
,
fi
,
fsNode
)
}
return
out
,
code
}
...
...
@@ -269,17 +294,12 @@ func (me *FileSystemConnector) Access(header *InHeader, input *AccessIn) (code S
func
(
me
*
FileSystemConnector
)
Create
(
header
*
InHeader
,
input
*
CreateIn
,
name
string
)
(
flags
uint32
,
h
uint64
,
out
*
EntryOut
,
code
Status
)
{
parent
:=
me
.
getInodeData
(
header
.
NodeId
)
f
,
code
:=
parent
.
fsInode
.
Create
(
name
,
uint32
(
input
.
Flags
),
input
.
Mode
,
&
header
.
Context
)
f
,
fi
,
fsNode
,
code
:=
parent
.
fsInode
.
Create
(
name
,
uint32
(
input
.
Flags
),
input
.
Mode
,
&
header
.
Context
)
if
!
code
.
Ok
()
{
return
0
,
0
,
nil
,
code
}
out
,
code
,
inode
:=
me
.
internalLookup
(
parent
,
name
,
1
,
&
header
.
Context
)
if
inode
==
nil
{
msg
:=
fmt
.
Sprintf
(
"Create succeded, but GetAttr returned no entry %v, %q. code %v"
,
header
.
NodeId
,
name
,
code
)
panic
(
msg
)
}
handle
,
opened
:=
parent
.
mount
.
registerFileHandle
(
inode
,
nil
,
f
,
input
.
Flags
)
out
,
child
:=
me
.
createChild
(
parent
,
name
,
fi
,
fsNode
)
handle
,
opened
:=
parent
.
mount
.
registerFileHandle
(
child
,
nil
,
f
,
input
.
Flags
)
return
opened
.
FuseFlags
,
handle
,
out
,
code
}
...
...
fuse/inode.go
View file @
d0dbfc98
...
...
@@ -43,6 +43,32 @@ type inode struct {
mount
*
fileSystemMount
}
func
(
me
*
inode
)
createChild
(
name
string
,
isDir
bool
,
fsi
*
fsInode
,
conn
*
FileSystemConnector
)
*
inode
{
me
.
treeLock
.
Lock
()
defer
me
.
treeLock
.
Unlock
()
ch
:=
me
.
children
[
name
]
if
ch
!=
nil
{
panic
(
fmt
.
Sprintf
(
"already have a child at %v %q"
,
me
.
nodeId
,
name
))
}
ch
=
conn
.
newInode
(
isDir
)
ch
.
fsInode
=
fsi
fsi
.
SetInode
(
ch
)
ch
.
mount
=
me
.
mount
ch
.
treeLock
=
me
.
treeLock
ch
.
lookupCount
=
1
me
.
addChild
(
name
,
ch
)
return
ch
}
func
(
me
*
inode
)
getChild
(
name
string
)
(
child
*
inode
)
{
me
.
treeLock
.
Lock
()
defer
me
.
treeLock
.
Unlock
()
return
me
.
children
[
name
]
}
// Must be called with treeLock for the mount held.
func
(
me
*
inode
)
addChild
(
name
string
,
child
*
inode
)
{
if
paranoia
{
...
...
@@ -67,7 +93,7 @@ func (me *inode) rmChild(name string) (ch *inode) {
}
// Can only be called on untouched inodes.
func
(
me
*
inode
)
mountFs
(
fs
FileSystem
,
opts
*
FileSystemOptions
)
{
func
(
me
*
inode
)
mountFs
(
fs
*
inodeFs
,
opts
*
FileSystemOptions
)
{
me
.
mountPoint
=
&
fileSystemMount
{
fs
:
fs
,
openFiles
:
NewHandleMap
(
true
),
...
...
@@ -76,6 +102,8 @@ func (me *inode) mountFs(fs FileSystem, opts *FileSystemOptions) {
}
me
.
mount
=
me
.
mountPoint
me
.
treeLock
=
&
me
.
mountPoint
.
treeLock
me
.
fsInode
=
fs
.
RootNode
()
me
.
fsInode
.
SetInode
(
me
)
}
// Must be called with treeLock held.
...
...
fuse/pathdebug.go
View file @
d0dbfc98
...
...
@@ -50,7 +50,7 @@ func (me *FileSystemDebug) Open(path string, flags uint32, context *Context) (fu
return
me
.
FileSystem
.
Open
(
path
,
flags
,
context
)
}
var
SeparatorString
=
string
(
[]
byte
{
filepath
.
Separator
}
)
var
SeparatorString
=
string
(
filepath
.
Separator
)
func
(
me
*
FileSystemDebug
)
getContent
(
path
string
)
[]
byte
{
comps
:=
strings
.
Split
(
path
,
SeparatorString
)
...
...
fuse/types.go
View file @
d0dbfc98
...
...
@@ -25,6 +25,7 @@ const (
S_IFDIR
=
syscall
.
S_IFDIR
S_IFREG
=
syscall
.
S_IFREG
S_IFLNK
=
syscall
.
S_IFLNK
S_IFIFO
=
syscall
.
S_IFIFO
// TODO - get this from a canonical place.
PAGESIZE
=
4096
...
...
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