github.com/hanwen/go-fuse@v1.0.0/fuse/pathfs/locking.go (about) 1 // Copyright 2016 the Go-FUSE Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package pathfs 6 7 import ( 8 "sync" 9 "time" 10 11 "github.com/hanwen/go-fuse/fuse" 12 "github.com/hanwen/go-fuse/fuse/nodefs" 13 ) 14 15 type lockingFileSystem struct { 16 // Should be public so people reusing can access the wrapped 17 // FS. 18 FS FileSystem 19 lock sync.Mutex 20 } 21 22 // NewLockingFileSystem is a wrapper that makes a FileSystem 23 // threadsafe by serializing each operation. 24 func NewLockingFileSystem(pfs FileSystem) FileSystem { 25 l := new(lockingFileSystem) 26 l.FS = pfs 27 return l 28 } 29 30 func (fs *lockingFileSystem) String() string { 31 defer fs.locked()() 32 return fs.FS.String() 33 } 34 35 func (fs *lockingFileSystem) SetDebug(debug bool) { 36 defer fs.locked()() 37 fs.FS.SetDebug(debug) 38 } 39 40 func (fs *lockingFileSystem) StatFs(name string) *fuse.StatfsOut { 41 defer fs.locked()() 42 return fs.FS.StatFs(name) 43 } 44 45 func (fs *lockingFileSystem) locked() func() { 46 fs.lock.Lock() 47 return func() { fs.lock.Unlock() } 48 } 49 50 func (fs *lockingFileSystem) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) { 51 defer fs.locked()() 52 return fs.FS.GetAttr(name, context) 53 } 54 55 func (fs *lockingFileSystem) Readlink(name string, context *fuse.Context) (string, fuse.Status) { 56 defer fs.locked()() 57 return fs.FS.Readlink(name, context) 58 } 59 60 func (fs *lockingFileSystem) Mknod(name string, mode uint32, dev uint32, context *fuse.Context) fuse.Status { 61 defer fs.locked()() 62 return fs.FS.Mknod(name, mode, dev, context) 63 } 64 65 func (fs *lockingFileSystem) Mkdir(name string, mode uint32, context *fuse.Context) fuse.Status { 66 defer fs.locked()() 67 return fs.FS.Mkdir(name, mode, context) 68 } 69 70 func (fs *lockingFileSystem) Unlink(name string, context *fuse.Context) (code fuse.Status) { 71 defer fs.locked()() 72 return fs.FS.Unlink(name, context) 73 } 74 75 func (fs *lockingFileSystem) Rmdir(name string, context *fuse.Context) (code fuse.Status) { 76 defer fs.locked()() 77 return fs.FS.Rmdir(name, context) 78 } 79 80 func (fs *lockingFileSystem) Symlink(value string, linkName string, context *fuse.Context) (code fuse.Status) { 81 defer fs.locked()() 82 return fs.FS.Symlink(value, linkName, context) 83 } 84 85 func (fs *lockingFileSystem) Rename(oldName string, newName string, context *fuse.Context) (code fuse.Status) { 86 defer fs.locked()() 87 return fs.FS.Rename(oldName, newName, context) 88 } 89 90 func (fs *lockingFileSystem) Link(oldName string, newName string, context *fuse.Context) (code fuse.Status) { 91 defer fs.locked()() 92 return fs.FS.Link(oldName, newName, context) 93 } 94 95 func (fs *lockingFileSystem) Chmod(name string, mode uint32, context *fuse.Context) (code fuse.Status) { 96 defer fs.locked()() 97 return fs.FS.Chmod(name, mode, context) 98 } 99 100 func (fs *lockingFileSystem) Chown(name string, uid uint32, gid uint32, context *fuse.Context) (code fuse.Status) { 101 defer fs.locked()() 102 return fs.FS.Chown(name, uid, gid, context) 103 } 104 105 func (fs *lockingFileSystem) Truncate(name string, offset uint64, context *fuse.Context) (code fuse.Status) { 106 defer fs.locked()() 107 return fs.FS.Truncate(name, offset, context) 108 } 109 110 func (fs *lockingFileSystem) Open(name string, flags uint32, context *fuse.Context) (file nodefs.File, code fuse.Status) { 111 file, code = fs.FS.Open(name, flags, context) 112 file = nodefs.NewLockingFile(&fs.lock, file) 113 return 114 } 115 116 func (fs *lockingFileSystem) OpenDir(name string, context *fuse.Context) (stream []fuse.DirEntry, status fuse.Status) { 117 defer fs.locked()() 118 return fs.FS.OpenDir(name, context) 119 } 120 121 func (fs *lockingFileSystem) OnMount(nodeFs *PathNodeFs) { 122 defer fs.locked()() 123 fs.FS.OnMount(nodeFs) 124 } 125 126 func (fs *lockingFileSystem) OnUnmount() { 127 defer fs.locked()() 128 fs.FS.OnUnmount() 129 } 130 131 func (fs *lockingFileSystem) Access(name string, mode uint32, context *fuse.Context) (code fuse.Status) { 132 defer fs.locked()() 133 return fs.FS.Access(name, mode, context) 134 } 135 136 func (fs *lockingFileSystem) Create(name string, flags uint32, mode uint32, context *fuse.Context) (file nodefs.File, code fuse.Status) { 137 defer fs.locked()() 138 file, code = fs.FS.Create(name, flags, mode, context) 139 140 file = nodefs.NewLockingFile(&fs.lock, file) 141 return file, code 142 } 143 144 func (fs *lockingFileSystem) Utimens(name string, Atime *time.Time, Mtime *time.Time, context *fuse.Context) (code fuse.Status) { 145 defer fs.locked()() 146 return fs.FS.Utimens(name, Atime, Mtime, context) 147 } 148 149 func (fs *lockingFileSystem) GetXAttr(name string, attr string, context *fuse.Context) ([]byte, fuse.Status) { 150 defer fs.locked()() 151 return fs.FS.GetXAttr(name, attr, context) 152 } 153 154 func (fs *lockingFileSystem) SetXAttr(name string, attr string, data []byte, flags int, context *fuse.Context) fuse.Status { 155 defer fs.locked()() 156 return fs.FS.SetXAttr(name, attr, data, flags, context) 157 } 158 159 func (fs *lockingFileSystem) ListXAttr(name string, context *fuse.Context) ([]string, fuse.Status) { 160 defer fs.locked()() 161 return fs.FS.ListXAttr(name, context) 162 } 163 164 func (fs *lockingFileSystem) RemoveXAttr(name string, attr string, context *fuse.Context) fuse.Status { 165 defer fs.locked()() 166 return fs.FS.RemoveXAttr(name, attr, context) 167 }