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
77177c5d
Commit
77177c5d
authored
Dec 05, 2011
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Change go-fuse to use fuse.Attr rather than os.FileInfo in preparation
of the fileinfo API update.
parent
5dac7ee0
Changes
32
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
319 additions
and
228 deletions
+319
-228
benchmark/stat_test.go
benchmark/stat_test.go
+6
-4
example/hello/main.go
example/hello/main.go
+4
-5
fuse/Makefile
fuse/Makefile
+1
-0
fuse/api.go
fuse/api.go
+12
-13
fuse/attr.go
fuse/attr.go
+131
-0
fuse/cache_test.go
fuse/cache_test.go
+3
-2
fuse/default.go
fuse/default.go
+2
-3
fuse/defaultfile.go
fuse/defaultfile.go
+2
-3
fuse/defaultnode.go
fuse/defaultnode.go
+10
-11
fuse/files.go
fuse/files.go
+6
-4
fuse/fsconnector.go
fuse/fsconnector.go
+1
-2
fuse/fsetattr_test.go
fuse/fsetattr_test.go
+20
-17
fuse/fsmount.go
fuse/fsmount.go
+7
-7
fuse/fsops.go
fuse/fsops.go
+9
-10
fuse/lockingfs.go
fuse/lockingfs.go
+2
-3
fuse/loopback.go
fuse/loopback.go
+6
-3
fuse/memnode.go
fuse/memnode.go
+15
-19
fuse/misc.go
fuse/misc.go
+0
-22
fuse/notify_test.go
fuse/notify_test.go
+5
-5
fuse/owner_test.go
fuse/owner_test.go
+7
-6
fuse/pathfs.go
fuse/pathfs.go
+10
-11
fuse/prefixfs.go
fuse/prefixfs.go
+2
-3
fuse/readonlyfs.go
fuse/readonlyfs.go
+2
-3
fuse/xattr_test.go
fuse/xattr_test.go
+2
-2
unionfs/autounion.go
unionfs/autounion.go
+7
-7
unionfs/cachingfs.go
unionfs/cachingfs.go
+5
-6
unionfs/unionfs.go
unionfs/unionfs.go
+22
-34
zipfs/memtree.go
zipfs/memtree.go
+4
-5
zipfs/multizip.go
zipfs/multizip.go
+2
-3
zipfs/multizip_test.go
zipfs/multizip_test.go
+1
-1
zipfs/tarfs.go
zipfs/tarfs.go
+10
-11
zipfs/zipfs.go
zipfs/zipfs.go
+3
-3
No files found.
benchmark/stat_test.go
View file @
77177c5d
...
...
@@ -20,7 +20,7 @@ var CheckSuccess = fuse.CheckSuccess
type
StatFs
struct
{
fuse
.
DefaultFileSystem
entries
map
[
string
]
*
os
.
FileInfo
entries
map
[
string
]
*
fuse
.
Attr
dirs
map
[
string
][]
fuse
.
DirEntry
}
...
...
@@ -31,7 +31,9 @@ func (me *StatFs) add(name string, fi os.FileInfo) {
return
}
me
.
entries
[
name
]
=
&
fi
a
:=
&
fuse
.
Attr
{}
a
.
FromFileInfo
(
&
fi
)
me
.
entries
[
name
]
=
a
if
name
==
"/"
||
name
==
""
{
return
}
...
...
@@ -42,7 +44,7 @@ func (me *StatFs) add(name string, fi os.FileInfo) {
me
.
add
(
dir
,
os
.
FileInfo
{
Mode
:
fuse
.
S_IFDIR
|
0755
})
}
func
(
me
*
StatFs
)
GetAttr
(
name
string
,
context
*
fuse
.
Context
)
(
*
os
.
FileInfo
,
fuse
.
Status
)
{
func
(
me
*
StatFs
)
GetAttr
(
name
string
,
context
*
fuse
.
Context
)
(
*
fuse
.
Attr
,
fuse
.
Status
)
{
e
:=
me
.
entries
[
name
]
if
e
==
nil
{
return
nil
,
fuse
.
ENOENT
...
...
@@ -65,7 +67,7 @@ func (me *StatFs) OpenDir(name string, context *fuse.Context) (stream chan fuse.
func
NewStatFs
()
*
StatFs
{
return
&
StatFs
{
entries
:
make
(
map
[
string
]
*
os
.
FileInfo
),
entries
:
make
(
map
[
string
]
*
fuse
.
Attr
),
dirs
:
make
(
map
[
string
][]
fuse
.
DirEntry
),
}
}
...
...
example/hello/main.go
View file @
77177c5d
...
...
@@ -6,21 +6,20 @@ import (
"flag"
"github.com/hanwen/go-fuse/fuse"
"log"
"os"
)
type
HelloFs
struct
{
fuse
.
DefaultFileSystem
}
func
(
me
*
HelloFs
)
GetAttr
(
name
string
,
context
*
fuse
.
Context
)
(
*
os
.
FileInfo
,
fuse
.
Status
)
{
func
(
me
*
HelloFs
)
GetAttr
(
name
string
,
context
*
fuse
.
Context
)
(
*
fuse
.
Attr
,
fuse
.
Status
)
{
switch
name
{
case
"file.txt"
:
return
&
os
.
FileInfo
{
Mode
:
fuse
.
S_IFREG
|
0644
,
Size
:
int64
(
len
(
name
)),
return
&
fuse
.
Attr
{
Mode
:
fuse
.
S_IFREG
|
0644
,
Size
:
u
int64
(
len
(
name
)),
},
fuse
.
OK
case
""
:
return
&
os
.
FileInfo
{
return
&
fuse
.
Attr
{
Mode
:
fuse
.
S_IFDIR
|
0755
,
},
fuse
.
OK
}
...
...
fuse/Makefile
View file @
77177c5d
...
...
@@ -4,6 +4,7 @@ include $(GOROOT)/src/Make.inc
TARG
=
github.com/hanwen/go-fuse/fuse
MANUAL_GOFILES
=
api.go
\
attr.go
\
bufferpool.go
\
copy.go
\
default.go
\
...
...
fuse/api.go
View file @
77177c5d
...
...
@@ -5,7 +5,6 @@
package
fuse
import
(
"os"
)
// Types for users to implement.
...
...
@@ -29,7 +28,7 @@ type FsNode interface {
Inode
()
*
Inode
SetInode
(
node
*
Inode
)
Lookup
(
name
string
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
node
FsNode
,
code
Status
)
Lookup
(
name
string
,
context
*
Context
)
(
fi
*
Attr
,
node
FsNode
,
code
Status
)
// Deletable() should return true if this inode may be
// discarded from the children list. This will be called from
...
...
@@ -46,16 +45,16 @@ type FsNode interface {
Readlink
(
c
*
Context
)
([]
byte
,
Status
)
// Namespace operations
Mknod
(
name
string
,
mode
uint32
,
dev
uint32
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
Mkdir
(
name
string
,
mode
uint32
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
Mknod
(
name
string
,
mode
uint32
,
dev
uint32
,
context
*
Context
)
(
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
Mkdir
(
name
string
,
mode
uint32
,
context
*
Context
)
(
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
Unlink
(
name
string
,
context
*
Context
)
(
code
Status
)
Rmdir
(
name
string
,
context
*
Context
)
(
code
Status
)
Symlink
(
name
string
,
content
string
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
Symlink
(
name
string
,
content
string
,
context
*
Context
)
(
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
Rename
(
oldName
string
,
newParent
FsNode
,
newName
string
,
context
*
Context
)
(
code
Status
)
Link
(
name
string
,
existing
FsNode
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
Link
(
name
string
,
existing
FsNode
,
context
*
Context
)
(
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
// Files
Create
(
name
string
,
flags
uint32
,
mode
uint32
,
context
*
Context
)
(
file
File
,
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
Create
(
name
string
,
flags
uint32
,
mode
uint32
,
context
*
Context
)
(
file
File
,
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
Open
(
flags
uint32
,
context
*
Context
)
(
file
File
,
code
Status
)
OpenDir
(
context
*
Context
)
(
chan
DirEntry
,
Status
)
...
...
@@ -66,11 +65,11 @@ type FsNode interface {
ListXAttr
(
context
*
Context
)
(
attrs
[]
string
,
code
Status
)
// Attributes
GetAttr
(
file
File
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
code
Status
)
GetAttr
(
file
File
,
context
*
Context
)
(
fi
*
Attr
,
code
Status
)
Chmod
(
file
File
,
perms
uint32
,
context
*
Context
)
(
code
Status
)
Chown
(
file
File
,
uid
uint32
,
gid
uint32
,
context
*
Context
)
(
code
Status
)
Truncate
(
file
File
,
size
uint64
,
context
*
Context
)
(
code
Status
)
Utimens
(
file
File
,
atime
uint64
,
mtime
u
int64
,
context
*
Context
)
(
code
Status
)
Utimens
(
file
File
,
atime
int64
,
mtime
int64
,
context
*
Context
)
(
code
Status
)
StatFs
()
*
StatfsOut
}
...
...
@@ -92,12 +91,12 @@ type FileSystem interface {
// If the filesystem wants to implement hard-links, it should
// return consistent non-zero FileInfo.Ino data. Using
// hardlinks incurs a performance hit.
GetAttr
(
name
string
,
context
*
Context
)
(
*
os
.
FileInfo
,
Status
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
Attr
,
Status
)
// These should update the file's ctime too.
Chmod
(
name
string
,
mode
uint32
,
context
*
Context
)
(
code
Status
)
Chown
(
name
string
,
uid
uint32
,
gid
uint32
,
context
*
Context
)
(
code
Status
)
Utimens
(
name
string
,
AtimeNs
uint64
,
MtimeNs
u
int64
,
context
*
Context
)
(
code
Status
)
Utimens
(
name
string
,
AtimeNs
int64
,
MtimeNs
int64
,
context
*
Context
)
(
code
Status
)
Truncate
(
name
string
,
size
uint64
,
context
*
Context
)
(
code
Status
)
...
...
@@ -168,10 +167,10 @@ type File interface {
// The methods below may be called on closed files, due to
// concurrency. In that case, you should return EBADF.
Truncate
(
size
uint64
)
Status
GetAttr
()
(
*
os
.
FileInfo
,
Status
)
GetAttr
()
(
*
Attr
,
Status
)
Chown
(
uid
uint32
,
gid
uint32
)
Status
Chmod
(
perms
uint32
)
Status
Utimens
(
atimeNs
uint64
,
mtimeNs
u
int64
)
Status
Utimens
(
atimeNs
int64
,
mtimeNs
int64
)
Status
}
// Wrap a File return in this to set FUSE flags. Also used internally
...
...
fuse/attr.go
0 → 100644
View file @
77177c5d
package
fuse
import
(
"log"
"os"
"syscall"
)
type
FileMode
uint32
func
(
me
FileMode
)
String
()
string
{
switch
uint32
(
me
)
&
syscall
.
S_IFMT
{
case
syscall
.
S_IFIFO
:
return
"p"
case
syscall
.
S_IFCHR
:
return
"c"
case
syscall
.
S_IFDIR
:
return
"d"
case
syscall
.
S_IFBLK
:
return
"b"
case
syscall
.
S_IFREG
:
return
"f"
case
syscall
.
S_IFLNK
:
return
"l"
case
syscall
.
S_IFSOCK
:
return
"s"
default
:
log
.
Panic
(
"Unknown mode: %o"
,
me
)
}
return
"0"
}
func
(
me
FileMode
)
IsFifo
()
bool
{
return
(
uint32
(
me
)
&
syscall
.
S_IFMT
)
==
syscall
.
S_IFIFO
}
// IsChar reports whether the FileInfo describes a character special file.
func
(
me
FileMode
)
IsChar
()
bool
{
return
(
uint32
(
me
)
&
syscall
.
S_IFMT
)
==
syscall
.
S_IFCHR
}
// IsDirectory reports whether the FileInfo describes a directory.
func
(
me
FileMode
)
IsDirectory
()
bool
{
return
(
uint32
(
me
)
&
syscall
.
S_IFMT
)
==
syscall
.
S_IFDIR
}
// IsBlock reports whether the FileInfo describes a block special file.
func
(
me
FileMode
)
IsBlock
()
bool
{
return
(
uint32
(
me
)
&
syscall
.
S_IFMT
)
==
syscall
.
S_IFBLK
}
// IsRegular reports whether the FileInfo describes a regular file.
func
(
me
FileMode
)
IsRegular
()
bool
{
return
(
uint32
(
me
)
&
syscall
.
S_IFMT
)
==
syscall
.
S_IFREG
}
// IsSymlink reports whether the FileInfo describes a symbolic link.
func
(
me
FileMode
)
IsSymlink
()
bool
{
return
(
uint32
(
me
)
&
syscall
.
S_IFMT
)
==
syscall
.
S_IFLNK
}
// IsSocket reports whether the FileInfo describes a socket.
func
(
me
FileMode
)
IsSocket
()
bool
{
return
(
uint32
(
me
)
&
syscall
.
S_IFMT
)
==
syscall
.
S_IFSOCK
}
func
(
me
*
Attr
)
IsFifo
()
bool
{
return
(
uint32
(
me
.
Mode
)
&
syscall
.
S_IFMT
)
==
syscall
.
S_IFIFO
}
// IsChar reports whether the FileInfo describes a character special file.
func
(
me
*
Attr
)
IsChar
()
bool
{
return
(
uint32
(
me
.
Mode
)
&
syscall
.
S_IFMT
)
==
syscall
.
S_IFCHR
}
// IsDirectory reports whether the FileInfo describes a directory.
func
(
me
*
Attr
)
IsDirectory
()
bool
{
return
(
uint32
(
me
.
Mode
)
&
syscall
.
S_IFMT
)
==
syscall
.
S_IFDIR
}
// IsBlock reports whether the FileInfo describes a block special file.
func
(
me
*
Attr
)
IsBlock
()
bool
{
return
(
uint32
(
me
.
Mode
)
&
syscall
.
S_IFMT
)
==
syscall
.
S_IFBLK
}
// IsRegular reports whether the FileInfo describes a regular file.
func
(
me
*
Attr
)
IsRegular
()
bool
{
return
(
uint32
(
me
.
Mode
)
&
syscall
.
S_IFMT
)
==
syscall
.
S_IFREG
}
// IsSymlink reports whether the FileInfo describes a symbolic link.
func
(
me
*
Attr
)
IsSymlink
()
bool
{
return
(
uint32
(
me
.
Mode
)
&
syscall
.
S_IFMT
)
==
syscall
.
S_IFLNK
}
// IsSocket reports whether the FileInfo describes a socket.
func
(
me
*
Attr
)
IsSocket
()
bool
{
return
(
uint32
(
me
.
Mode
)
&
syscall
.
S_IFMT
)
==
syscall
.
S_IFSOCK
}
func
(
a
*
Attr
)
Atimens
()
int64
{
return
int64
(
1e9
*
a
.
Atime
)
+
int64
(
a
.
Atimensec
)
}
func
(
a
*
Attr
)
Mtimens
()
int64
{
return
int64
(
1e9
*
a
.
Mtime
)
+
int64
(
a
.
Mtimensec
)
}
func
(
a
*
Attr
)
Ctimens
()
int64
{
return
int64
(
1e9
*
a
.
Ctime
)
+
int64
(
a
.
Ctimensec
)
}
func
(
a
*
Attr
)
SetTimes
(
atimens
int64
,
mtimens
int64
,
ctimens
int64
)
{
if
atimens
>=
0
{
a
.
Atime
=
uint64
(
atimens
/
1e9
)
a
.
Atimensec
=
uint32
(
atimens
%
1e9
)
}
if
mtimens
>=
0
{
a
.
Mtime
=
uint64
(
mtimens
/
1e9
)
a
.
Mtimensec
=
uint32
(
mtimens
%
1e9
)
}
if
atimens
>=
0
{
a
.
Ctime
=
uint64
(
ctimens
/
1e9
)
a
.
Ctimensec
=
uint32
(
ctimens
%
1e9
)
}
}
func
(
attr
*
Attr
)
FromFileInfo
(
fi
*
os
.
FileInfo
)
{
attr
.
Ino
=
uint64
(
fi
.
Ino
)
attr
.
Size
=
uint64
(
fi
.
Size
)
attr
.
Blocks
=
uint64
(
fi
.
Blocks
)
attr
.
SetTimes
(
fi
.
Atime_ns
,
fi
.
Mtime_ns
,
fi
.
Ctime_ns
)
attr
.
Mode
=
fi
.
Mode
attr
.
Nlink
=
uint32
(
fi
.
Nlink
)
attr
.
Uid
=
uint32
(
fi
.
Uid
)
attr
.
Gid
=
uint32
(
fi
.
Gid
)
attr
.
Rdev
=
uint32
(
fi
.
Rdev
)
attr
.
Blksize
=
uint32
(
fi
.
Blksize
)
}
func
(
a
*
Attr
)
ToFileInfo
()
(
fi
*
os
.
FileInfo
)
{
return
&
os
.
FileInfo
{
Ino
:
a
.
Ino
,
Size
:
int64
(
a
.
Size
),
Atime_ns
:
a
.
Atimens
(),
Mtime_ns
:
a
.
Mtimens
(),
Ctime_ns
:
a
.
Ctimens
(),
Blocks
:
int64
(
a
.
Blocks
),
Mode
:
a
.
Mode
,
Nlink
:
uint64
(
a
.
Nlink
),
Uid
:
int
(
a
.
Uid
),
Gid
:
int
(
a
.
Gid
),
Rdev
:
uint64
(
a
.
Rdev
),
Blksize
:
int64
(
a
.
Blksize
),
}
}
fuse/cache_test.go
View file @
77177c5d
...
...
@@ -74,6 +74,7 @@ func TestCacheFs(t *testing.T) {
c
,
err
=
ioutil
.
ReadFile
(
wd
+
"/mnt/file.txt"
)
CheckSuccess
(
err
)
// x
if
string
(
c
)
!=
"hello"
{
t
.
Fatalf
(
"Page cache skipped: expect 'hello' %q"
,
string
(
c
))
}
...
...
@@ -95,9 +96,9 @@ type nonseekFs struct {
Length
int
}
func
(
me
*
nonseekFs
)
GetAttr
(
name
string
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
status
Status
)
{
func
(
me
*
nonseekFs
)
GetAttr
(
name
string
,
context
*
Context
)
(
fi
*
Attr
,
status
Status
)
{
if
name
==
"file"
{
return
&
os
.
FileInfo
{
Mode
:
S_IFREG
|
0644
},
OK
return
&
Attr
{
Mode
:
S_IFREG
|
0644
},
OK
}
return
nil
,
ENOENT
}
...
...
fuse/default.go
View file @
77177c5d
package
fuse
import
(
"os"
)
// DefaultFileSystem
func
(
me
*
DefaultFileSystem
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
os
.
FileInfo
,
Status
)
{
func
(
me
*
DefaultFileSystem
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
Attr
,
Status
)
{
return
nil
,
ENOSYS
}
...
...
@@ -91,7 +90,7 @@ func (me *DefaultFileSystem) Create(name string, flags uint32, mode uint32, cont
return
nil
,
ENOSYS
}
func
(
me
*
DefaultFileSystem
)
Utimens
(
name
string
,
AtimeNs
uint64
,
CtimeNs
u
int64
,
context
*
Context
)
(
code
Status
)
{
func
(
me
*
DefaultFileSystem
)
Utimens
(
name
string
,
AtimeNs
int64
,
CtimeNs
int64
,
context
*
Context
)
(
code
Status
)
{
return
ENOSYS
}
...
...
fuse/defaultfile.go
View file @
77177c5d
...
...
@@ -2,7 +2,6 @@ package fuse
import
(
"log"
"os"
)
var
_
=
log
.
Println
...
...
@@ -34,7 +33,7 @@ func (me *DefaultFile) Release() {
}
func
(
me
*
DefaultFile
)
GetAttr
()
(
*
os
.
FileInfo
,
Status
)
{
func
(
me
*
DefaultFile
)
GetAttr
()
(
*
Attr
,
Status
)
{
return
nil
,
ENOSYS
}
...
...
@@ -42,7 +41,7 @@ func (me *DefaultFile) Fsync(*FsyncIn) (code Status) {
return
ENOSYS
}
func
(
me
*
DefaultFile
)
Utimens
(
atimeNs
uint64
,
mtimeNs
u
int64
)
Status
{
func
(
me
*
DefaultFile
)
Utimens
(
atimeNs
int64
,
mtimeNs
int64
)
Status
{
return
ENOSYS
}
...
...
fuse/defaultnode.go
View file @
77177c5d
...
...
@@ -2,7 +2,6 @@ package fuse
import
(
"log"
"os"
)
var
_
=
log
.
Println
...
...
@@ -55,7 +54,7 @@ func (me *DefaultFsNode) Inode() *Inode {
func
(
me
*
DefaultFsNode
)
OnForget
()
{
}
func
(
me
*
DefaultFsNode
)
Lookup
(
name
string
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
node
FsNode
,
code
Status
)
{
func
(
me
*
DefaultFsNode
)
Lookup
(
name
string
,
context
*
Context
)
(
fi
*
Attr
,
node
FsNode
,
code
Status
)
{
return
nil
,
nil
,
ENOENT
}
...
...
@@ -67,10 +66,10 @@ func (me *DefaultFsNode) Readlink(c *Context) ([]byte, Status) {
return
nil
,
ENOSYS
}
func
(
me
*
DefaultFsNode
)
Mknod
(
name
string
,
mode
uint32
,
dev
uint32
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
{
func
(
me
*
DefaultFsNode
)
Mknod
(
name
string
,
mode
uint32
,
dev
uint32
,
context
*
Context
)
(
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
{
return
nil
,
nil
,
ENOSYS
}
func
(
me
*
DefaultFsNode
)
Mkdir
(
name
string
,
mode
uint32
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
{
func
(
me
*
DefaultFsNode
)
Mkdir
(
name
string
,
mode
uint32
,
context
*
Context
)
(
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
{
return
nil
,
nil
,
ENOSYS
}
func
(
me
*
DefaultFsNode
)
Unlink
(
name
string
,
context
*
Context
)
(
code
Status
)
{
...
...
@@ -79,7 +78,7 @@ func (me *DefaultFsNode) Unlink(name string, context *Context) (code Status) {
func
(
me
*
DefaultFsNode
)
Rmdir
(
name
string
,
context
*
Context
)
(
code
Status
)
{
return
ENOSYS
}
func
(
me
*
DefaultFsNode
)
Symlink
(
name
string
,
content
string
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
{
func
(
me
*
DefaultFsNode
)
Symlink
(
name
string
,
content
string
,
context
*
Context
)
(
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
{
return
nil
,
nil
,
ENOSYS
}
...
...
@@ -87,11 +86,11 @@ func (me *DefaultFsNode) Rename(oldName string, newParent FsNode, newName string
return
ENOSYS
}
func
(
me
*
DefaultFsNode
)
Link
(
name
string
,
existing
FsNode
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
{
func
(
me
*
DefaultFsNode
)
Link
(
name
string
,
existing
FsNode
,
context
*
Context
)
(
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
{
return
nil
,
nil
,
ENOSYS
}
func
(
me
*
DefaultFsNode
)
Create
(
name
string
,
flags
uint32
,
mode
uint32
,
context
*
Context
)
(
file
File
,
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
{
func
(
me
*
DefaultFsNode
)
Create
(
name
string
,
flags
uint32
,
mode
uint32
,
context
*
Context
)
(
file
File
,
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
{
return
nil
,
nil
,
nil
,
ENOSYS
}
...
...
@@ -132,11 +131,11 @@ func (me *DefaultFsNode) ListXAttr(context *Context) (attrs []string, code Statu
return
nil
,
ENOSYS
}
func
(
me
*
DefaultFsNode
)
GetAttr
(
file
File
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
code
Status
)
{
func
(
me
*
DefaultFsNode
)
GetAttr
(
file
File
,
context
*
Context
)
(
fi
*
Attr
,
code
Status
)
{
if
me
.
Inode
()
.
IsDir
()
{
return
&
os
.
FileInfo
{
Mode
:
S_IFDIR
|
0755
},
OK
return
&
Attr
{
Mode
:
S_IFDIR
|
0755
},
OK
}
return
&
os
.
FileInfo
{
Mode
:
S_IFREG
|
0644
},
OK
return
&
Attr
{
Mode
:
S_IFREG
|
0644
},
OK
}
func
(
me
*
DefaultFsNode
)
Chmod
(
file
File
,
perms
uint32
,
context
*
Context
)
(
code
Status
)
{
...
...
@@ -151,6 +150,6 @@ func (me *DefaultFsNode) Truncate(file File, size uint64, context *Context) (cod
return
ENOSYS
}
func
(
me
*
DefaultFsNode
)
Utimens
(
file
File
,
atime
uint64
,
mtime
u
int64
,
context
*
Context
)
(
code
Status
)
{
func
(
me
*
DefaultFsNode
)
Utimens
(
file
File
,
atime
int64
,
mtime
int64
,
context
*
Context
)
(
code
Status
)
{
return
ENOSYS
}
fuse/files.go
View file @
77177c5d
...
...
@@ -26,8 +26,8 @@ func (me *DataFile) String() string {
return
fmt
.
Sprintf
(
"DataFile(%x)"
,
me
.
data
[
:
l
])
}
func
(
me
*
DataFile
)
GetAttr
()
(
*
os
.
FileInfo
,
Status
)
{
return
&
os
.
FileInfo
{
Mode
:
S_IFREG
|
0644
,
Size
:
int64
(
len
(
me
.
data
))},
OK
func
(
me
*
DataFile
)
GetAttr
()
(
*
Attr
,
Status
)
{
return
&
Attr
{
Mode
:
S_IFREG
|
0644
,
Size
:
u
int64
(
len
(
me
.
data
))},
OK
}
func
NewDataFile
(
data
[]
byte
)
*
DataFile
{
...
...
@@ -130,12 +130,14 @@ func (me *LoopbackFile) Chown(uid uint32, gid uint32) Status {
return
ToStatus
(
me
.
File
.
Chown
(
int
(
uid
),
int
(
gid
)))
}
func
(
me
*
LoopbackFile
)
GetAttr
()
(
*
os
.
FileInfo
,
Status
)
{
func
(
me
*
LoopbackFile
)
GetAttr
()
(
*
Attr
,
Status
)
{
fi
,
err
:=
me
.
File
.
Stat
()
if
err
!=
nil
{
return
nil
,
ToStatus
(
err
)
}
return
fi
,
OK
a
:=
&
Attr
{}
a
.
FromFileInfo
(
fi
)
return
a
,
OK
}
////////////////////////////////////////////////////////////////
...
...
fuse/fsconnector.go
View file @
77177c5d
...
...
@@ -6,7 +6,6 @@ package fuse
import
(
"log"
"os"
"path/filepath"
"strings"
"unsafe"
...
...
@@ -77,7 +76,7 @@ func (me *FileSystemConnector) verify() {
}
// Generate EntryOut and increase the lookup count for an inode.
func
(
me
*
FileSystemConnector
)
childLookup
(
fi
*
os
.
FileInfo
,
fsi
FsNode
)
(
out
*
EntryOut
)
{
func
(
me
*
FileSystemConnector
)
childLookup
(
fi
*
Attr
,
fsi
FsNode
)
(
out
*
EntryOut
)
{
n
:=
fsi
.
Inode
()
out
=
n
.
mount
.
fileInfoToEntry
(
fi
)
out
.
Ino
=
me
.
lookupUpdate
(
n
)
...
...
fuse/fsetattr_test.go
View file @
77177c5d
...
...
@@ -11,10 +11,14 @@ type MutableDataFile struct {
DefaultFile
data
[]
byte
os
.
FileInfo
Attr
GetAttrCalled
bool
}
func
(
me
*
MutableDataFile
)
String
()
string
{
return
"MutableDataFile"
}
func
(
me
*
MutableDataFile
)
Read
(
r
*
ReadIn
,
bp
BufferPool
)
([]
byte
,
Status
)
{
return
me
.
data
[
r
.
Offset
:
r
.
Offset
+
uint64
(
r
.
Size
)],
OK
}
...
...
@@ -38,13 +42,13 @@ func (me *MutableDataFile) Release() {
}
func
(
me
*
MutableDataFile
)
getAttr
()
*
os
.
FileInfo
{
f
:=
me
.
FileInfo
f
.
Size
=
int64
(
len
(
me
.
data
))
func
(
me
*
MutableDataFile
)
getAttr
()
*
Attr
{
f
:=
me
.
Attr
f
.
Size
=
u
int64
(
len
(
me
.
data
))
return
&
f
}
func
(
me
*
MutableDataFile
)
GetAttr
()
(
*
os
.
FileInfo
,
Status
)
{
func
(
me
*
MutableDataFile
)
GetAttr
()
(
*
Attr
,
Status
)
{
me
.
GetAttrCalled
=
true
return
me
.
getAttr
(),
OK
}
...
...
@@ -53,9 +57,8 @@ func (me *MutableDataFile) Fsync(*FsyncIn) (code Status) {
return
OK
}
func
(
me
*
MutableDataFile
)
Utimens
(
atimeNs
uint64
,
mtimeNs
uint64
)
Status
{
me
.
FileInfo
.
Atime_ns
=
int64
(
atimeNs
)
me
.
FileInfo
.
Mtime_ns
=
int64
(
mtimeNs
)
func
(
me
*
MutableDataFile
)
Utimens
(
atimeNs
int64
,
mtimeNs
int64
)
Status
{
me
.
Attr
.
SetTimes
(
atimeNs
,
mtimeNs
,
-
1
)
return
OK
}
...
...
@@ -65,13 +68,13 @@ func (me *MutableDataFile) Truncate(size uint64) Status {
}
func
(
me
*
MutableDataFile
)
Chown
(
uid
uint32
,
gid
uint32
)
Status
{
me
.
FileInfo
.
Uid
=
int
(
uid
)
me
.
FileInfo
.
Gid
=
int
(
uid
)
me
.
Attr
.
Uid
=
uid
me
.
Attr
.
Gid
=
gid
return
OK
}
func
(
me
*
MutableDataFile
)
Chmod
(
perms
uint32
)
Status
{
me
.
FileInfo
.
Mode
=
(
me
.
FileInfo
.
Mode
&^
07777
)
|
perms
me
.
Attr
.
Mode
=
(
me
.
Attr
.
Mode
&^
07777
)
|
perms
return
OK
}
...
...
@@ -86,9 +89,9 @@ func (me *FSetAttrFs) GetXAttr(name string, attr string, context *Context) ([]by
return
nil
,
ENODATA
}
func
(
me
*
FSetAttrFs
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
os
.
FileInfo
,
Status
)
{
func
(
me
*
FSetAttrFs
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
Attr
,
Status
)
{
if
name
==
""
{
return
&
os
.
FileInfo
{
Mode
:
S_IFDIR
|
0700
},
OK
return
&
Attr
{
Mode
:
S_IFDIR
|
0700
},
OK
}
if
name
==
"file"
&&
me
.
file
!=
nil
{
a
:=
me
.
file
.
getAttr
()
...
...
@@ -109,7 +112,7 @@ func (me *FSetAttrFs) Create(name string, flags uint32, mode uint32, context *Co
if
name
==
"file"
{
f
:=
NewFile
()
me
.
file
=
f
me
.
file
.
FileInfo
.
Mode
=
mode
me
.
file
.
Attr
.
Mode
=
mode
return
f
,
OK
}
return
nil
,
ENOENT
...
...
@@ -168,15 +171,15 @@ func TestFSetAttr(t *testing.T) {
err
=
f
.
Chmod
(
024
)
CheckSuccess
(
err
)
if
fs
.
file
.
FileInfo
.
Mode
&
07777
!=
024
{
if
fs
.
file
.
Attr
.
Mode
&
07777
!=
024
{
t
.
Error
(
"chmod"
)
}
err
=
os
.
Chtimes
(
fn
,
100e3
,
101e3
)
CheckSuccess
(
err
)
if
fs
.
file
.
FileInfo
.
Atime_ns
!=
100e3
||
fs
.
file
.
FileInfo
.
Mtime_ns
!=
101e3
{
if
fs
.
file
.
Attr
.
Atimensec
!=
100e3
||
fs
.
file
.
Attr
.
Mtimensec
!=
101e3
{
t
.
Errorf
(
"Utimens: atime %d != 100e3 mtime %d != 101e3"
,
fs
.
file
.
FileInfo
.
Atime_ns
,
fs
.
file
.
FileInfo
.
Mtime_ns
)
fs
.
file
.
Attr
.
Atimensec
,
fs
.
file
.
Attr
.
Mtimensec
)
}
newFi
,
err
:=
f
.
Stat
()
...
...
fuse/fsmount.go
View file @
77177c5d
...
...
@@ -2,7 +2,6 @@ package fuse
import
(
"log"
"os"
"sync"
"unsafe"
)
...
...
@@ -60,21 +59,22 @@ func (me *fileSystemMount) setOwner(attr *Attr) {
}
}
func
(
me
*
fileSystemMount
)
fileInfoToEntry
(
fi
*
os
.
FileInfo
)
(
out
*
EntryOut
)
{
func
(
me
*
fileSystemMount
)
fileInfoToEntry
(
attr
*
Attr
)
(
out
*
EntryOut
)
{
out
=
&
EntryOut
{}
out
.
Attr
=
*
attr
splitNs
(
me
.
options
.
EntryTimeout
,
&
out
.
EntryValid
,
&
out
.
EntryValidNsec
)
splitNs
(
me
.
options
.
AttrTimeout
,
&
out
.
AttrValid
,
&
out
.
AttrValidNsec
)
out
.
Attr
.
FromFileInfo
(
fi
)
me
.
setOwner
(
&
out
.
Attr
)
if
!
fi
.
IsDirectory
()
&&
fi
.
Nlink
==
0
{
if
!
attr
.
IsDirectory
()
&&
attr
.
Nlink
==
0
{
out
.
Nlink
=
1
}
return
out
}
func
(
me
*
fileSystemMount
)
fil
eInfoToAttr
(
fi
*
os
.
FileInfo
,
nodeId
uint64
)
(
out
*
AttrOut
)
{
func
(
me
*
fileSystemMount
)
fil
lAttr
(
a
*
Attr
,
nodeId
uint64
)
(
out
*
AttrOut
)
{
out
=
&
AttrOut
{}
out
.
Attr
.
FromFileInfo
(
fi
)
out
.
Attr
=
*
a
splitNs
(
me
.
options
.
AttrTimeout
,
&
out
.
AttrValid
,
&
out
.
AttrValidNsec
)
me
.
setOwner
(
&
out
.
Attr
)
out
.
Ino
=
nodeId
...
...
fuse/fsops.go
View file @
77177c5d
...
...
@@ -5,7 +5,6 @@ package fuse
import
(
"bytes"
"log"
"os"
"time"
)
...
...
@@ -15,17 +14,17 @@ func (me *FileSystemConnector) Init(fsInit *RawFsInit) {
me
.
fsInit
=
*
fsInit
}
func
(
me
*
FileSystemConnector
)
lookupMountUpdate
(
mount
*
fileSystemMount
)
(
fi
*
os
.
FileInfo
,
node
*
Inode
,
code
Status
)
{
func
(
me
*
FileSystemConnector
)
lookupMountUpdate
(
mount
*
fileSystemMount
)
(
fi
*
Attr
,
node
*
Inode
,
code
Status
)
{
fi
,
code
=
mount
.
fs
.
Root
()
.
GetAttr
(
nil
,
nil
)
if
!
code
.
Ok
()
{
log
.
Println
(
"Root getattr should not return error"
,
code
)
return
&
os
.
FileInfo
{
Mode
:
S_IFDIR
|
0755
},
mount
.
mountInode
,
OK
return
&
Attr
{
Mode
:
S_IFDIR
|
0755
},
mount
.
mountInode
,
OK
}
return
fi
,
mount
.
mountInode
,
OK
}
func
(
me
*
FileSystemConnector
)
internalLookup
(
parent
*
Inode
,
name
string
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
node
*
Inode
,
code
Status
)
{
func
(
me
*
FileSystemConnector
)
internalLookup
(
parent
*
Inode
,
name
string
,
context
*
Context
)
(
fi
*
Attr
,
node
*
Inode
,
code
Status
)
{
if
subMount
:=
me
.
findMount
(
parent
,
name
);
subMount
!=
nil
{
return
me
.
lookupMountUpdate
(
subMount
)
}
...
...
@@ -89,7 +88,7 @@ func (me *FileSystemConnector) GetAttr(header *InHeader, input *GetAttrIn) (out
if
!
code
.
Ok
()
{
return
nil
,
code
}
out
=
node
.
mount
.
fil
eInfoTo
Attr
(
fi
,
header
.
NodeId
)
out
=
node
.
mount
.
fil
l
Attr
(
fi
,
header
.
NodeId
)
return
out
,
OK
}
...
...
@@ -151,17 +150,17 @@ func (me *FileSystemConnector) SetAttr(header *InHeader, input *SetAttrIn) (out
code
=
node
.
fsInode
.
Truncate
(
f
,
input
.
Size
,
&
header
.
Context
)
}
if
code
.
Ok
()
&&
(
input
.
Valid
&
(
FATTR_ATIME
|
FATTR_MTIME
|
FATTR_ATIME_NOW
|
FATTR_MTIME_NOW
)
!=
0
)
{
now
:=
u
int64
(
0
)
now
:=
int64
(
0
)
if
input
.
Valid
&
FATTR_ATIME_NOW
!=
0
||
input
.
Valid
&
FATTR_MTIME_NOW
!=
0
{
now
=
uint64
(
time
.
Nanoseconds
()
)
now
=
time
.
Nanoseconds
(
)
}
atime
:=
uint64
(
input
.
Atime
*
1e9
)
+
u
int64
(
input
.
Atimensec
)
atime
:=
int64
(
input
.
Atime
*
1e9
)
+
int64
(
input
.
Atimensec
)
if
input
.
Valid
&
FATTR_ATIME_NOW
!=
0
{
atime
=
now
}
mtime
:=
uint64
(
input
.
Mtime
*
1e9
)
+
u
int64
(
input
.
Mtimensec
)
mtime
:=
int64
(
input
.
Mtime
*
1e9
)
+
int64
(
input
.
Mtimensec
)
if
input
.
Valid
&
FATTR_MTIME_NOW
!=
0
{
mtime
=
now
}
...
...
@@ -178,7 +177,7 @@ func (me *FileSystemConnector) SetAttr(header *InHeader, input *SetAttrIn) (out
fi
,
code
:=
node
.
fsInode
.
GetAttr
(
f
,
&
header
.
Context
)
if
code
.
Ok
()
{
out
=
node
.
mount
.
fil
eInfoTo
Attr
(
fi
,
header
.
NodeId
)
out
=
node
.
mount
.
fil
l
Attr
(
fi
,
header
.
NodeId
)
}
return
out
,
code
}
...
...
fuse/lockingfs.go
View file @
77177c5d
package
fuse
import
(
"os"
"sync"
)
...
...
@@ -26,7 +25,7 @@ func (me *LockingFileSystem) locked() func() {
return
func
()
{
me
.
lock
.
Unlock
()
}
}
func
(
me
*
LockingFileSystem
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
os
.
FileInfo
,
Status
)
{
func
(
me
*
LockingFileSystem
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
Attr
,
Status
)
{
defer
me
.
locked
()()
return
me
.
FileSystem
.
GetAttr
(
name
,
context
)
}
...
...
@@ -115,7 +114,7 @@ func (me *LockingFileSystem) Create(name string, flags uint32, mode uint32, cont
return
me
.
FileSystem
.
Create
(
name
,
flags
,
mode
,
context
)
}
func
(
me
*
LockingFileSystem
)
Utimens
(
name
string
,
AtimeNs
uint64
,
CtimeNs
u
int64
,
context
*
Context
)
(
code
Status
)
{
func
(
me
*
LockingFileSystem
)
Utimens
(
name
string
,
AtimeNs
int64
,
CtimeNs
int64
,
context
*
Context
)
(
code
Status
)
{
defer
me
.
locked
()()
return
me
.
FileSystem
.
Utimens
(
name
,
AtimeNs
,
CtimeNs
,
context
)
}
...
...
fuse/loopback.go
View file @
77177c5d
...
...
@@ -33,9 +33,10 @@ func (me *LoopbackFileSystem) GetPath(relPath string) string {
return
filepath
.
Join
(
me
.
Root
,
relPath
)
}
func
(
me
*
LoopbackFileSystem
)
GetAttr
(
name
string
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
code
Status
)
{
func
(
me
*
LoopbackFileSystem
)
GetAttr
(
name
string
,
context
*
Context
)
(
a
*
Attr
,
code
Status
)
{
fullPath
:=
me
.
GetPath
(
name
)
var
err
error
=
nil
var
fi
*
os
.
FileInfo
if
name
==
""
{
// When GetAttr is called for the toplevel directory, we always want
// to look through symlinks.
...
...
@@ -46,7 +47,9 @@ func (me *LoopbackFileSystem) GetAttr(name string, context *Context) (fi *os.Fil
if
err
!=
nil
{
return
nil
,
ToStatus
(
err
)
}
return
fi
,
OK
a
=
&
Attr
{}
a
.
FromFileInfo
(
fi
)
return
a
,
OK
}
func
(
me
*
LoopbackFileSystem
)
OpenDir
(
name
string
,
context
*
Context
)
(
stream
chan
DirEntry
,
status
Status
)
{
...
...
@@ -103,7 +106,7 @@ func (me *LoopbackFileSystem) Truncate(path string, offset uint64, context *Cont
return
ToStatus
(
os
.
Truncate
(
me
.
GetPath
(
path
),
int64
(
offset
)))
}
func
(
me
*
LoopbackFileSystem
)
Utimens
(
path
string
,
AtimeNs
uint64
,
MtimeNs
u
int64
,
context
*
Context
)
(
code
Status
)
{
func
(
me
*
LoopbackFileSystem
)
Utimens
(
path
string
,
AtimeNs
int64
,
MtimeNs
int64
,
context
*
Context
)
(
code
Status
)
{
return
ToStatus
(
os
.
Chtimes
(
me
.
GetPath
(
path
),
int64
(
AtimeNs
),
int64
(
MtimeNs
)))
}
...
...
fuse/memnode.go
View file @
77177c5d
...
...
@@ -35,9 +35,7 @@ func (me *MemNodeFs) newNode() *memNode {
id
:
me
.
nextFree
,
}
now
:=
time
.
Nanoseconds
()
n
.
info
.
Mtime_ns
=
now
n
.
info
.
Atime_ns
=
now
n
.
info
.
Ctime_ns
=
now
n
.
info
.
SetTimes
(
now
,
now
,
now
)
n
.
info
.
Mode
=
S_IFDIR
|
0777
me
.
nextFree
++
return
n
...
...
@@ -61,7 +59,7 @@ type memNode struct {
id
int
link
string
info
os
.
FileInfo
info
Attr
}
func
(
me
*
memNode
)
newNode
(
isdir
bool
)
*
memNode
{
...
...
@@ -82,7 +80,7 @@ func (me *memNode) Readlink(c *Context) ([]byte, Status) {
return
[]
byte
(
me
.
link
),
OK
}
func
(
me
*
memNode
)
Mkdir
(
name
string
,
mode
uint32
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
{
func
(
me
*
memNode
)
Mkdir
(
name
string
,
mode
uint32
,
context
*
Context
)
(
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
{
n
:=
me
.
newNode
(
true
)
n
.
info
.
Mode
=
mode
|
S_IFDIR
me
.
Inode
()
.
AddChild
(
name
,
n
.
Inode
())
...
...
@@ -101,7 +99,7 @@ func (me *memNode) Rmdir(name string, context *Context) (code Status) {
return
me
.
Unlink
(
name
,
context
)
}
func
(
me
*
memNode
)
Symlink
(
name
string
,
content
string
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
{
func
(
me
*
memNode
)
Symlink
(
name
string
,
content
string
,
context
*
Context
)
(
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
{
n
:=
me
.
newNode
(
false
)
n
.
info
.
Mode
=
S_IFLNK
|
0777
n
.
link
=
content
...
...
@@ -117,13 +115,13 @@ func (me *memNode) Rename(oldName string, newParent FsNode, newName string, cont
return
OK
}
func
(
me
*
memNode
)
Link
(
name
string
,
existing
FsNode
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
{
func
(
me
*
memNode
)
Link
(
name
string
,
existing
FsNode
,
context
*
Context
)
(
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
{
me
.
Inode
()
.
AddChild
(
name
,
existing
.
Inode
())
fi
,
code
=
existing
.
GetAttr
(
nil
,
context
)
return
fi
,
existing
,
code
}
func
(
me
*
memNode
)
Create
(
name
string
,
flags
uint32
,
mode
uint32
,
context
*
Context
)
(
file
File
,
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
{
func
(
me
*
memNode
)
Create
(
name
string
,
flags
uint32
,
mode
uint32
,
context
*
Context
)
(
file
File
,
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
{
n
:=
me
.
newNode
(
false
)
n
.
info
.
Mode
=
mode
|
S_IFREG
...
...
@@ -172,7 +170,7 @@ func (me *memNode) Open(flags uint32, context *Context) (file File, code Status)
return
me
.
newFile
(
f
),
OK
}
func
(
me
*
memNode
)
GetAttr
(
file
File
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
code
Status
)
{
func
(
me
*
memNode
)
GetAttr
(
file
File
,
context
*
Context
)
(
fi
*
Attr
,
code
Status
)
{
return
&
me
.
info
,
OK
}
...
...
@@ -184,29 +182,27 @@ func (me *memNode) Truncate(file File, size uint64, context *Context) (code Stat
code
=
ToStatus
(
err
)
}
if
code
.
Ok
()
{
me
.
info
.
Ctime_ns
=
time
.
Nanoseconds
(
)
me
.
info
.
SetTimes
(
-
1
,
-
1
,
time
.
Nanoseconds
()
)
// TODO - should update mtime too?
me
.
info
.
Size
=
int64
(
size
)
me
.
info
.
Size
=
size
}
return
code
}
func
(
me
*
memNode
)
Utimens
(
file
File
,
atime
uint64
,
mtime
uint64
,
context
*
Context
)
(
code
Status
)
{
me
.
info
.
Atime_ns
=
int64
(
atime
)
me
.
info
.
Mtime_ns
=
int64
(
mtime
)
me
.
info
.
Ctime_ns
=
time
.
Nanoseconds
()
func
(
me
*
memNode
)
Utimens
(
file
File
,
atime
int64
,
mtime
int64
,
context
*
Context
)
(
code
Status
)
{
me
.
info
.
SetTimes
(
int64
(
atime
),
int64
(
mtime
),
time
.
Nanoseconds
())
return
OK
}
func
(
me
*
memNode
)
Chmod
(
file
File
,
perms
uint32
,
context
*
Context
)
(
code
Status
)
{
me
.
info
.
Mode
=
(
me
.
info
.
Mode
^
07777
)
|
perms
me
.
info
.
Ctime_ns
=
time
.
Nanoseconds
(
)
me
.
info
.
SetTimes
(
-
1
,
-
1
,
time
.
Nanoseconds
()
)
return
OK
}
func
(
me
*
memNode
)
Chown
(
file
File
,
uid
uint32
,
gid
uint32
,
context
*
Context
)
(
code
Status
)
{
me
.
info
.
Uid
=
int
(
uid
)
me
.
info
.
Gid
=
int
(
gid
)
me
.
info
.
Ctime_ns
=
time
.
Nanoseconds
(
)
me
.
info
.
Uid
=
uid
me
.
info
.
Gid
=
gid
me
.
info
.
SetTimes
(
-
1
,
-
1
,
time
.
Nanoseconds
()
)
return
OK
}
fuse/misc.go
View file @
77177c5d
...
...
@@ -55,28 +55,6 @@ func splitNs(time float64, secs *uint64, nsecs *uint32) {
*
secs
=
uint64
(
math
.
Trunc
(
time
))
}
func
(
attr
*
Attr
)
FromFileInfo
(
fi
*
os
.
FileInfo
)
{
attr
.
Ino
=
uint64
(
fi
.
Ino
)
attr
.
Size
=
uint64
(
fi
.
Size
)
attr
.
Blocks
=
uint64
(
fi
.
Blocks
)
attr
.
Atime
=
uint64
(
fi
.
Atime_ns
/
1e9
)
attr
.
Atimensec
=
uint32
(
fi
.
Atime_ns
%
1e9
)
attr
.
Mtime
=
uint64
(
fi
.
Mtime_ns
/
1e9
)
attr
.
Mtimensec
=
uint32
(
fi
.
Mtime_ns
%
1e9
)
attr
.
Ctime
=
uint64
(
fi
.
Ctime_ns
/
1e9
)
attr
.
Ctimensec
=
uint32
(
fi
.
Ctime_ns
%
1e9
)
attr
.
Mode
=
fi
.
Mode
attr
.
Nlink
=
uint32
(
fi
.
Nlink
)
attr
.
Uid
=
uint32
(
fi
.
Uid
)
attr
.
Gid
=
uint32
(
fi
.
Gid
)
attr
.
Rdev
=
uint32
(
fi
.
Rdev
)
attr
.
Blksize
=
uint32
(
fi
.
Blksize
)
}
// TODO - expose in Go's syscall package.
func
writev
(
fd
int
,
iovecs
*
syscall
.
Iovec
,
cnt
int
)
(
n
int
,
errno
int
)
{
n1
,
_
,
e1
:=
syscall
.
Syscall
(
...
...
fuse/notify_test.go
View file @
77177c5d
...
...
@@ -11,19 +11,19 @@ var _ = log.Println
type
NotifyFs
struct
{
DefaultFileSystem
size
int64
size
u
int64
exist
bool
}
func
(
me
*
NotifyFs
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
os
.
FileInfo
,
Status
)
{
func
(
me
*
NotifyFs
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
Attr
,
Status
)
{
if
name
==
""
{
return
&
os
.
FileInfo
{
Mode
:
S_IFDIR
|
0755
},
OK
return
&
Attr
{
Mode
:
S_IFDIR
|
0755
},
OK
}
if
name
==
"file"
||
(
name
==
"dir/file"
&&
me
.
exist
)
{
return
&
os
.
FileInfo
{
Mode
:
S_IFREG
|
0644
,
Size
:
me
.
size
},
OK
return
&
Attr
{
Mode
:
S_IFREG
|
0644
,
Size
:
me
.
size
},
OK
}
if
name
==
"dir"
{
return
&
os
.
FileInfo
{
Mode
:
S_IFDIR
|
0755
},
OK
return
&
Attr
{
Mode
:
S_IFDIR
|
0755
},
OK
}
return
nil
,
ENOENT
}
...
...
fuse/owner_test.go
View file @
77177c5d
...
...
@@ -12,17 +12,18 @@ type ownerFs struct {
const
_RANDOM_OWNER
=
31415265
func
(
me
*
ownerFs
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
os
.
FileInfo
,
Status
)
{
func
(
me
*
ownerFs
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
Attr
,
Status
)
{
if
name
==
""
{
return
&
os
.
FileInfo
{
return
&
Attr
{
Mode
:
S_IFDIR
|
0755
,
},
OK
}
return
&
os
.
FileInfo
{
a
:=
&
Attr
{
Mode
:
S_IFREG
|
0644
,
Uid
:
_RANDOM_OWNER
,
Gid
:
_RANDOM_OWNER
,
},
OK
}
a
.
Uid
=
_RANDOM_OWNER
a
.
Gid
=
_RANDOM_OWNER
return
a
,
OK
}
func
setupOwnerTest
(
opts
*
FileSystemOptions
)
(
workdir
string
,
cleanup
func
())
{
...
...
fuse/pathfs.go
View file @
77177c5d
...
...
@@ -3,7 +3,6 @@ package fuse
import
(
"fmt"
"log"
"os"
"path/filepath"
"sync"
)
...
...
@@ -218,7 +217,7 @@ func (me *pathInode) RLockTree() func() {
return
func
()
{
me
.
pathFs
.
pathLock
.
RUnlock
()
}
}
func
(
me
*
pathInode
)
fillNewChildAttr
(
path
string
,
child
*
pathInode
,
c
*
Context
)
(
fi
*
os
.
FileInfo
,
code
Status
)
{
func
(
me
*
pathInode
)
fillNewChildAttr
(
path
string
,
child
*
pathInode
,
c
*
Context
)
(
fi
*
Attr
,
code
Status
)
{
fi
,
_
=
me
.
fs
.
GetAttr
(
path
,
c
)
if
fi
!=
nil
&&
fi
.
Ino
>
0
{
child
.
clientInode
=
fi
.
Ino
...
...
@@ -378,7 +377,7 @@ func (me *pathInode) OpenDir(context *Context) (chan DirEntry, Status) {
return
me
.
fs
.
OpenDir
(
me
.
GetPath
(),
context
)
}
func
(
me
*
pathInode
)
Mknod
(
name
string
,
mode
uint32
,
dev
uint32
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
{
func
(
me
*
pathInode
)
Mknod
(
name
string
,
mode
uint32
,
dev
uint32
,
context
*
Context
)
(
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
{
fullPath
:=
filepath
.
Join
(
me
.
GetPath
(),
name
)
code
=
me
.
fs
.
Mknod
(
fullPath
,
mode
,
dev
,
context
)
if
code
.
Ok
()
{
...
...
@@ -390,7 +389,7 @@ func (me *pathInode) Mknod(name string, mode uint32, dev uint32, context *Contex
return
}
func
(
me
*
pathInode
)
Mkdir
(
name
string
,
mode
uint32
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
{
func
(
me
*
pathInode
)
Mkdir
(
name
string
,
mode
uint32
,
context
*
Context
)
(
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
{
fullPath
:=
filepath
.
Join
(
me
.
GetPath
(),
name
)
code
=
me
.
fs
.
Mkdir
(
fullPath
,
mode
,
context
)
if
code
.
Ok
()
{
...
...
@@ -418,7 +417,7 @@ func (me *pathInode) Rmdir(name string, context *Context) (code Status) {
return
code
}
func
(
me
*
pathInode
)
Symlink
(
name
string
,
content
string
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
{
func
(
me
*
pathInode
)
Symlink
(
name
string
,
content
string
,
context
*
Context
)
(
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
{
fullPath
:=
filepath
.
Join
(
me
.
GetPath
(),
name
)
code
=
me
.
fs
.
Symlink
(
content
,
fullPath
,
context
)
if
code
.
Ok
()
{
...
...
@@ -443,7 +442,7 @@ func (me *pathInode) Rename(oldName string, newParent FsNode, newName string, co
return
code
}
func
(
me
*
pathInode
)
Link
(
name
string
,
existingFsnode
FsNode
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
{
func
(
me
*
pathInode
)
Link
(
name
string
,
existingFsnode
FsNode
,
context
*
Context
)
(
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
{
if
!
me
.
pathFs
.
options
.
ClientInodes
{
return
nil
,
nil
,
ENOSYS
}
...
...
@@ -470,7 +469,7 @@ func (me *pathInode) Link(name string, existingFsnode FsNode, context *Context)
return
}
func
(
me
*
pathInode
)
Create
(
name
string
,
flags
uint32
,
mode
uint32
,
context
*
Context
)
(
file
File
,
fi
*
os
.
FileInfo
,
newNode
FsNode
,
code
Status
)
{
func
(
me
*
pathInode
)
Create
(
name
string
,
flags
uint32
,
mode
uint32
,
context
*
Context
)
(
file
File
,
fi
*
Attr
,
newNode
FsNode
,
code
Status
)
{
fullPath
:=
filepath
.
Join
(
me
.
GetPath
(),
name
)
file
,
code
=
me
.
fs
.
Create
(
fullPath
,
flags
,
mode
,
context
)
if
code
.
Ok
()
{
...
...
@@ -502,7 +501,7 @@ func (me *pathInode) Open(flags uint32, context *Context) (file File, code Statu
return
}
func
(
me
*
pathInode
)
Lookup
(
name
string
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
node
FsNode
,
code
Status
)
{
func
(
me
*
pathInode
)
Lookup
(
name
string
,
context
*
Context
)
(
fi
*
Attr
,
node
FsNode
,
code
Status
)
{
fullPath
:=
filepath
.
Join
(
me
.
GetPath
(),
name
)
fi
,
code
=
me
.
fs
.
GetAttr
(
fullPath
,
context
)
if
code
.
Ok
()
{
...
...
@@ -512,7 +511,7 @@ func (me *pathInode) Lookup(name string, context *Context) (fi *os.FileInfo, nod
return
}
func
(
me
*
pathInode
)
findChild
(
fi
*
os
.
FileInfo
,
name
string
,
fullPath
string
)
(
out
*
pathInode
)
{
func
(
me
*
pathInode
)
findChild
(
fi
*
Attr
,
name
string
,
fullPath
string
)
(
out
*
pathInode
)
{
if
fi
.
Ino
>
0
{
unlock
:=
me
.
RLockTree
()
v
:=
me
.
pathFs
.
clientInodeMap
[
fi
.
Ino
]
...
...
@@ -535,7 +534,7 @@ func (me *pathInode) findChild(fi *os.FileInfo, name string, fullPath string) (o
return
out
}
func
(
me
*
pathInode
)
GetAttr
(
file
File
,
context
*
Context
)
(
fi
*
os
.
FileInfo
,
code
Status
)
{
func
(
me
*
pathInode
)
GetAttr
(
file
File
,
context
*
Context
)
(
fi
*
Attr
,
code
Status
)
{
if
file
==
nil
{
// called on a deleted files.
file
=
me
.
inode
.
AnyFile
()
...
...
@@ -606,7 +605,7 @@ func (me *pathInode) Truncate(file File, size uint64, context *Context) (code St
return
code
}
func
(
me
*
pathInode
)
Utimens
(
file
File
,
atime
uint64
,
mtime
u
int64
,
context
*
Context
)
(
code
Status
)
{
func
(
me
*
pathInode
)
Utimens
(
file
File
,
atime
int64
,
mtime
int64
,
context
*
Context
)
(
code
Status
)
{
files
:=
me
.
inode
.
Files
(
O_ANYWRITE
)
for
_
,
f
:=
range
files
{
// TODO - pass context
...
...
fuse/prefixfs.go
View file @
77177c5d
...
...
@@ -2,7 +2,6 @@ package fuse
import
(
"fmt"
"os"
"path/filepath"
)
...
...
@@ -16,7 +15,7 @@ func (me *PrefixFileSystem) prefixed(n string) string {
return
filepath
.
Join
(
me
.
Prefix
,
n
)
}
func
(
me
*
PrefixFileSystem
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
os
.
FileInfo
,
Status
)
{
func
(
me
*
PrefixFileSystem
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
Attr
,
Status
)
{
return
me
.
FileSystem
.
GetAttr
(
me
.
prefixed
(
name
),
context
)
}
...
...
@@ -88,7 +87,7 @@ func (me *PrefixFileSystem) Create(name string, flags uint32, mode uint32, conte
return
me
.
FileSystem
.
Create
(
me
.
prefixed
(
name
),
flags
,
mode
,
context
)
}
func
(
me
*
PrefixFileSystem
)
Utimens
(
name
string
,
AtimeNs
uint64
,
CtimeNs
u
int64
,
context
*
Context
)
(
code
Status
)
{
func
(
me
*
PrefixFileSystem
)
Utimens
(
name
string
,
AtimeNs
int64
,
CtimeNs
int64
,
context
*
Context
)
(
code
Status
)
{
return
me
.
FileSystem
.
Utimens
(
me
.
prefixed
(
name
),
AtimeNs
,
CtimeNs
,
context
)
}
...
...
fuse/readonlyfs.go
View file @
77177c5d
...
...
@@ -2,7 +2,6 @@ package fuse
import
(
"fmt"
"os"
)
// This is a wrapper that only exposes read-only operations.
...
...
@@ -10,7 +9,7 @@ type ReadonlyFileSystem struct {
FileSystem
}
func
(
me
*
ReadonlyFileSystem
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
os
.
FileInfo
,
Status
)
{
func
(
me
*
ReadonlyFileSystem
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
Attr
,
Status
)
{
return
me
.
FileSystem
.
GetAttr
(
name
,
context
)
}
...
...
@@ -90,7 +89,7 @@ func (me *ReadonlyFileSystem) Create(name string, flags uint32, mode uint32, con
return
nil
,
EPERM
}
func
(
me
*
ReadonlyFileSystem
)
Utimens
(
name
string
,
AtimeNs
uint64
,
CtimeNs
u
int64
,
context
*
Context
)
(
code
Status
)
{
func
(
me
*
ReadonlyFileSystem
)
Utimens
(
name
string
,
AtimeNs
int64
,
CtimeNs
int64
,
context
*
Context
)
(
code
Status
)
{
return
EPERM
}
...
...
fuse/xattr_test.go
View file @
77177c5d
...
...
@@ -26,8 +26,8 @@ func NewXAttrFs(nm string, m map[string][]byte) *XAttrTestFs {
return
x
}
func
(
me
*
XAttrTestFs
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
os
.
FileInfo
,
Status
)
{
a
:=
&
os
.
FileInfo
{}
func
(
me
*
XAttrTestFs
)
GetAttr
(
name
string
,
context
*
Context
)
(
*
Attr
,
Status
)
{
a
:=
&
Attr
{}
if
name
==
""
||
name
==
"/"
{
a
.
Mode
=
S_IFDIR
|
0700
return
a
,
OK
...
...
unionfs/autounion.go
View file @
77177c5d
...
...
@@ -257,31 +257,31 @@ func (me *AutoUnionFs) GetXAttr(name string, attr string, context *fuse.Context)
return
nil
,
fuse
.
ENODATA
}
func
(
me
*
AutoUnionFs
)
GetAttr
(
path
string
,
context
*
fuse
.
Context
)
(
*
os
.
FileInfo
,
fuse
.
Status
)
{
func
(
me
*
AutoUnionFs
)
GetAttr
(
path
string
,
context
*
fuse
.
Context
)
(
*
fuse
.
Attr
,
fuse
.
Status
)
{
if
path
==
""
||
path
==
_CONFIG
||
path
==
_STATUS
{
a
:=
&
os
.
FileInfo
{
a
:=
&
fuse
.
Attr
{
Mode
:
fuse
.
S_IFDIR
|
0755
,
}
return
a
,
fuse
.
OK
}
if
path
==
filepath
.
Join
(
_STATUS
,
_VERSION
)
{
a
:=
&
os
.
FileInfo
{
a
:=
&
fuse
.
Attr
{
Mode
:
fuse
.
S_IFREG
|
0644
,
Size
:
int64
(
len
(
fuse
.
Version
())),
Size
:
u
int64
(
len
(
fuse
.
Version
())),
}
return
a
,
fuse
.
OK
}
if
path
==
filepath
.
Join
(
_STATUS
,
_ROOT
)
{
a
:=
&
os
.
FileInfo
{
a
:=
&
fuse
.
Attr
{
Mode
:
syscall
.
S_IFLNK
|
0644
,
}
return
a
,
fuse
.
OK
}
if
path
==
filepath
.
Join
(
_CONFIG
,
_SCAN_CONFIG
)
{
a
:=
&
os
.
FileInfo
{
a
:=
&
fuse
.
Attr
{
Mode
:
fuse
.
S_IFREG
|
0644
,
}
return
a
,
fuse
.
OK
...
...
@@ -295,7 +295,7 @@ func (me *AutoUnionFs) GetAttr(path string, context *fuse.Context) (*os.FileInfo
return
nil
,
fuse
.
ENOENT
}
a
:=
&
os
.
FileInfo
{
a
:=
&
fuse
.
Attr
{
Mode
:
syscall
.
S_IFLNK
|
0644
,
}
return
a
,
fuse
.
OK
...
...
unionfs/cachingfs.go
View file @
77177c5d
...
...
@@ -4,7 +4,6 @@ import (
"fmt"
"github.com/hanwen/go-fuse/fuse"
"log"
"os"
"strings"
)
...
...
@@ -13,7 +12,7 @@ var _ = fmt.Println
const
_XATTRSEP
=
"@XATTR@"
type
attrResponse
struct
{
*
os
.
FileInfo
*
fuse
.
Attr
fuse
.
Status
}
...
...
@@ -63,7 +62,7 @@ func readDir(fs fuse.FileSystem, name string) *dirResponse {
func
getAttr
(
fs
fuse
.
FileSystem
,
name
string
)
*
attrResponse
{
a
,
code
:=
fs
.
GetAttr
(
name
,
nil
)
return
&
attrResponse
{
FileInfo
:
a
,
Attr
:
a
,
Status
:
code
,
}
}
...
...
@@ -113,15 +112,15 @@ func (me *CachingFileSystem) DropCache() {
}
}
func
(
me
*
CachingFileSystem
)
GetAttr
(
name
string
,
context
*
fuse
.
Context
)
(
*
os
.
FileInfo
,
fuse
.
Status
)
{
func
(
me
*
CachingFileSystem
)
GetAttr
(
name
string
,
context
*
fuse
.
Context
)
(
*
fuse
.
Attr
,
fuse
.
Status
)
{
if
name
==
_DROP_CACHE
{
return
&
os
.
FileInfo
{
return
&
fuse
.
Attr
{
Mode
:
fuse
.
S_IFREG
|
0777
,
},
fuse
.
OK
}
r
:=
me
.
attributes
.
Get
(
name
)
.
(
*
attrResponse
)
return
r
.
FileInfo
,
r
.
Status
return
r
.
Attr
,
r
.
Status
}
func
(
me
*
CachingFileSystem
)
GetXAttr
(
name
string
,
attr
string
,
context
*
fuse
.
Context
)
([]
byte
,
fuse
.
Status
)
{
...
...
unionfs/unionfs.go
View file @
77177c5d
...
...
@@ -152,21 +152,13 @@ func (me *UnionFs) getBranch(name string) branchResult {
}
type
branchResult
struct
{
attr
*
os
.
FileInfo
attr
*
fuse
.
Attr
code
fuse
.
Status
branch
int
}
func
printFileInfo
(
me
*
os
.
FileInfo
)
string
{
return
fmt
.
Sprintf
(
"{0%o S=%d L=%d %d:%d %d*%d %d:%d "
+
"A %.09f M %.09f C %.09f}"
,
me
.
Mode
,
me
.
Size
,
me
.
Nlink
,
me
.
Uid
,
me
.
Gid
,
me
.
Blocks
,
me
.
Blksize
,
me
.
Rdev
,
me
.
Ino
,
float64
(
me
.
Atime_ns
)
*
1e-9
,
float64
(
me
.
Mtime_ns
)
*
1e-9
,
float64
(
me
.
Ctime_ns
)
*
1e-9
)
}
func
(
me
branchResult
)
String
()
string
{
return
fmt
.
Sprintf
(
"{%
s %v branch %d}"
,
printFileInfo
(
me
.
attr
)
,
me
.
code
,
me
.
branch
)
return
fmt
.
Sprintf
(
"{%
v %v branch %d}"
,
me
.
attr
,
me
.
code
,
me
.
branch
)
}
func
(
me
*
UnionFs
)
getBranchAttrNoCache
(
name
string
)
branchResult
{
...
...
@@ -237,7 +229,7 @@ func (me *UnionFs) putDeletion(name string) (code fuse.Status) {
// Is there a WriteStringToFileOrDie ?
writable
:=
me
.
fileSystems
[
0
]
fi
,
code
:=
writable
.
GetAttr
(
marker
,
nil
)
if
code
.
Ok
()
&&
fi
.
Size
==
int64
(
len
(
name
))
{
if
code
.
Ok
()
&&
fi
.
Size
==
u
int64
(
len
(
name
))
{
return
fuse
.
OK
}
...
...
@@ -279,8 +271,8 @@ func (me *UnionFs) Promote(name string, srcResult branchResult, context *fuse.Co
code
=
writable
.
Chmod
(
name
,
srcResult
.
attr
.
Mode
&
07777
|
0200
,
context
)
}
if
code
.
Ok
()
{
code
=
writable
.
Utimens
(
name
,
uint64
(
srcResult
.
attr
.
Atime_ns
),
uint64
(
srcResult
.
attr
.
Mtime_ns
),
context
)
code
=
writable
.
Utimens
(
name
,
srcResult
.
attr
.
Atimens
(
),
srcResult
.
attr
.
Mtimens
(
),
context
)
}
files
:=
me
.
nodeFs
.
AllFiles
(
name
,
0
)
...
...
@@ -422,7 +414,7 @@ func (me *UnionFs) Mkdir(path string, mode uint32, context *fuse.Context) (code
}
if
code
.
Ok
()
{
me
.
removeDeletion
(
path
)
attr
:=
&
os
.
FileInfo
{
attr
:=
&
fuse
.
Attr
{
Mode
:
fuse
.
S_IFDIR
|
mode
,
}
me
.
branchCache
.
Set
(
path
,
branchResult
{
attr
,
fuse
.
OK
,
0
})
...
...
@@ -467,16 +459,15 @@ func (me *UnionFs) Truncate(path string, size uint64, context *fuse.Context) (co
code
=
me
.
fileSystems
[
0
]
.
Truncate
(
path
,
size
,
context
)
}
if
code
.
Ok
()
{
r
.
attr
.
Size
=
int64
(
size
)
r
.
attr
.
Size
=
size
now
:=
time
.
Nanoseconds
()
r
.
attr
.
Mtime_ns
=
now
r
.
attr
.
Ctime_ns
=
now
r
.
attr
.
SetTimes
(
-
1
,
now
,
now
)
me
.
branchCache
.
Set
(
path
,
r
)
}
return
code
}
func
(
me
*
UnionFs
)
Utimens
(
name
string
,
atime
uint64
,
mtime
u
int64
,
context
*
fuse
.
Context
)
(
code
fuse
.
Status
)
{
func
(
me
*
UnionFs
)
Utimens
(
name
string
,
atime
int64
,
mtime
int64
,
context
*
fuse
.
Context
)
(
code
fuse
.
Status
)
{
name
=
stripSlash
(
name
)
r
:=
me
.
getBranch
(
name
)
...
...
@@ -489,9 +480,7 @@ func (me *UnionFs) Utimens(name string, atime uint64, mtime uint64, context *fus
code
=
me
.
fileSystems
[
0
]
.
Utimens
(
name
,
atime
,
mtime
,
context
)
}
if
code
.
Ok
()
{
r
.
attr
.
Atime_ns
=
int64
(
atime
)
r
.
attr
.
Mtime_ns
=
int64
(
mtime
)
r
.
attr
.
Ctime_ns
=
time
.
Nanoseconds
()
r
.
attr
.
SetTimes
(
atime
,
mtime
,
time
.
Nanoseconds
())
me
.
branchCache
.
Set
(
name
,
r
)
}
return
code
...
...
@@ -508,7 +497,7 @@ func (me *UnionFs) Chown(name string, uid uint32, gid uint32, context *fuse.Cont
return
fuse
.
EPERM
}
if
r
.
attr
.
Uid
!=
int
(
uid
)
||
r
.
attr
.
Gid
!=
int
(
gid
)
{
if
r
.
attr
.
Uid
!=
uid
||
r
.
attr
.
Gid
!=
gid
{
if
r
.
branch
>
0
{
code
:=
me
.
Promote
(
name
,
r
,
context
)
if
code
!=
fuse
.
OK
{
...
...
@@ -518,9 +507,9 @@ func (me *UnionFs) Chown(name string, uid uint32, gid uint32, context *fuse.Cont
}
me
.
fileSystems
[
0
]
.
Chown
(
name
,
uid
,
gid
,
context
)
}
r
.
attr
.
Uid
=
int
(
uid
)
r
.
attr
.
Gid
=
int
(
gid
)
r
.
attr
.
Ctime_ns
=
time
.
Nanoseconds
(
)
r
.
attr
.
Uid
=
uid
r
.
attr
.
Gid
=
gid
r
.
attr
.
SetTimes
(
-
1
,
-
1
,
time
.
Nanoseconds
()
)
me
.
branchCache
.
Set
(
name
,
r
)
return
fuse
.
OK
}
...
...
@@ -551,7 +540,7 @@ func (me *UnionFs) Chmod(name string, mode uint32, context *fuse.Context) (code
me
.
fileSystems
[
0
]
.
Chmod
(
name
,
mode
,
context
)
}
r
.
attr
.
Mode
=
(
r
.
attr
.
Mode
&^
permMask
)
|
mode
r
.
attr
.
Ctime_ns
=
time
.
Nanoseconds
(
)
r
.
attr
.
SetTimes
(
-
1
,
-
1
,
time
.
Nanoseconds
()
)
me
.
branchCache
.
Set
(
name
,
r
)
return
fuse
.
OK
}
...
...
@@ -638,7 +627,7 @@ func (me *UnionFs) promoteDirsTo(filename string) fuse.Status {
return
fuse
.
EPERM
}
me
.
fileSystems
[
0
]
.
Utimens
(
d
,
uint64
(
r
.
attr
.
Atime_ns
),
uint64
(
r
.
attr
.
Mtime_ns
),
nil
)
me
.
fileSystems
[
0
]
.
Utimens
(
d
,
r
.
attr
.
Atimens
(),
r
.
attr
.
Mtimens
(
),
nil
)
r
.
branch
=
0
me
.
branchCache
.
Set
(
d
,
r
)
}
...
...
@@ -658,22 +647,21 @@ func (me *UnionFs) Create(name string, flags uint32, mode uint32, context *fuse.
me
.
removeDeletion
(
name
)
now
:=
time
.
Nanoseconds
()
a
:=
os
.
FileInfo
{
a
:=
fuse
.
Attr
{
Mode
:
fuse
.
S_IFREG
|
mode
,
Ctime_ns
:
now
,
Mtime_ns
:
now
,
}
a
.
SetTimes
(
-
1
,
now
,
now
)
me
.
branchCache
.
Set
(
name
,
branchResult
{
&
a
,
fuse
.
OK
,
0
})
}
return
fuseFile
,
code
}
func
(
me
*
UnionFs
)
GetAttr
(
name
string
,
context
*
fuse
.
Context
)
(
a
*
os
.
FileInfo
,
s
fuse
.
Status
)
{
func
(
me
*
UnionFs
)
GetAttr
(
name
string
,
context
*
fuse
.
Context
)
(
a
*
fuse
.
Attr
,
s
fuse
.
Status
)
{
if
name
==
_READONLY
{
return
nil
,
fuse
.
ENOENT
}
if
name
==
_DROP_CACHE
{
return
&
os
.
FileInfo
{
return
&
fuse
.
Attr
{
Mode
:
fuse
.
S_IFREG
|
0777
,
},
fuse
.
OK
}
...
...
@@ -949,7 +937,7 @@ func (me *UnionFs) Open(name string, flags uint32, context *fuse.Context) (fuseF
return
nil
,
code
}
r
.
branch
=
0
r
.
attr
.
Mtime_ns
=
time
.
Nanoseconds
(
)
r
.
attr
.
SetTimes
(
-
1
,
time
.
Nanoseconds
(),
-
1
)
me
.
branchCache
.
Set
(
name
,
r
)
}
fuseFile
,
status
=
me
.
fileSystems
[
r
.
branch
]
.
Open
(
name
,
uint32
(
flags
),
context
)
...
...
@@ -1007,7 +995,7 @@ func (me *unionFsFile) SetInode(node *fuse.Inode) {
me
.
node
=
node
}
func
(
me
*
unionFsFile
)
GetAttr
()
(
*
os
.
FileInfo
,
fuse
.
Status
)
{
func
(
me
*
unionFsFile
)
GetAttr
()
(
*
fuse
.
Attr
,
fuse
.
Status
)
{
fi
,
code
:=
me
.
File
.
GetAttr
()
if
fi
!=
nil
{
f
:=
*
fi
...
...
zipfs/memtree.go
View file @
77177c5d
...
...
@@ -3,12 +3,11 @@ package zipfs
import
(
"fmt"
"github.com/hanwen/go-fuse/fuse"
"os"
"strings"
)
type
MemFile
interface
{
Stat
()
*
os
.
FileInfo
Stat
()
*
fuse
.
Attr
Data
()
[]
byte
}
...
...
@@ -63,7 +62,7 @@ func (me *memNode) Print(indent int) {
}
// We construct the tree at mount, so we never need to look anything up.
func
(
me
*
memNode
)
Lookup
(
name
string
,
c
*
fuse
.
Context
)
(
fi
*
os
.
FileInfo
,
node
fuse
.
FsNode
,
code
fuse
.
Status
)
{
func
(
me
*
memNode
)
Lookup
(
name
string
,
c
*
fuse
.
Context
)
(
fi
*
fuse
.
Attr
,
node
fuse
.
FsNode
,
code
fuse
.
Status
)
{
return
nil
,
nil
,
fuse
.
ENOENT
}
...
...
@@ -96,9 +95,9 @@ func (me *memNode) Deletable() bool {
return
false
}
func
(
me
*
memNode
)
GetAttr
(
file
fuse
.
File
,
context
*
fuse
.
Context
)
(
*
os
.
FileInfo
,
fuse
.
Status
)
{
func
(
me
*
memNode
)
GetAttr
(
file
fuse
.
File
,
context
*
fuse
.
Context
)
(
*
fuse
.
Attr
,
fuse
.
Status
)
{
if
me
.
Inode
()
.
IsDir
()
{
return
&
os
.
FileInfo
{
return
&
fuse
.
Attr
{
Mode
:
fuse
.
S_IFDIR
|
0777
,
},
fuse
.
OK
}
...
...
zipfs/multizip.go
View file @
77177c5d
...
...
@@ -13,7 +13,6 @@ symlinking path/to/zipfile to /config/zipmount
import
(
"github.com/hanwen/go-fuse/fuse"
"log"
"os"
"path/filepath"
"sync"
)
...
...
@@ -76,8 +75,8 @@ func (me *MultiZipFs) OpenDir(name string, context *fuse.Context) (stream chan f
return
stream
,
fuse
.
OK
}
func
(
me
*
MultiZipFs
)
GetAttr
(
name
string
,
context
*
fuse
.
Context
)
(
*
os
.
FileInfo
,
fuse
.
Status
)
{
a
:=
&
os
.
FileInfo
{}
func
(
me
*
MultiZipFs
)
GetAttr
(
name
string
,
context
*
fuse
.
Context
)
(
*
fuse
.
Attr
,
fuse
.
Status
)
{
a
:=
&
fuse
.
Attr
{}
if
name
==
""
{
// Should not write in top dir.
a
.
Mode
=
fuse
.
S_IFDIR
|
0500
...
...
zipfs/multizip_test.go
View file @
77177c5d
...
...
@@ -16,7 +16,7 @@ const testTtl = 0.1
func
setupMzfs
()
(
mountPoint
string
,
cleanup
func
())
{
fs
:=
NewMultiZipFs
()
mountPoint
,
_
=
ioutil
.
TempDir
(
""
,
""
)
nfs
:=
fuse
.
NewPathNodeFs
(
fs
)
nfs
:=
fuse
.
NewPathNodeFs
(
fs
,
nil
)
state
,
_
,
err
:=
fuse
.
MountNodeFileSystem
(
mountPoint
,
nfs
,
&
fuse
.
FileSystemOptions
{
EntryTimeout
:
testTtl
,
AttrTimeout
:
testTtl
,
...
...
zipfs/tarfs.go
View file @
77177c5d
...
...
@@ -6,6 +6,7 @@ import (
"compress/bzip2"
"compress/gzip"
"fmt"
"github.com/hanwen/go-fuse/fuse"
"io"
"os"
"strings"
...
...
@@ -16,17 +17,15 @@ var _ = fmt.Println
// TODO - handle symlinks.
func
HeaderToFileInfo
(
h
*
tar
.
Header
)
*
os
.
FileInfo
{
return
&
os
.
FileInfo
{
Name
:
h
.
Name
,
func
HeaderToFileInfo
(
h
*
tar
.
Header
)
(
*
fuse
.
Attr
,
string
)
{
a
:=
&
fuse
.
Attr
{
Mode
:
uint32
(
h
.
Mode
),
Uid
:
h
.
Uid
,
Gid
:
h
.
Gid
,
Size
:
h
.
Size
,
Mtime_ns
:
h
.
Mtime
,
Atime_ns
:
h
.
Atime
,
Ctime_ns
:
h
.
Ctime
,
Size
:
uint64
(
h
.
Size
),
}
a
.
Uid
=
uint32
(
h
.
Uid
)
a
.
Gid
=
uint32
(
h
.
Gid
)
a
.
SetTimes
(
h
.
Atime
,
h
.
Mtime
,
h
.
Ctime
)
return
a
,
h
.
Name
}
type
TarFile
struct
{
...
...
@@ -34,8 +33,8 @@ type TarFile struct {
tar
.
Header
}
func
(
me
*
TarFile
)
Stat
()
*
os
.
FileInfo
{
fi
:=
HeaderToFileInfo
(
&
me
.
Header
)
func
(
me
*
TarFile
)
Stat
()
*
fuse
.
Attr
{
fi
,
_
:=
HeaderToFileInfo
(
&
me
.
Header
)
fi
.
Mode
|=
syscall
.
S_IFREG
return
fi
}
...
...
zipfs/zipfs.go
View file @
77177c5d
...
...
@@ -19,11 +19,11 @@ type ZipFile struct {
*
zip
.
File
}
func
(
me
*
ZipFile
)
Stat
()
*
os
.
FileInfo
{
func
(
me
*
ZipFile
)
Stat
()
*
fuse
.
Attr
{
// TODO - do something intelligent with timestamps.
return
&
os
.
FileInfo
{
return
&
fuse
.
Attr
{
Mode
:
fuse
.
S_IFREG
|
0444
,
Size
:
int64
(
me
.
File
.
UncompressedSize
),
Size
:
u
int64
(
me
.
File
.
UncompressedSize
),
}
}
...
...
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