Commit 2e0db5ff authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Set options per filesystem mount.

parent 124708c4
...@@ -33,7 +33,7 @@ func main() { ...@@ -33,7 +33,7 @@ func main() {
} }
gofs := unionfs.NewAutoUnionFs(flag.Arg(1), options) gofs := unionfs.NewAutoUnionFs(flag.Arg(1), options)
conn := fuse.NewFileSystemConnector(gofs) conn := fuse.NewFileSystemConnector(gofs, nil)
mountState := fuse.NewMountState(conn) mountState := fuse.NewMountState(conn)
mountState.Debug = *debug mountState.Debug = *debug
fmt.Printf("Mounting...\n") fmt.Printf("Mounting...\n")
......
...@@ -48,23 +48,26 @@ func main() { ...@@ -48,23 +48,26 @@ func main() {
finalFs = timing finalFs = timing
} }
var opts fuse.FileSystemConnectorOptions opts := &fuse.MountOptions{
// These options are to be compatible with libfuse defaults,
loopbackfs.FillOptions(&opts) // making benchmarking easier.
NegativeTimeout: 1.0,
AttrTimeout: 1.0,
EntryTimeout: 1.0,
}
if *latencies { if *latencies {
debugFs.Original = finalFs debugFs.Original = finalFs
finalFs = debugFs finalFs = debugFs
} }
conn := fuse.NewFileSystemConnector(finalFs) conn := fuse.NewFileSystemConnector(finalFs, opts)
var finalRawFs fuse.RawFileSystem = conn var finalRawFs fuse.RawFileSystem = conn
if *latencies { if *latencies {
rawTiming := fuse.NewTimingRawFileSystem(conn) rawTiming := fuse.NewTimingRawFileSystem(conn)
debugFs.AddRawTimingFileSystem(rawTiming) debugFs.AddRawTimingFileSystem(rawTiming)
finalRawFs = rawTiming finalRawFs = rawTiming
} }
conn.SetOptions(opts)
state := fuse.NewMountState(finalRawFs) state := fuse.NewMountState(finalRawFs)
state.Debug = *debug state.Debug = *debug
......
...@@ -30,7 +30,7 @@ func main() { ...@@ -30,7 +30,7 @@ func main() {
} }
ufs := unionfs.NewUnionFs(flag.Args()[1:], ufsOptions) ufs := unionfs.NewUnionFs(flag.Args()[1:], ufsOptions)
conn := fuse.NewFileSystemConnector(ufs) conn := fuse.NewFileSystemConnector(ufs, nil)
mountState := fuse.NewMountState(conn) mountState := fuse.NewMountState(conn)
mountState.Debug = *debug mountState.Debug = *debug
fmt.Printf("Mounting...\n") fmt.Printf("Mounting...\n")
......
...@@ -35,7 +35,7 @@ func main() { ...@@ -35,7 +35,7 @@ func main() {
fs = debugFs fs = debugFs
} }
conn := fuse.NewFileSystemConnector(fs) conn := fuse.NewFileSystemConnector(fs, nil)
state := fuse.NewMountState(conn) state := fuse.NewMountState(conn)
if *latencies { if *latencies {
......
...@@ -162,14 +162,6 @@ func (me *LoopbackFileSystem) RemoveXAttr(name string, attr string) Status { ...@@ -162,14 +162,6 @@ func (me *LoopbackFileSystem) RemoveXAttr(name string, attr string) Status {
return Status(Removexattr(me.GetPath(name), attr)) return Status(Removexattr(me.GetPath(name), attr))
} }
func (me *LoopbackFileSystem) FillOptions(options *FileSystemConnectorOptions) {
// These options are to be compatible with libfuse defaults,
// making benchmarking easier.
options.NegativeTimeout = 1.0
options.AttrTimeout = 1.0
options.EntryTimeout = 1.0
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
type LoopbackFile struct { type LoopbackFile struct {
......
...@@ -61,7 +61,7 @@ func (me *testCase) Setup(t *testing.T) { ...@@ -61,7 +61,7 @@ func (me *testCase) Setup(t *testing.T) {
pfs = NewLockingFileSystem(pfs) pfs = NewLockingFileSystem(pfs)
var rfs RawFileSystem var rfs RawFileSystem
me.connector = NewFileSystemConnector(pfs) me.connector = NewFileSystemConnector(pfs, nil)
rfs = me.connector rfs = me.connector
rfs = NewTimingRawFileSystem(rfs) rfs = NewTimingRawFileSystem(rfs)
rfs = NewLockingRawFileSystem(rfs) rfs = NewLockingRawFileSystem(rfs)
...@@ -607,7 +607,7 @@ func TestRecursiveMount(t *testing.T) { ...@@ -607,7 +607,7 @@ func TestRecursiveMount(t *testing.T) {
f.Close() f.Close()
pfs2 := NewLoopbackFileSystem(ts.origDir) pfs2 := NewLoopbackFileSystem(ts.origDir)
code := ts.connector.Mount("/hello.txt", pfs2) code := ts.connector.Mount("/hello.txt", pfs2, nil)
if code != EINVAL { if code != EINVAL {
t.Error("expect EINVAL", code) t.Error("expect EINVAL", code)
} }
...@@ -615,7 +615,7 @@ func TestRecursiveMount(t *testing.T) { ...@@ -615,7 +615,7 @@ func TestRecursiveMount(t *testing.T) {
submnt := filepath.Join(ts.mountPoint, "mnt") submnt := filepath.Join(ts.mountPoint, "mnt")
err = os.Mkdir(submnt, 0777) err = os.Mkdir(submnt, 0777)
CheckSuccess(err) CheckSuccess(err)
code = ts.connector.Mount("/mnt", pfs2) code = ts.connector.Mount("/mnt", pfs2, nil)
if code != OK { if code != OK {
t.Errorf("mkdir") t.Errorf("mkdir")
} }
......
...@@ -12,7 +12,7 @@ func TestPathDebug(t *testing.T) { ...@@ -12,7 +12,7 @@ func TestPathDebug(t *testing.T) {
debugFs.Original = &DefaultFileSystem{} debugFs.Original = &DefaultFileSystem{}
debugFs.Add("test-entry", func() []byte { return []byte("test-content") }) debugFs.Add("test-entry", func() []byte { return []byte("test-content") })
connector := NewFileSystemConnector(debugFs) connector := NewFileSystemConnector(debugFs, nil)
mountPoint := MakeTempDir() mountPoint := MakeTempDir()
state := NewMountState(connector) state := NewMountState(connector)
......
...@@ -27,6 +27,8 @@ type mountData struct { ...@@ -27,6 +27,8 @@ type mountData struct {
// We could have separate treeLocks per mount; something to // We could have separate treeLocks per mount; something to
// consider if we can measure significant contention for // consider if we can measure significant contention for
// multi-mount filesystems. // multi-mount filesystems.
options *MountOptions
} }
func newMount(fs FileSystem) *mountData { func newMount(fs FileSystem) *mountData {
...@@ -139,28 +141,24 @@ func (me *inode) setParent(newParent *inode) { ...@@ -139,28 +141,24 @@ func (me *inode) setParent(newParent *inode) {
} }
} }
type TimeoutOptions struct { type MountOptions struct {
EntryTimeout float64 EntryTimeout float64
AttrTimeout float64 AttrTimeout float64
NegativeTimeout float64 NegativeTimeout float64
} }
func MakeTimeoutOptions() TimeoutOptions {
return TimeoutOptions{ func MakeMountOptions() *MountOptions {
return &MountOptions{
NegativeTimeout: 0.0, NegativeTimeout: 0.0,
AttrTimeout: 1.0, AttrTimeout: 1.0,
EntryTimeout: 1.0, EntryTimeout: 1.0,
} }
} }
type FileSystemConnectorOptions struct {
TimeoutOptions
}
type FileSystemConnector struct { type FileSystemConnector struct {
DefaultRawFileSystem DefaultRawFileSystem
options FileSystemConnectorOptions
Debug bool Debug bool
//////////////// ////////////////
...@@ -386,14 +384,11 @@ func EmptyFileSystemConnector() (out *FileSystemConnector) { ...@@ -386,14 +384,11 @@ func EmptyFileSystemConnector() (out *FileSystemConnector) {
rootData := out.newInode(true, true) rootData := out.newInode(true, true)
rootData.Children = make(map[string]*inode, initDirSize) rootData.Children = make(map[string]*inode, initDirSize)
out.options.NegativeTimeout = 0.0
out.options.AttrTimeout = 1.0
out.options.EntryTimeout = 1.0
out.verify() out.verify()
return out return out
} }
func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem) Status { func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem, opts *MountOptions) Status {
var node *inode var node *inode
if mountPoint != "/" { if mountPoint != "/" {
...@@ -433,7 +428,10 @@ func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem) Status { ...@@ -433,7 +428,10 @@ func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem) Status {
} }
node.mount = newMount(fs) node.mount = newMount(fs)
if opts == nil {
opts = MakeMountOptions()
}
node.mount.options = opts
return OK return OK
} }
......
...@@ -9,9 +9,9 @@ import ( ...@@ -9,9 +9,9 @@ import (
) )
func NewFileSystemConnector(fs FileSystem) (out *FileSystemConnector) { func NewFileSystemConnector(fs FileSystem, opts *MountOptions) (out *FileSystemConnector) {
out = EmptyFileSystemConnector() out = EmptyFileSystemConnector()
if code := out.Mount("/", fs); code != OK { if code := out.Mount("/", fs, opts); code != OK {
panic("root mount failed.") panic("root mount failed.")
} }
out.verify() out.verify()
...@@ -19,10 +19,6 @@ func NewFileSystemConnector(fs FileSystem) (out *FileSystemConnector) { ...@@ -19,10 +19,6 @@ func NewFileSystemConnector(fs FileSystem) (out *FileSystemConnector) {
return out return out
} }
func (me *FileSystemConnector) SetOptions(opts FileSystemConnectorOptions) {
me.options = opts
}
func (me *FileSystemConnector) Destroy(h *InHeader, input *InitIn) { func (me *FileSystemConnector) Destroy(h *InHeader, input *InitIn) {
// TODO - umount all. // TODO - umount all.
} }
...@@ -43,14 +39,14 @@ func (me *FileSystemConnector) internalLookupWithNode(parent *inode, name string ...@@ -43,14 +39,14 @@ func (me *FileSystemConnector) internalLookupWithNode(parent *inode, name string
// Init. // Init.
fullPath, mount := parent.GetPath() fullPath, mount := parent.GetPath()
if mount == nil { if mount == nil {
return NegativeEntry(me.options.NegativeTimeout), OK, nil return NegativeEntry(mount.options.NegativeTimeout), OK, nil
} }
fullPath = filepath.Join(fullPath, name) fullPath = filepath.Join(fullPath, name)
attr, err := mount.fs.GetAttr(fullPath) attr, err := mount.fs.GetAttr(fullPath)
if err == ENOENT && me.options.NegativeTimeout > 0.0 { if err == ENOENT && mount.options.NegativeTimeout > 0.0 {
return NegativeEntry(me.options.NegativeTimeout), OK, nil return NegativeEntry(mount.options.NegativeTimeout), OK, nil
} }
if err != OK { if err != OK {
...@@ -64,8 +60,8 @@ func (me *FileSystemConnector) internalLookupWithNode(parent *inode, name string ...@@ -64,8 +60,8 @@ func (me *FileSystemConnector) internalLookupWithNode(parent *inode, name string
NodeId: data.NodeId, NodeId: data.NodeId,
Generation: 1, // where to get the generation? Generation: 1, // where to get the generation?
} }
SplitNs(me.options.EntryTimeout, &out.EntryValid, &out.EntryValidNsec) SplitNs(mount.options.EntryTimeout, &out.EntryValid, &out.EntryValidNsec)
SplitNs(me.options.AttrTimeout, &out.AttrValid, &out.AttrValidNsec) SplitNs(mount.options.AttrTimeout, &out.AttrValid, &out.AttrValidNsec)
out.Attr = *attr out.Attr = *attr
out.Attr.Ino = data.NodeId out.Attr.Ino = data.NodeId
return out, OK, data return out, OK, data
...@@ -90,7 +86,7 @@ func (me *FileSystemConnector) GetAttr(header *InHeader, input *GetAttrIn) (out ...@@ -90,7 +86,7 @@ func (me *FileSystemConnector) GetAttr(header *InHeader, input *GetAttrIn) (out
Attr: *attr, Attr: *attr,
} }
out.Attr.Ino = header.NodeId out.Attr.Ino = header.NodeId
SplitNs(me.options.AttrTimeout, &out.AttrValid, &out.AttrValidNsec) SplitNs(mount.options.AttrTimeout, &out.AttrValid, &out.AttrValidNsec)
return out, OK return out, OK
} }
......
...@@ -93,7 +93,7 @@ func TestXAttrRead(t *testing.T) { ...@@ -93,7 +93,7 @@ func TestXAttrRead(t *testing.T) {
"user.attr2": []byte("val2")} "user.attr2": []byte("val2")}
xfs := NewXAttrFs(nm, golden) xfs := NewXAttrFs(nm, golden)
connector := NewFileSystemConnector(NewLockingFileSystem(xfs)) connector := NewFileSystemConnector(xfs, nil)
mountPoint := MakeTempDir() mountPoint := MakeTempDir()
state := NewMountState(connector) state := NewMountState(connector)
......
...@@ -74,7 +74,7 @@ func (me *AutoUnionFs) addFs(roots []string) { ...@@ -74,7 +74,7 @@ func (me *AutoUnionFs) addFs(roots []string) {
me.lock.Unlock() me.lock.Unlock()
if gofs != nil { if gofs != nil {
me.connector.Mount("/"+name, gofs) me.connector.Mount("/"+name, gofs, nil)
} }
} }
......
...@@ -40,7 +40,7 @@ func setup(t *testing.T) (workdir string, state *fuse.MountState) { ...@@ -40,7 +40,7 @@ func setup(t *testing.T) (workdir string, state *fuse.MountState) {
roots = append(roots, wd+"/ro") roots = append(roots, wd+"/ro")
ufs := NewUnionFs(roots, testOpts) ufs := NewUnionFs(roots, testOpts)
connector := fuse.NewFileSystemConnector(ufs) connector := fuse.NewFileSystemConnector(ufs, nil)
state = fuse.NewMountState(connector) state = fuse.NewMountState(connector)
state.Mount(wd + "/mount") state.Mount(wd + "/mount")
......
...@@ -50,7 +50,7 @@ func (me *zipCreateFile) Write(input *fuse.WriteIn, nameBytes []byte) (uint32, f ...@@ -50,7 +50,7 @@ func (me *zipCreateFile) Write(input *fuse.WriteIn, nameBytes []byte) (uint32, f
return 0, fuse.ENOSYS return 0, fuse.ENOSYS
} }
code := me.zfs.Connector.Mount("/"+filepath.Base(me.Basename), fs) code := me.zfs.Connector.Mount("/"+filepath.Base(me.Basename), fs, nil)
if code != fuse.OK { if code != fuse.OK {
return 0, code return 0, code
...@@ -85,7 +85,7 @@ func NewMultiZipFs() *MultiZipFs { ...@@ -85,7 +85,7 @@ func NewMultiZipFs() *MultiZipFs {
m.zips = make(map[string]*ZipArchiveFileSystem) m.zips = make(map[string]*ZipArchiveFileSystem)
m.pendingZips = make(map[string]bool) m.pendingZips = make(map[string]bool)
m.zipFileNames = make(map[string]string) m.zipFileNames = make(map[string]string)
m.Connector = fuse.NewFileSystemConnector(m) m.Connector = fuse.NewFileSystemConnector(m, nil)
return m return m
} }
......
...@@ -14,7 +14,7 @@ func TestZipFs(t *testing.T) { ...@@ -14,7 +14,7 @@ func TestZipFs(t *testing.T) {
t.Error("NewZipArchiveFileSystem failed:", err) t.Error("NewZipArchiveFileSystem failed:", err)
} }
connector := fuse.NewFileSystemConnector(zfs) connector := fuse.NewFileSystemConnector(zfs, nil)
mountPoint := fuse.MakeTempDir() mountPoint := fuse.MakeTempDir()
state := fuse.NewMountState(connector) state := fuse.NewMountState(connector)
......
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