Commit 64e13af4 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Use inode passed to Statfs throughout.

Changes to API:

- Statfs takes a *InHeader argument in the raw API
- Statfs moves to the FsNode API.
- Statfs takes a path argument in the FileSystem API.
parent 2e08b9e3
......@@ -19,7 +19,6 @@ import (
type NodeFileSystem interface {
OnUnmount()
OnMount(conn *FileSystemConnector)
StatFs() *StatfsOut
Root() FsNode
// Used for debug outputs
......@@ -70,6 +69,8 @@ type FsNode interface {
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 uint64, context *Context) (code Status)
StatFs() *StatfsOut
}
// A filesystem API that uses paths rather than inodes. A minimal
......@@ -130,7 +131,7 @@ type FileSystem interface {
Symlink(value string, linkName string, context *Context) (code Status)
Readlink(name string, context *Context) (string, Status)
StatFs() *StatfsOut
StatFs(name string) *StatfsOut
}
// A File object should be returned from FileSystem.Open and
......@@ -268,7 +269,7 @@ type RawFileSystem interface {
//
Ioctl(header *InHeader, input *IoctlIn) (output *IoctlOut, data []byte, code Status)
StatFs() *StatfsOut
StatFs(header *InHeader) *StatfsOut
// Provide callbacks for pushing notifications to the kernel.
Init(params *RawFsInit)
......
......@@ -99,6 +99,6 @@ func (me *DefaultFileSystem) String() string {
return "DefaultFileSystem"
}
func (me *DefaultFileSystem) StatFs() *StatfsOut {
func (me *DefaultFileSystem) StatFs(name string) *StatfsOut {
return nil
}
......@@ -18,10 +18,6 @@ func (me *DefaultNodeFileSystem) OnMount(conn *FileSystemConnector) {
}
func (me *DefaultNodeFileSystem) StatFs() *StatfsOut {
return nil
}
func (me *DefaultNodeFileSystem) Root() FsNode {
return new(DefaultFsNode)
}
......@@ -37,6 +33,10 @@ type DefaultFsNode struct {
inode *Inode
}
func (me *DefaultFsNode) StatFs() *StatfsOut {
return nil
}
func (me *DefaultFsNode) SetInode(node *Inode) {
if me.inode != nil {
panic("already have Inode")
......
......@@ -3,7 +3,7 @@ package fuse
func (me *DefaultRawFileSystem) Init(init *RawFsInit) {
}
func (me *DefaultRawFileSystem) StatFs() *StatfsOut {
func (me *DefaultRawFileSystem) StatFs(h *InHeader) *StatfsOut {
return nil
}
......
......@@ -327,8 +327,9 @@ func (me *FileSystemConnector) Read(header *InHeader, input *ReadIn, bp BufferPo
return opened.WithFlags.File.Read(input, bp)
}
func (me *FileSystemConnector) StatFs() *StatfsOut {
return me.rootNode.mountPoint.fs.StatFs()
func (me *FileSystemConnector) StatFs(header *InHeader) *StatfsOut {
node := me.toInode(header.NodeId)
return node.FsNode().StatFs()
}
func (me *FileSystemConnector) Flush(header *InHeader, input *FlushIn) Status {
......
......@@ -170,9 +170,9 @@ func (me *LoopbackFileSystem) String() string {
return fmt.Sprintf("LoopbackFileSystem(%s)", me.Root)
}
func (me *LoopbackFileSystem) StatFs() *StatfsOut {
func (me *LoopbackFileSystem) StatFs(name string) *StatfsOut {
s := syscall.Statfs_t{}
errNo := syscall.Statfs(me.Root, &s)
errNo := syscall.Statfs(me.GetPath(name), &s)
if errNo == 0 {
return &StatfsOut{
......
......@@ -673,6 +673,13 @@ func TestIoctl(t *testing.T) {
ioctl(f.Fd(), 0x5401, 42)
}
func clearStatfs(s *syscall.Statfs_t) {
empty := syscall.Statfs_t{}
s.Type = 0
s.Fsid = empty.Fsid
s.Spare = empty.Spare
}
// This test is racy. If an external process consumes space while this
// runs, we may see spurious differences between the two statfs() calls.
func TestStatFs(t *testing.T) {
......@@ -689,19 +696,44 @@ func TestStatFs(t *testing.T) {
s2 := syscall.Statfs_t{}
err = syscall.Statfs(ts.mnt, &s2)
s1.Type = 0
s2.Type = 0
if err != 0 {
t.Fatal("statfs mnt", err)
}
s1.Fsid = empty.Fsid
s2.Fsid = empty.Fsid
clearStatfs(&s1)
clearStatfs(&s2)
if fmt.Sprintf("%v", s2) != fmt.Sprintf("%v", s1) {
t.Error("Mismatch", s1, s2)
}
}
s1.Spare = empty.Spare
s2.Spare = empty.Spare
func TestFStatFs(t *testing.T) {
ts := NewTestCase(t)
defer ts.Cleanup()
if err != 0 {
t.Fatal("statfs mnt", err)
fOrig, err := os.OpenFile(ts.orig+"/file", os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0644)
CheckSuccess(err)
defer fOrig.Close()
empty := syscall.Statfs_t{}
s1 := empty
errno := syscall.Fstatfs(fOrig.Fd(), &s1)
if errno != 0 {
t.Fatal("statfs orig", err)
}
fMnt, err := os.OpenFile(ts.mnt+"/file", os.O_RDWR, 0644)
CheckSuccess(err)
defer fMnt.Close()
s2 := empty
errno = syscall.Fstatfs(fMnt.Fd(), &s2)
if errno != 0 {
t.Fatal("statfs mnt", err)
}
clearStatfs(&s1)
clearStatfs(&s2)
if fmt.Sprintf("%v", s2) != fmt.Sprintf("%v", s1) {
t.Error("Mismatch", s1, s2)
}
......
......@@ -280,7 +280,7 @@ func doRename(state *MountState, req *request) {
}
func doStatFs(state *MountState, req *request) {
stat := state.fileSystem.StatFs()
stat := state.fileSystem.StatFs(req.inHeader)
if stat != nil {
req.outData = unsafe.Pointer(stat)
req.status = OK
......
......@@ -104,10 +104,6 @@ func (me *PathNodeFs) OnMount(conn *FileSystemConnector) {
me.fs.OnMount(me)
}
func (me *PathNodeFs) StatFs() *StatfsOut {
return me.fs.StatFs()
}
func (me *PathNodeFs) Node(name string) *Inode {
n, rest := me.LastNode(name)
if len(rest) > 0 {
......@@ -362,6 +358,9 @@ func (me *pathInode) OnForget() {
////////////////////////////////////////////////////////////////
// FS operations
func (me *pathInode) StatFs() *StatfsOut {
return me.fs.StatFs(me.GetPath())
}
func (me *pathInode) Readlink(c *Context) ([]byte, Status) {
path := me.GetPath()
......
......@@ -199,3 +199,10 @@ func (me *FlushIn) String() string {
func (me *AccessIn) String() string {
return fmt.Sprintf("{%s}", flagString(accessFlagName, int(me.Mask), ""))
}
func (me *Kstatfs) String() string {
return fmt.Sprintf(
"{b%d f%d fs%d ff%d bs%d nl%d frs%d}",
me.Blocks, me.Bfree, me.Bavail, me.Files, me.Ffree,
me.Bsize, me.NameLen, me.Frsize)
}
......@@ -383,6 +383,6 @@ func (me *AutoUnionFs) OpenDir(name string, context *fuse.Context) (stream chan
return stream, status
}
func (me *AutoUnionFs) StatFs() *fuse.StatfsOut {
func (me *AutoUnionFs) StatFs(name string) *fuse.StatfsOut {
return &fuse.StatfsOut{}
}
......@@ -192,11 +192,6 @@ func (me *MemUnionFs) Root() fuse.FsNode {
return me.root
}
func (me *MemUnionFs) StatFs() *fuse.StatfsOut {
backingFs := &fuse.LoopbackFileSystem{Root: me.backingStore}
return backingFs.StatFs()
}
func (me *MemUnionFs) newNode(isdir bool) *memNode {
n := &memNode{
fs: me,
......@@ -225,6 +220,11 @@ func (me *memNode) Deletable() bool {
return !me.changed && me.original == ""
}
func (me *memNode) StatFs() *fuse.StatfsOut {
backingFs := &fuse.LoopbackFileSystem{Root: me.fs.backingStore}
return backingFs.StatFs("")
}
func (me *memNode) touch() {
me.changed = true
me.info.Mtime_ns = time.Nanoseconds()
......
......@@ -970,8 +970,8 @@ func (me *UnionFs) String() string {
return fmt.Sprintf("UnionFs(%v)", names)
}
func (me *UnionFs) StatFs() *fuse.StatfsOut {
return me.fileSystems[0].StatFs()
func (me *UnionFs) StatFs(name string) *fuse.StatfsOut {
return me.fileSystems[0].StatFs("")
}
type unionFsFile struct {
......
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