Commit 77177c5d authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Change go-fuse to use fuse.Attr rather than os.FileInfo in preparation

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