commit bad803f5d352e0cd2f16716f53e47994276331d3
parent 9dba92ddf907baf0b09acfb252b5fe4ae2a1c755
Author: Antoine Amarilli <a3nm@a3nm.net>
Date: Sat, 29 Dec 2012 00:19:16 +0100
CacheFS inherits from MetaCacheFS
Diffstat:
TODO | | | 1 | - |
cachefs.py | | | 77 | +++++++++++++++++------------------------------------------------------------ |
2 files changed, 17 insertions(+), 61 deletions(-)
diff --git a/TODO b/TODO
@@ -1,4 +1,3 @@
- fail more gracefully for missing endpoints
- partial reads, or bufferize as much as needed
- don't cache for a small read
-- cachefs inherits from loopfs or from metacachefs
diff --git a/cachefs.py b/cachefs.py
@@ -12,6 +12,7 @@ import pickle
import time
import heapq
from threading import Lock
+from metacachefs import MetaCacheFS
DB = ".cache.db"
@@ -48,7 +49,7 @@ class Cache:
self.heap = []
self.files = {}
self.path = path
- self.discover()
+ # TODO self.discover()
@property
def freeSize(self):
@@ -96,9 +97,9 @@ class Cache:
return f
-class CacheFS(fuse.Fuse):
+class CacheFS(MetaCacheFS):
def __init__(self, *args, **kw):
- fuse.Fuse.__init__(self, *args, **kw)
+ MetaCacheFS.__init__(self, *args, **kw)
self.rwlock = Lock()
self.cache = None
@@ -115,9 +116,9 @@ class CacheFS(fuse.Fuse):
type='int', help="maximal size of cache")
def fsinit(self):
+ MetaCacheFS.fsinit(self)
+
options = self.cmdline[0]
- args = self.cmdline[1]
- self.sourceRoot = args[0]
self.cacheRoot = options.cache
self.db = options.db
self.size = options.size
@@ -140,9 +141,6 @@ class CacheFS(fuse.Fuse):
with open(self.db, 'wb+') as f:
pickle.dump(self.cache, f)
- def sourcePath(self, path):
- return os.path.join(self.sourceRoot, path[1:])
-
def cachePath(self, path):
return os.path.join(self.cacheRoot, path[1:])
@@ -194,54 +192,32 @@ class CacheFS(fuse.Fuse):
return self.sourcePath(path)
# create folder hierarchy
head, tail = os.path.split(self.cachePath(path))
+ print "will create folders"
try:
os.makedirs(head)
except OSError as exc: # Python >2.5
if exc.errno == errno.EEXIST and os.path.isdir(head):
pass
else: raise
+ print "will copy %s to %s" % (self.sourcePath(path), self.cachePath(path))
shutil.copy2(self.sourcePath(path), self.cachePath(path))
self.cache.addFile(path[1:])
return self.cachePath(path)
- def access(self, path, mode):
- if not os.access(self.sourcePath(path), mode):
- return -errno.EACCES
-
def chmod(self, path, mode):
wasCached = self.isCached(path)
- retval = os.chmod(self.sourcePath(path), mode)
+ retval = super(CacheFS, self).chmod(path, mode)
if wasCached:
os.chmod(self.cachePath(path), mode) # ignore errors
return retval
def chown(self, path, mode):
wasCached = self.isCached(path)
- retval = os.chown(self.sourcePath(path), mode)
+ retval = super(CacheFS, self).chown(path, mode)
if wasCached:
os.chown(self.cachePath(path), mode) # ignore errors
return retval
- def create(self, path, flags, mode):
- return os.open(self.sourcePath(path), os.O_WRONLY | os.O_CREAT, mode)
-
- def getattr(self, path):
- return os.lstat(self.sourcePath(path))
-
- def link(self, target, source):
- os.link(self.sourcePath(source), self.sourcePath(target))
-
- def mkdir(self, path, mode):
- return os.mkdir(self.sourcePath(path), mode)
-
- def mknod(self, path, mode, rdev):
- return os.mknod(self.sourcePath(path), mode, rdev)
-
- def open(self, path, flags):
- #print("will call open %s %s" % (self.prepare(path), flags))
- #return os.open(self.prepare(path), flags)
- return 0
-
def read(self, path, size, offset):
f = self.prepare(path)
with self.rwlock:
@@ -251,30 +227,14 @@ class CacheFS(fuse.Fuse):
os.close(fh)
return x
- def readdir(self, path, offset):
- path = self.sourcePath(path)
- myIno = os.lstat(path).st_ino
- yield fuse.Direntry('.', ino=myIno)
- parentIno = os.lstat(os.path.join(path, "..")).st_ino
- yield fuse.Direntry('..', ino=parentIno)
- for name in os.listdir(path):
- ino = os.lstat(os.path.join(path, name)).st_ino
- yield fuse.Direntry(name, ino=ino)
-
- def readlink(self, path):
- return os.readlink(self.sourcePath(path))
-
def rename(self, old, new):
wasCached = self.isCached(old)
- retval = os.rename(self.sourcePath(old), self.sourcePath(new))
+ retval = super(CacheFS, self).rename(old, new)
if wasCached:
self.cache.moveFile(old[1:], new[1:])
os.rename(self.cachePath(old), self.cachePath(new))
return retval
- def rmdir(self, path):
- return os.rmdir(self.sourcePath(path))
-
def statfs(self):
stv = os.statvfs(self.cacheRoot)
stv = Stat(**dict((key, getattr(stv, key)) for key in ["f_bavail",
@@ -285,24 +245,23 @@ class CacheFS(fuse.Fuse):
stv.f_blocks = self.cache.maxSize/stv.f_bsize
return stv
- def symlink(self, target, source):
- return os.symlink(self.sourcePath(source), self.sourcePath(target))
-
def doTruncate(self, path, length):
with open(path, 'r+') as f:
f.truncate(length)
- def truncate(self, path, length, fh=None):
+ def truncate(self, path, length):
wasCached = self.isCached(path)
+ retval = super(CacheFS, self).truncate(path, length)
self.doTruncate(self.sourcePath(path), length)
if wasCached:
self.cache.currentSize -= self.cache.files[path[1:]].size
self.doTruncate(self.cachePath(path), length)
self.cache.currentSize += self.cache.files[path[1:]].size
+ return retval
def unlink(self, path):
wasCached = self.isCached(path)
- retval = os.unlink(self.sourcePath(path))
+ retval = super(CacheFS, self).unlink(path)
if wasCached:
self.cache.deleteFile(path[1:])
os.unlink(self.cachePath(path))
@@ -311,7 +270,7 @@ class CacheFS(fuse.Fuse):
def utimens(self, path, ts_acc, ts_mod):
wasCached = self.isCached(path)
times = (ts_acc.tv_sec, ts_mod.tv_sec)
- retval = os.utime(self.sourcePath(path), times)
+ retval = super(CacheFS, self).utimens(path, ts_acc, ts_mod)
if wasCached:
os.utime(self.cachePath(path), times)
return retval
@@ -327,7 +286,7 @@ class CacheFS(fuse.Fuse):
def write(self, path, data, offset):
wasCached = self.isCached(path)
print "writing to a %s file" % ("cached" if wasCached else "non-cached")
- retval = self.doWrite(self.sourcePath(path), data, offset)
+ retval = super(CacheFS, self).write(path, data, offset)
if retval > 0 and wasCached:
self.makeRoom(len(data))
self.cache.currentSize -= self.cache.files[path[1:]].size
@@ -336,8 +295,6 @@ class CacheFS(fuse.Fuse):
return retval
-
-
if __name__ == "__main__":
cachefs = CacheFS()
fuse_opts = cachefs.parse(['-o', 'fsname=cachefs'] + sys.argv[1:])