Commit 839a1f68 by rfkelly0

fix a locking bug in MountFS.getsize

parent 654209fd
#!/usr/bin/env python #!/usr/bin/env python
from base import * from fs.base import *
from objecttree import ObjectTree from fs.objecttree import ObjectTree
from memoryfs import MemoryFS
class DirMount(object): class DirMount(object):
...@@ -53,9 +52,8 @@ class MountFS(FS): ...@@ -53,9 +52,8 @@ class MountFS(FS):
return self, head_path, tail_path return self, head_path, tail_path
@synchronize
def desc(self, path): def desc(self, path):
self._lock.acquire()
try:
fs, mount_path, delegate_path = self._delegate(path) fs, mount_path, delegate_path = self._delegate(path)
if fs is self: if fs is self:
if fs.isdir(path): if fs.isdir(path):
...@@ -63,12 +61,9 @@ class MountFS(FS): ...@@ -63,12 +61,9 @@ class MountFS(FS):
else: else:
return "Mounted file" return "Mounted file"
return "Mounted dir, maps to path %s on %s" % (delegate_path, str(fs)) return "Mounted dir, maps to path %s on %s" % (delegate_path, str(fs))
finally:
self._lock.release()
@synchronize
def isdir(self, path): def isdir(self, path):
self._lock.acquire()
try:
fs, mount_path, delegate_path = self._delegate(path) fs, mount_path, delegate_path = self._delegate(path)
if fs is None: if fs is None:
raise ResourceNotFoundError(path) raise ResourceNotFoundError(path)
...@@ -78,13 +73,9 @@ class MountFS(FS): ...@@ -78,13 +73,9 @@ class MountFS(FS):
return isinstance(object, dict) return isinstance(object, dict)
else: else:
return fs.isdir(delegate_path) return fs.isdir(delegate_path)
finally:
self._lock.release()
@synchronize
def isfile(self, path): def isfile(self, path):
self._lock.acquire()
try:
fs, mount_path, delegate_path = self._delegate(path) fs, mount_path, delegate_path = self._delegate(path)
if fs is None: if fs is None:
return ResourceNotFoundError(path) return ResourceNotFoundError(path)
...@@ -94,13 +85,9 @@ class MountFS(FS): ...@@ -94,13 +85,9 @@ class MountFS(FS):
return type(object) is MountFS.FileMount return type(object) is MountFS.FileMount
else: else:
return fs.isfile(delegate_path) return fs.isfile(delegate_path)
finally:
self._lock.release()
@synchronize
def listdir(self, path="/", wildcard=None, full=False, absolute=False, dirs_only=False, files_only=False): def listdir(self, path="/", wildcard=None, full=False, absolute=False, dirs_only=False, files_only=False):
self._lock.acquire()
try:
path = normpath(path) path = normpath(path)
fs, mount_path, delegate_path = self._delegate(path) fs, mount_path, delegate_path = self._delegate(path)
...@@ -134,24 +121,17 @@ class MountFS(FS): ...@@ -134,24 +121,17 @@ class MountFS(FS):
paths = [pathjoin(path, p) for p in paths] paths = [pathjoin(path, p) for p in paths]
return paths return paths
finally:
self._lock.release()
@synchronize
def makedir(self, path, recursive=False, allow_recreate=False): def makedir(self, path, recursive=False, allow_recreate=False):
path = normpath(path) path = normpath(path)
self._lock.acquire()
try:
fs, mount_path, delegate_path = self._delegate(path) fs, mount_path, delegate_path = self._delegate(path)
if fs is self: if fs is self:
raise UnsupportedError("make directory", msg="Can only makedir for mounted paths" ) raise UnsupportedError("make directory", msg="Can only makedir for mounted paths" )
return fs.makedir(delegate_path, recursive=recursive, allow_recreate=allow_recreate) return fs.makedir(delegate_path, recursive=recursive, allow_recreate=allow_recreate)
finally:
self._lock.release()
@synchronize
def open(self, path, mode="r", **kwargs): def open(self, path, mode="r", **kwargs):
self._lock.acquire()
try:
path = normpath(path) path = normpath(path)
object = self.mount_tree.get(path, None) object = self.mount_tree.get(path, None)
if type(object) is MountFS.FileMount: if type(object) is MountFS.FileMount:
...@@ -165,31 +145,19 @@ class MountFS(FS): ...@@ -165,31 +145,19 @@ class MountFS(FS):
return fs.open(delegate_path, mode, **kwargs) return fs.open(delegate_path, mode, **kwargs)
finally:
self._lock.release()
@synchronize
def exists(self, path): def exists(self, path):
self._lock.acquire()
try:
path = normpath(path) path = normpath(path)
fs, mount_path, delegate_path = self._delegate(path) fs, mount_path, delegate_path = self._delegate(path)
if fs is None: if fs is None:
return False return False
if fs is self: if fs is self:
return path in self.mount_tree return path in self.mount_tree
return fs.exists(delegate_path) return fs.exists(delegate_path)
finally: @synchronize
self._lock.release()
def remove(self, path): def remove(self, path):
self._lock.acquire()
try:
path = normpath(path) path = normpath(path)
fs, mount_path, delegate_path = self._delegate(path) fs, mount_path, delegate_path = self._delegate(path)
if fs is None: if fs is None:
...@@ -198,14 +166,8 @@ class MountFS(FS): ...@@ -198,14 +166,8 @@ class MountFS(FS):
raise UnsupportedError("remove file", msg="Can only remove paths within a mounted dir") raise UnsupportedError("remove file", msg="Can only remove paths within a mounted dir")
return fs.remove(delegate_path) return fs.remove(delegate_path)
finally: @synchronize
self._lock.release()
def removedir(self, path, recursive=False, force=False): def removedir(self, path, recursive=False, force=False):
self._lock.acquire()
try:
path = normpath(path) path = normpath(path)
fs, mount_path, delegate_path = self._delegate(path) fs, mount_path, delegate_path = self._delegate(path)
...@@ -217,16 +179,10 @@ class MountFS(FS): ...@@ -217,16 +179,10 @@ class MountFS(FS):
return fs.removedir(delegate_path, recursive, force) return fs.removedir(delegate_path, recursive, force)
finally: @synchronize
self._lock.release()
def rename(self, src, dst): def rename(self, src, dst):
if not issamedir(src, dst): if not issamedir(src, dst):
raise ValueError("Destination path must the same directory (use the move method for moving to a different directory)") raise ValueError("Destination path must the same directory (use the move method for moving to a different directory)")
self._lock.acquire()
try:
fs1, mount_path1, delegate_path1 = self._delegate(src) fs1, mount_path1, delegate_path1 = self._delegate(src)
fs2, mount_path2, delegate_path2 = self._delegate(dst) fs2, mount_path2, delegate_path2 = self._delegate(dst)
...@@ -246,11 +202,9 @@ class MountFS(FS): ...@@ -246,11 +202,9 @@ class MountFS(FS):
raise ResourceNotFoundError(src) raise ResourceNotFoundError(src)
# TODO! # TODO!
raise UnsupportedError("rename resource", path=src) raise UnsupportedError("rename resource", path=src)
finally:
self._lock.release()
@synchronize
def mountdir(self, path, fs): def mountdir(self, path, fs):
"""Mounts a directory on a given path. """Mounts a directory on a given path.
...@@ -258,26 +212,17 @@ class MountFS(FS): ...@@ -258,26 +212,17 @@ class MountFS(FS):
fs -- A filesystem object to mount fs -- A filesystem object to mount
""" """
self._lock.acquire()
try:
path = normpath(path) path = normpath(path)
self.mount_tree[path] = MountFS.DirMount(path, fs) self.mount_tree[path] = MountFS.DirMount(path, fs)
finally:
self._lock.release()
mount = mountdir mount = mountdir
@synchronize
def mountfile(self, path, open_callable=None, info_callable=None): def mountfile(self, path, open_callable=None, info_callable=None):
self._lock.acquire()
try:
path = normpath(path) path = normpath(path)
self.mount_tree[path] = MountFS.FileMount(path, callable, info_callable) self.mount_tree[path] = MountFS.FileMount(path, callable, info_callable)
finally:
self._lock.release()
@synchronize
def getinfo(self, path): def getinfo(self, path):
self._lock.acquire()
try:
path = normpath(path) path = normpath(path)
fs, mount_path, delegate_path = self._delegate(path) fs, mount_path, delegate_path = self._delegate(path)
...@@ -290,12 +235,9 @@ class MountFS(FS): ...@@ -290,12 +235,9 @@ class MountFS(FS):
return self.mount_tree[path].info_callable(path) return self.mount_tree[path].info_callable(path)
return {} return {}
return fs.getinfo(delegate_path) return fs.getinfo(delegate_path)
finally:
self._lock.release()
@synchronize
def getsize(self, path): def getsize(self, path):
self._lock.acquire()
try:
path = normpath(path) path = normpath(path)
fs, mount_path, delegate_path = self._delegate(path) fs, mount_path, delegate_path = self._delegate(path)
...@@ -312,6 +254,4 @@ class MountFS(FS): ...@@ -312,6 +254,4 @@ class MountFS(FS):
return size return size
return fs.getinfo(delegate_path).get("size", None) return fs.getinfo(delegate_path).get("size", None)
except:
self._lock.release()
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